Compare commits

...

69 Commits

Author SHA1 Message Date
刘祥超
7c3d5aa69c 修改docker版本号为1.2.7 2023-08-14 09:09:02 +08:00
刘祥超
7224ba1123 提交components.js 2023-08-13 20:04:51 +08:00
刘祥超
0f7d5057fd 优化缓存策略--“清理“功能 2023-08-13 19:22:48 +08:00
刘祥超
43f2804ced WAF增加通配符匹配/不匹配操作符 2023-08-13 10:38:14 +08:00
刘祥超
5bb83555a4 优化WAF添加规则表单 2023-08-13 10:00:41 +08:00
刘祥超
af4d14364c 修改区域监控的api.yaml到api_reporter.yaml 2023-08-12 19:12:46 +08:00
刘祥超
105e717eb2 将cluster.yaml修改为api_cluster.yaml 2023-08-12 18:52:32 +08:00
刘祥超
697ec6f6e3 优化API配置格式化 2023-08-12 18:16:17 +08:00
刘祥超
e07c99f34d 修复安装界面中安装按钮被部分遮挡的问题 2023-08-12 18:09:25 +08:00
刘祥超
c047bd5896 安装界面中增加MySQL版本号需求说明 2023-08-12 17:59:32 +08:00
刘祥超
d97ac01d79 提交components.js 2023-08-12 17:58:09 +08:00
刘祥超
df19a04ad1 将api.yaml修改为api_admin.yaml 2023-08-12 17:58:00 +08:00
刘祥超
cbce8a9934 优化多个节点安装界面 2023-08-12 15:43:03 +08:00
刘祥超
7739a84828 将节点的api.yaml改为api_node.yaml,并简化配置内容 2023-08-12 15:29:28 +08:00
刘祥超
96f711b43f 优化错误处理相关代码 2023-08-11 16:41:43 +08:00
刘祥超
96b3ae5e7d 安装时API节点端口输入框增加新手提示 2023-08-11 15:36:40 +08:00
刘祥超
d0508e257a 提交components.js 2023-08-11 08:20:10 +08:00
刘祥超
ec8548f133 临时关闭页面内容默认类型从url改为html 2023-08-10 14:07:46 +08:00
刘祥超
f217b4190b 静态分发增加例外URL、限制URL、排除隐藏文件等选项 2023-08-10 11:26:53 +08:00
刘祥超
9a3b9ee8f8 访问日志中的“[服务]”改为“[网站]” 2023-08-10 10:34:48 +08:00
刘祥超
1c299c767b WAF策略可以自定义默认的区域/省份封禁提示 2023-08-10 10:30:38 +08:00
刘祥超
03b46f4c24 WAF策略中的地区/省份封禁也支持自定义提示HTML 2023-08-10 09:52:01 +08:00
刘祥超
0f40b6438a 讲默认的最多检查内容尺寸从1MB改为512K 2023-08-10 09:21:08 +08:00
刘祥超
4549d93e0d 改进文字 2023-08-10 09:12:25 +08:00
刘祥超
844cec1011 节点安装界面显示SSH地址,方便用户校对 2023-08-09 15:41:07 +08:00
刘祥超
0464c6ce43 将版本号修改为1.2.7 2023-08-09 14:24:09 +08:00
刘祥超
0cdaa9bb70 提交components.js 2023-08-09 14:23:57 +08:00
刘祥超
dade2eb4ff Update .golangci.yaml 2023-08-09 08:11:42 +08:00
刘祥超
42e1cd560e 添加golangci-lint配置 2023-08-08 18:32:58 +08:00
刘祥超
5db14ec84a 优化代码 2023-08-08 14:17:16 +08:00
刘祥超
22aca2e80c 集群设置 -- 缓存策略 可以直接点击修改 2023-08-07 17:39:10 +08:00
刘祥超
4f105f9327 优化缓存条件输入框 2023-08-07 17:16:55 +08:00
刘祥超
e2a218dd63 可以在缓存设置中搜索缓存条件 2023-08-07 17:08:38 +08:00
刘祥超
f9c0226fa0 缓存条件默认最大值设置从32MB改为128MB 2023-08-07 11:32:59 +08:00
刘祥超
fcccd69cee 如果用户设置的可缓存最大尺寸超出缓存策略设置,则提示用户 2023-08-07 11:32:36 +08:00
刘祥超
cc60c827da 缓存策略增加“缓存磁盘最小空余空间”选项 2023-08-06 18:09:01 +08:00
刘祥超
3c44e14386 缓存策略增加预热超时时间设置(默认20分钟) 2023-08-06 17:06:28 +08:00
刘祥超
7f765f4267 当网站所在集群没有指定根域名时,增加提示和设置链接 2023-08-06 11:22:52 +08:00
刘祥超
2262e6f3ca 优化网站设置DNS菜单位置 2023-08-06 11:22:02 +08:00
刘祥超
4349d165ac 优化文字 2023-08-06 10:27:55 +08:00
刘祥超
9d396af447 优化文字提示 2023-08-02 19:22:07 +08:00
刘祥超
a665457014 WAF策略增加“最多检查内容尺寸“选项 2023-08-02 16:58:45 +08:00
刘祥超
92ddd04b07 节点详情中显示磁盘预估写入速度 2023-08-02 14:48:23 +08:00
刘祥超
b5f93d6fbc 修复系统服务相关代码可能不执行的问题 2023-08-01 16:18:04 +08:00
刘祥超
374b75b9f1 启动时自动创建相关软链接 2023-08-01 10:46:56 +08:00
刘祥超
47b7d283a3 缓存条件增加“强制Range回源选项” 2023-07-31 17:31:42 +08:00
刘祥超
03a3b8b38f 将“区间”改为“分片” 2023-07-31 17:11:42 +08:00
刘祥超
d2a27f16d7 将“分片”改为“分段”,将“分区”改为“分片” 2023-07-31 16:59:12 +08:00
刘祥超
b9837f526b 缓存条件增加是否允许异步读取源站选项 2023-07-31 15:59:19 +08:00
刘祥超
2393f3a701 修复自定义页面可能无法保存的问题 2023-07-31 09:38:28 +08:00
刘祥超
b910339e6e Update Dockerfile 2023-07-28 09:26:27 +08:00
刘祥超
438445dab8 版本号更改为1.2.6 2023-07-28 09:26:05 +08:00
刘祥超
dc7e62c388 修复分组设置无法打开的问题 2023-07-28 09:25:04 +08:00
刘祥超
3ed8f9ca55 可以修改访问未绑定域名时的提示页面的状态码 2023-07-27 11:23:08 +08:00
刘祥超
0282b5e75f Update Dockerfile 2023-07-27 08:36:27 +08:00
刘祥超
f5f8218940 Update Dockerfile 2023-07-26 15:52:58 +08:00
刘祥超
a634046757 版本号更改为1.2.5 2023-07-26 15:30:19 +08:00
刘祥超
6a4d86e084 将版本号改为1.2.4 2023-07-26 10:15:40 +08:00
刘祥超
9f9b41c63d 更新Dockerfile中版本号 2023-07-26 10:15:32 +08:00
刘祥超
d813f6515b Update Dockerfile 2023-07-25 13:41:24 +08:00
刘祥超
730a445ef6 版本号修改为1.2.3 2023-07-25 13:16:31 +08:00
刘祥超
938947548b 优化节点同步任务界面 2023-07-25 10:21:50 +08:00
刘祥超
2d5085e652 删除TOA功能 2023-07-24 09:51:37 +08:00
刘祥超
e665e299f2 优化缓存策略相关界面 2023-07-20 17:06:45 +08:00
刘祥超
30b9c5eda5 默认自动检查版本更新 2023-07-20 09:38:09 +08:00
刘祥超
fbf29e774a 优化文字提示 2023-07-19 19:40:11 +08:00
刘祥超
5429971553 优化文字提示 2023-07-19 15:14:33 +08:00
刘祥超
df81bde6fd 优化安装界面 2023-07-19 14:22:48 +08:00
刘祥超
cb8b56ceb8 自动安装的mysql版本从8.0改为8.1 2023-07-19 11:18:25 +08:00
173 changed files with 2089 additions and 1129 deletions

74
.golangci.yaml Normal file
View File

@@ -0,0 +1,74 @@
# https://golangci-lint.run/usage/configuration/
linters:
enable-all: true
disable:
- ifshort
- exhaustivestruct
- golint
- nosnakecase
- scopelint
- varcheck
- structcheck
- interfacer
- maligned
- deadcode
- dogsled
- wrapcheck
- wastedassign
- varnamelen
- testpackage
- thelper
- nilerr
- sqlclosecheck
- paralleltest
- nonamedreturns
- nlreturn
- nakedret
- ireturn
- interfacebloat
- gosmopolitan
- gomnd
- goerr113
- gochecknoglobals
- exhaustruct
- errorlint
- depguard
- exhaustive
- containedctx
- wsl
- cyclop
- dupword
- errchkjson
- contextcheck
- tagalign
- dupl
- forbidigo
- funlen
- goconst
- godox
- gosec
- lll
- nestif
- revive
- unparam
- stylecheck
- gocritic
- gofumpt
- gomoddirectives
- godot
- gofmt
- gocognit
- mirror
- gocyclo
- gochecknoinits
- gci
- maintidx
- prealloc
- goimports
- errname
- musttag
- forcetypeassert
- whitespace
- noctx
- reassign

View File

@@ -57,9 +57,11 @@ function build() {
if [ "$(which uglifyjs)" ]; then if [ "$(which uglifyjs)" ]; then
echo "compress to component.js ..." echo "compress to component.js ..."
uglifyjs --compress --mangle -- "${JS_ROOT}"/components.src.js > "${JS_ROOT}"/components.js uglifyjs --compress --mangle -- "${JS_ROOT}"/components.src.js > "${JS_ROOT}"/components.js
uglifyjs --compress --mangle -- "${JS_ROOT}"/utils.js > "${JS_ROOT}"/utils.min.js
else else
echo "copy to component.js ..." echo "copy to component.js ..."
cp "${JS_ROOT}"/components.src.js "${JS_ROOT}"/components.js cp "${JS_ROOT}"/components.src.js "${JS_ROOT}"/components.js
cp "${JS_ROOT}"/utils.js "${JS_ROOT}"/utils.min.js
fi fi
# create dir & copy files # create dir & copy files

View File

@@ -1,4 +1,5 @@
api.yaml api.yaml
api_admin.yaml
server.yaml server.yaml
api_db.yaml api_db.yaml
*.pem *.pem

View File

@@ -1,4 +0,0 @@
rpc:
endpoints: [ "http://127.0.0.1:8003" ]
nodeId: ""
secret: ""

View File

@@ -0,0 +1,3 @@
rpc.endpoints: [ "http://127.0.0.1:8003" ]
nodeId: ""
secret: ""

View File

@@ -2,15 +2,21 @@
JS_ROOT=../web/public/js JS_ROOT=../web/public/js
echo "generate component.src.js ..." echo "generating component.src.js ..."
go run -tags=community ../cmd/edge-admin/main.go generate go run -tags=community ../cmd/edge-admin/main.go generate
if [ `which uglifyjs` ]; then if [ "$(which uglifyjs)" ]; then
echo "compress to component.js ..." echo "compress to component.js ..."
uglifyjs --compress --mangle -- ${JS_ROOT}/components.src.js > ${JS_ROOT}/components.js uglifyjs --compress --mangle -- ${JS_ROOT}/components.src.js > ${JS_ROOT}/components.js
echo "compress to utils.min.js ..."
uglifyjs --compress --mangle -- ${JS_ROOT}/utils.js > ${JS_ROOT}/utils.min.js
else else
echo "copy to component.js ..." echo "copy to component.js ..."
cp ${JS_ROOT}/components.src.js ${JS_ROOT}/components.js cp ${JS_ROOT}/components.src.js ${JS_ROOT}/components.js
echo "copy to utils.min.js ..."
cp ${JS_ROOT}/utils.js ${JS_ROOT}/utils.min.js
fi fi
echo "ok" echo "ok"

View File

@@ -161,7 +161,7 @@ func main() {
if progress >= 0 { if progress >= 0 {
if progress == 0 || progress == 1 || progress-lastProgress >= 0.1 { if progress == 0 || progress == 1 || progress-lastProgress >= 0.1 {
lastProgress = progress lastProgress = progress
log.Println(fmt.Sprintf("%.2f%%", manager.Progress()*100)) log.Printf("%.2f%%", manager.Progress()*100)
} }
} }
} else { } else {

View File

@@ -1,11 +1,11 @@
FROM alpine:latest FROM alpine:latest
LABEL maintainer="goedge.cdn@gmail.com" LABEL maintainer="goedge.cdn@gmail.com"
ENV TZ "Asia/Shanghai" ENV TZ "Asia/Shanghai"
ENV VERSION 1.2.2 ENV VERSION 1.2.7
ENV ROOT_DIR /usr/local/goedge ENV ROOT_DIR /usr/local/goedge
ENV TAR_FILE edge-admin-linux-amd64-plus-v${VERSION}.zip ENV TAR_FILE edge-admin-linux-amd64-plus-v${VERSION}.zip
ENV TAR_URL "https://dl.goedge.cn/edge/v${VERSION}/edge-admin-linux-amd64-plus-v${VERSION}.zip" ENV TAR_URL "https://dl.goedge.cn/edge/v${VERSION}/edge-admin-linux-amd64-plus-v${VERSION}.zip"
#ENV TAR_URL "http://192.168.2.60:8080/edge-admin-linux-amd64-plus-v${VERSION}.zip" # your local repository #ENV TAR_URL "http://192.168.2.61:8080/edge-admin-linux-amd64-plus-v${VERSION}.zip" # your local repository
RUN apk add --no-cache tzdata RUN apk add --no-cache tzdata

View File

@@ -1,6 +1,7 @@
package apps package apps
import ( import (
"errors"
"fmt" "fmt"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/iwind/TeaGo/logs" "github.com/iwind/TeaGo/logs"
@@ -9,8 +10,10 @@ import (
"github.com/iwind/gosock/pkg/gosock" "github.com/iwind/gosock/pkg/gosock"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"strings"
"time" "time"
) )
@@ -186,13 +189,16 @@ func (this *AppCmd) runStart() {
return return
} }
cmd := exec.Command(os.Args[0]) var cmd = exec.Command(this.exe())
err := cmd.Start() err := cmd.Start()
if err != nil { if err != nil {
fmt.Println(this.product+" start failed:", err.Error()) fmt.Println(this.product+" start failed:", err.Error())
return return
} }
// create symbolic links
_ = this.createSymLinks()
fmt.Println(this.product+" started ok, pid:", cmd.Process.Pid) fmt.Println(this.product+" started ok, pid:", cmd.Process.Pid)
} }
@@ -239,3 +245,58 @@ func (this *AppCmd) getPID() int {
} }
return maps.NewMap(reply.Params).GetInt("pid") return maps.NewMap(reply.Params).GetInt("pid")
} }
func (this *AppCmd) exe() string {
var exe, _ = os.Executable()
if len(exe) == 0 {
exe = os.Args[0]
}
return exe
}
// 创建软链接
func (this *AppCmd) createSymLinks() error {
if runtime.GOOS != "linux" {
return nil
}
var exe, _ = os.Executable()
if len(exe) == 0 {
return nil
}
var errorList = []string{}
// bin
{
var target = "/usr/bin/" + teaconst.ProcessName
old, _ := filepath.EvalSymlinks(target)
if old != exe {
_ = os.Remove(target)
err := os.Symlink(exe, target)
if err != nil {
errorList = append(errorList, err.Error())
}
}
}
// log
{
var realPath = filepath.Dir(filepath.Dir(exe)) + "/logs/run.log"
var target = "/var/log/" + teaconst.ProcessName + ".log"
old, _ := filepath.EvalSymlinks(target)
if old != realPath {
_ = os.Remove(target)
err := os.Symlink(realPath, target)
if err != nil {
errorList = append(errorList, err.Error())
}
}
}
if len(errorList) > 0 {
return errors.New(strings.Join(errorList, "\n"))
}
return nil
}

View File

@@ -1,6 +1,7 @@
package configs package configs
import ( import (
"errors"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
@@ -8,12 +9,19 @@ import (
"path/filepath" "path/filepath"
) )
const ConfigFileName = "api_admin.yaml"
const oldConfigFileName = "api.yaml"
// APIConfig API配置 // APIConfig API配置
type APIConfig struct { type APIConfig struct {
RPC struct { OldRPC struct {
Endpoints []string `yaml:"endpoints"` Endpoints []string `yaml:"endpoints"`
DisableUpdate bool `yaml:"disableUpdate"` DisableUpdate bool `yaml:"disableUpdate"`
} `yaml:"rpc"` } `yaml:"rpc,omitempty"`
RPCEndpoints []string `yaml:"rpc.endpoints,flow" json:"rpc.endpoints"`
RPCDisableUpdate bool `yaml:"rpc.disableUpdate" json:"rpc.disableUpdate"`
NodeId string `yaml:"nodeId"` NodeId string `yaml:"nodeId"`
Secret string `yaml:"secret"` Secret string `yaml:"secret"`
} }
@@ -21,21 +29,22 @@ type APIConfig struct {
// LoadAPIConfig 加载API配置 // LoadAPIConfig 加载API配置
func LoadAPIConfig() (*APIConfig, error) { func LoadAPIConfig() (*APIConfig, error) {
// 候选文件 // 候选文件
var localFile = Tea.ConfigFile("api.yaml") var realFile = Tea.ConfigFile(ConfigFileName)
var oldRealFile = Tea.ConfigFile(oldConfigFileName)
var isFromLocal = false var isFromLocal = false
var paths = []string{localFile} var paths = []string{realFile, oldRealFile}
homeDir, homeErr := os.UserHomeDir() homeDir, homeErr := os.UserHomeDir()
if homeErr == nil { if homeErr == nil {
paths = append(paths, homeDir+"/."+teaconst.ProcessName+"/api.yaml") paths = append(paths, homeDir+"/."+teaconst.ProcessName+"/"+ConfigFileName)
} }
paths = append(paths, "/etc/"+teaconst.ProcessName+"/api.yaml") paths = append(paths, "/etc/"+teaconst.ProcessName+"/"+ConfigFileName)
var data []byte var data []byte
var err error var err error
for _, path := range paths { for _, path := range paths {
data, err = os.ReadFile(path) data, err = os.ReadFile(path)
if err == nil { if err == nil {
if path == localFile { if path == realFile || path == oldRealFile {
isFromLocal = true isFromLocal = true
} }
break break
@@ -51,9 +60,14 @@ func LoadAPIConfig() (*APIConfig, error) {
return nil, err return nil, err
} }
err = config.Init()
if err != nil {
return nil, errors.New("init error: " + err.Error())
}
if !isFromLocal { if !isFromLocal {
// 恢复文件 // 恢复文件
_ = os.WriteFile(localFile, data, 0666) _ = os.WriteFile(realFile, data, 0666)
} }
return config, nil return config, nil
@@ -61,9 +75,9 @@ func LoadAPIConfig() (*APIConfig, error) {
// ResetAPIConfig 重置配置 // ResetAPIConfig 重置配置
func ResetAPIConfig() error { func ResetAPIConfig() error {
var filename = "api.yaml" var filename = ConfigFileName
// 重置 configs/api.yaml // 重置 configs/api_admin.yaml
{ {
var configFile = Tea.ConfigFile(filename) var configFile = Tea.ConfigFile(filename)
stat, err := os.Stat(configFile) stat, err := os.Stat(configFile)
@@ -75,7 +89,7 @@ func ResetAPIConfig() error {
} }
} }
// 重置 ~/.edge-admin/api.yaml // 重置 ~/.edge-admin/api_admin.yaml
homeDir, homeErr := os.UserHomeDir() homeDir, homeErr := os.UserHomeDir()
if homeErr == nil { if homeErr == nil {
var configFile = homeDir + "/." + teaconst.ProcessName + "/" + filename var configFile = homeDir + "/." + teaconst.ProcessName + "/" + filename
@@ -88,7 +102,7 @@ func ResetAPIConfig() error {
} }
} }
// 重置 /etc/edge-admin/api.yaml // 重置 /etc/edge-admin/api_admin.yaml
{ {
var configFile = "/etc/" + teaconst.ProcessName + "/" + filename var configFile = "/etc/" + teaconst.ProcessName + "/" + filename
stat, err := os.Stat(configFile) stat, err := os.Stat(configFile)
@@ -103,6 +117,22 @@ func ResetAPIConfig() error {
return nil return nil
} }
func IsNewInstalled() bool {
homeDir, err := os.UserHomeDir()
if err != nil {
return false
}
for _, filename := range []string{ConfigFileName, oldConfigFileName} {
_, err = os.Stat(homeDir + "/." + teaconst.ProcessName + "/" + filename)
if err == nil {
return false
}
}
return true
}
// WriteFile 写入API配置 // WriteFile 写入API配置
func (this *APIConfig) WriteFile(path string) error { func (this *APIConfig) WriteFile(path string) error {
data, err := yaml.Marshal(this) data, err := yaml.Marshal(this)
@@ -159,11 +189,27 @@ func (this *APIConfig) WriteFile(path string) error {
// Clone 克隆当前配置 // Clone 克隆当前配置
func (this *APIConfig) Clone() *APIConfig { func (this *APIConfig) Clone() *APIConfig {
return &APIConfig{ return &APIConfig{
RPC: struct {
Endpoints []string `yaml:"endpoints"`
DisableUpdate bool `yaml:"disableUpdate"`
}{},
NodeId: this.NodeId, NodeId: this.NodeId,
Secret: this.Secret, Secret: this.Secret,
} }
} }
func (this *APIConfig) Init() error {
// compatible with old
if len(this.RPCEndpoints) == 0 && len(this.OldRPC.Endpoints) > 0 {
this.RPCEndpoints = this.OldRPC.Endpoints
this.RPCDisableUpdate = this.OldRPC.DisableUpdate
}
if len(this.RPCEndpoints) == 0 {
return errors.New("no valid 'rpc.endpoints'")
}
if len(this.NodeId) == 0 {
return errors.New("'nodeId' required")
}
if len(this.Secret) == 0 {
return errors.New("'secret' required")
}
return nil
}

View File

@@ -2,6 +2,7 @@ package configs
import ( import (
_ "github.com/iwind/TeaGo/bootstrap" _ "github.com/iwind/TeaGo/bootstrap"
"gopkg.in/yaml.v3"
"testing" "testing"
) )
@@ -11,10 +12,16 @@ func TestLoadAPIConfig(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
t.Log(config) t.Log(config)
configData, err := yaml.Marshal(config)
if err != nil {
t.Fatal(err)
}
t.Log(string(configData))
} }
func TestAPIConfig_WriteFile(t *testing.T) { func TestAPIConfig_WriteFile(t *testing.T) {
config := &APIConfig{} var config = &APIConfig{}
err := config.WriteFile("/tmp/api_config.yaml") err := config.WriteFile("/tmp/api_config.yaml")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@@ -1,9 +1,9 @@
package teaconst package teaconst
const ( const (
Version = "1.2.2" Version = "1.2.7"
APINodeVersion = "1.2.2" APINodeVersion = "1.2.7"
ProductName = "Edge Admin" ProductName = "Edge Admin"
ProcessName = "edge-admin" ProcessName = "edge-admin"

View File

@@ -19,7 +19,6 @@ func TestAES128CFBMethod_Encrypt(t *testing.T) {
dst = dst[:len(src)] dst = dst[:len(src)]
t.Log("dst:", string(dst)) t.Log("dst:", string(dst))
src = make([]byte, len(src))
src, err = method.Decrypt(dst) src, err = method.Decrypt(dst)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -64,7 +63,6 @@ func TestAES128CFBMethod_Encrypt2(t *testing.T) {
for _, dst := range sources { for _, dst := range sources {
dst2 := append([]byte{}, dst...) dst2 := append([]byte{}, dst...)
src2 := make([]byte, len(dst2))
src2, err := method.Decrypt(dst2) src2, err := method.Decrypt(dst2)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@@ -5,20 +5,20 @@ import "sync"
var eventsMap = map[string][]func(){} // event => []callbacks var eventsMap = map[string][]func(){} // event => []callbacks
var locker = sync.Mutex{} var locker = sync.Mutex{}
// 增加事件回调 // On 增加事件回调
func On(event string, callback func()) { func On(event string, callback func()) {
locker.Lock() locker.Lock()
defer locker.Unlock() defer locker.Unlock()
callbacks, _ := eventsMap[event] var callbacks = eventsMap[event]
callbacks = append(callbacks, callback) callbacks = append(callbacks, callback)
eventsMap[event] = callbacks eventsMap[event] = callbacks
} }
// 通知事件 // Notify 通知事件
func Notify(event string) { func Notify(event string) {
locker.Lock() locker.Lock()
callbacks, _ := eventsMap[event] var callbacks = eventsMap[event]
locker.Unlock() locker.Unlock()
for _, callback := range callbacks { for _, callback := range callbacks {

View File

@@ -5,7 +5,7 @@ package gen
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors" "fmt"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/conds/condutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/conds/condutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
@@ -22,7 +22,7 @@ import (
func Generate() error { func Generate() error {
err := generateComponentsJSFile() err := generateComponentsJSFile()
if err != nil { if err != nil {
return errors.New("generate 'components.src.js' failed: " + err.Error()) return fmt.Errorf("generate 'components.src.js' failed: %w", err)
} }
return nil return nil

View File

@@ -2,6 +2,7 @@ package nodes
import ( import (
"errors" "errors"
"fmt"
"github.com/TeaOSLab/EdgeAdmin/internal/configs" "github.com/TeaOSLab/EdgeAdmin/internal/configs"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/TeaOSLab/EdgeAdmin/internal/events" "github.com/TeaOSLab/EdgeAdmin/internal/events"
@@ -65,7 +66,7 @@ func (this *AdminNode) Run() {
this.addPortsToFirewall() this.addPortsToFirewall()
// 监听信号 // 监听信号
sigQueue := make(chan os.Signal) var sigQueue = make(chan os.Signal, 8)
signal.Notify(sigQueue, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL, syscall.SIGQUIT) signal.Notify(sigQueue, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL, syscall.SIGQUIT)
go func() { go func() {
for range sigQueue { for range sigQueue {
@@ -106,8 +107,7 @@ func (this *AdminNode) Run() {
// Daemon 实现守护进程 // Daemon 实现守护进程
func (this *AdminNode) Daemon() { func (this *AdminNode) Daemon() {
var sock = gosock.NewTmpSock(teaconst.ProcessName) var sock = gosock.NewTmpSock(teaconst.ProcessName)
isDebug := lists.ContainsString(os.Args, "debug") var isDebug = lists.ContainsString(os.Args, "debug")
isDebug = true
for { for {
conn, err := sock.Dial() conn, err := sock.Dial()
if err != nil { if err != nil {
@@ -185,7 +185,7 @@ func (this *AdminNode) checkServer() error {
if err == nil { if err == nil {
err = os.WriteFile(configFile, data, 0666) err = os.WriteFile(configFile, data, 0666)
if err != nil { if err != nil {
return errors.New("create config file failed: " + err.Error()) return fmt.Errorf("create config file failed: %w", err)
} }
} else { } else {
templateYAML := `# environment code templateYAML := `# environment code
@@ -205,11 +205,11 @@ https:
` `
err = os.WriteFile(configFile, []byte(templateYAML), 0666) err = os.WriteFile(configFile, []byte(templateYAML), 0666)
if err != nil { if err != nil {
return errors.New("create config file failed: " + err.Error()) return fmt.Errorf("create config file failed: %w", err)
} }
} }
} else { } else {
return errors.New("can not read config from 'configs/server.yaml': " + err.Error()) return fmt.Errorf("can not read config from 'configs/server.yaml': %w", err)
} }
return nil return nil
@@ -255,7 +255,7 @@ func (this *AdminNode) addPortsToFirewall() {
// 启动API节点 // 启动API节点
func (this *AdminNode) startAPINode() { func (this *AdminNode) startAPINode() {
configPath := Tea.Root + "/edge-api/configs/api.yaml" var configPath = Tea.Root + "/edge-api/configs/api.yaml"
_, err := os.Stat(configPath) _, err := os.Stat(configPath)
canStart := false canStart := false
if err == nil { if err == nil {

View File

@@ -5,6 +5,7 @@ import (
"crypto/tls" "crypto/tls"
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt"
"github.com/TeaOSLab/EdgeAdmin/internal/configs" "github.com/TeaOSLab/EdgeAdmin/internal/configs"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/TeaOSLab/EdgeAdmin/internal/encrypt" "github.com/TeaOSLab/EdgeAdmin/internal/encrypt"
@@ -522,10 +523,10 @@ func (this *RPCClient) init() error {
// 重新连接 // 重新连接
var conns = []*grpc.ClientConn{} var conns = []*grpc.ClientConn{}
for _, endpoint := range this.apiConfig.RPC.Endpoints { for _, endpoint := range this.apiConfig.RPCEndpoints {
u, err := url.Parse(endpoint) u, err := url.Parse(endpoint)
if err != nil { if err != nil {
return errors.New("parse endpoint failed: " + err.Error()) return fmt.Errorf("parse endpoint failed: %w", err)
} }
var apiHost = u.Host var apiHost = u.Host

View File

@@ -2,8 +2,6 @@ package setup
import ( import (
"github.com/TeaOSLab/EdgeAdmin/internal/configs" "github.com/TeaOSLab/EdgeAdmin/internal/configs"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"os"
) )
var isConfigured bool var isConfigured bool
@@ -21,13 +19,5 @@ func IsConfigured() bool {
// IsNewInstalled IsNew 检查是否新安装 // IsNewInstalled IsNew 检查是否新安装
func IsNewInstalled() bool { func IsNewInstalled() bool {
homeDir, err := os.UserHomeDir() return configs.IsNewInstalled()
if err != nil {
return false
}
_, err = os.Stat(homeDir + "/." + teaconst.ProcessName + "/api.yaml")
if err != nil {
return true
}
return false
} }

View File

@@ -5,6 +5,7 @@ package tasks
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/TeaOSLab/EdgeAdmin/internal/events" "github.com/TeaOSLab/EdgeAdmin/internal/events"
"github.com/TeaOSLab/EdgeAdmin/internal/goman" "github.com/TeaOSLab/EdgeAdmin/internal/goman"
@@ -59,11 +60,11 @@ func (this *CheckUpdatesTask) Loop() error {
return err return err
} }
var valueJSON = valueResp.ValueJSON var valueJSON = valueResp.ValueJSON
var config = &systemconfigs.CheckUpdatesConfig{AutoCheck: false} var config = systemconfigs.NewCheckUpdatesConfig()
if len(valueJSON) > 0 { if len(valueJSON) > 0 {
err = json.Unmarshal(valueJSON, config) err = json.Unmarshal(valueJSON, config)
if err != nil { if err != nil {
return errors.New("decode config failed: " + err.Error()) return fmt.Errorf("decode config failed: %w", err)
} }
if !config.AutoCheck { if !config.AutoCheck {
return nil return nil
@@ -90,7 +91,7 @@ func (this *CheckUpdatesTask) Loop() error {
apiURL = strings.ReplaceAll(apiURL, "${version}", teaconst.Version) apiURL = strings.ReplaceAll(apiURL, "${version}", teaconst.Version)
resp, err := http.Get(apiURL) resp, err := http.Get(apiURL)
if err != nil { if err != nil {
return errors.New("read api failed: " + err.Error()) return fmt.Errorf("read api failed: %w", err)
} }
defer func() { defer func() {
@@ -98,13 +99,13 @@ func (this *CheckUpdatesTask) Loop() error {
}() }()
data, err := io.ReadAll(resp.Body) data, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return errors.New("read api failed: " + err.Error()) return fmt.Errorf("read api failed: %w", err)
} }
var apiResponse = &Response{} var apiResponse = &Response{}
err = json.Unmarshal(data, apiResponse) err = json.Unmarshal(data, apiResponse)
if err != nil { if err != nil {
return errors.New("decode version data failed: " + err.Error()) return fmt.Errorf("decode version data failed: %w", err)
} }
if apiResponse.Code != 200 { if apiResponse.Code != 200 {

View File

@@ -65,7 +65,7 @@ func (this *SyncAPINodesTask) Loop() error {
} }
// 是否禁止自动升级 // 是否禁止自动升级
if config.RPC.DisableUpdate { if config.RPCDisableUpdate {
return nil return nil
} }
@@ -88,7 +88,7 @@ func (this *SyncAPINodesTask) Loop() error {
} }
// 和现有的对比 // 和现有的对比
if this.isSame(newEndpoints, config.RPC.Endpoints) { if this.isSame(newEndpoints, config.RPCEndpoints) {
return nil return nil
} }
@@ -99,14 +99,14 @@ func (this *SyncAPINodesTask) Loop() error {
} }
// 修改RPC对象配置 // 修改RPC对象配置
config.RPC.Endpoints = newEndpoints config.RPCEndpoints = newEndpoints
err = rpcClient.UpdateConfig(config) err = rpcClient.UpdateConfig(config)
if err != nil { if err != nil {
return err return err
} }
// 保存到文件 // 保存到文件
err = config.WriteFile(Tea.ConfigFile("api.yaml")) err = config.WriteFile(Tea.ConfigFile(configs.ConfigFileName))
if err != nil { if err != nil {
return err return err
} }

View File

@@ -10,8 +10,10 @@ var DefaultCache = NewCache()
// TTL缓存 // TTL缓存
// 最大的缓存时间为30 * 86400 // 最大的缓存时间为30 * 86400
// Piece数据结构 // Piece数据结构
// Piece1 | Piece2 | Piece3 | ... //
// [ Item1, Item2, ... | ... // Piece1 | Piece2 | Piece3 | ...
// [ Item1, Item2, ... | ...
//
// KeyMap列表数据结构 // KeyMap列表数据结构
// { timestamp1 => [key1, key2, ...] }, ... // { timestamp1 => [key1, key2, ...] }, ...
type Cache struct { type Cache struct {
@@ -109,19 +111,11 @@ func (this *Cache) Read(key string) (item *Item) {
return this.pieces[uint64Key%this.countPieces].Read(uint64Key) return this.pieces[uint64Key%this.countPieces].Read(uint64Key)
} }
func (this *Cache) readIntKey(key uint64) (value *Item) {
return this.pieces[key%this.countPieces].Read(key)
}
func (this *Cache) Delete(key string) { func (this *Cache) Delete(key string) {
uint64Key := HashKey([]byte(key)) uint64Key := HashKey([]byte(key))
this.pieces[uint64Key%this.countPieces].Delete(uint64Key) this.pieces[uint64Key%this.countPieces].Delete(uint64Key)
} }
func (this *Cache) deleteIntKey(key uint64) {
this.pieces[key%this.countPieces].Delete(key)
}
func (this *Cache) Count() (count int) { func (this *Cache) Count() (count int) {
for _, piece := range this.pieces { for _, piece := range this.pieces {
count += piece.Count() count += piece.Count()

View File

@@ -57,7 +57,7 @@ func (this *Upgrader) Upgrade() error {
return err return err
} }
var newAPIConfig = apiConfig.Clone() var newAPIConfig = apiConfig.Clone()
newAPIConfig.RPC.Endpoints = apiNode.AccessAddrs newAPIConfig.RPCEndpoints = apiNode.AccessAddrs
rpcClient, err := rpc.NewRPCClient(newAPIConfig, false) rpcClient, err := rpc.NewRPCClient(newAPIConfig, false)
if err != nil { if err != nil {
@@ -79,7 +79,7 @@ func (this *Upgrader) Upgrade() error {
// 升级API节点 // 升级API节点
err = this.upgradeAPINode(sharedClient.Context(0), rpcClient) err = this.upgradeAPINode(sharedClient.Context(0), rpcClient)
if err != nil { if err != nil {
return errors.New("upgrade api node failed: " + err.Error()) return fmt.Errorf("upgrade api node failed: %w", err)
} }
return nil return nil
@@ -109,7 +109,7 @@ func (this *Upgrader) upgradeAPINode(ctx context.Context, rpcClient *rpc.RPCClie
localVersion, err := lookupLocalVersion() localVersion, err := lookupLocalVersion()
if err != nil { if err != nil {
return errors.New("lookup version failed: " + err.Error()) return fmt.Errorf("lookup version failed: %w", err)
} }
// 检查要升级的文件 // 检查要升级的文件
@@ -251,7 +251,7 @@ func (this *Upgrader) upgradeNodes(ctx context.Context, rpcClient *rpc.RPCClient
if !ok || stringutil.VersionCompare(remoteDeployFile.Version, deployFile.Version) < 0 { if !ok || stringutil.VersionCompare(remoteDeployFile.Version, deployFile.Version) < 0 {
err = this.uploadNodeDeployFile(ctx, rpcClient, deployFile.Path) err = this.uploadNodeDeployFile(ctx, rpcClient, deployFile.Path)
if err != nil { if err != nil {
return errors.New("upload deploy file '" + filepath.Base(deployFile.Path) + "' failed: " + err.Error()) return fmt.Errorf("upload deploy file '%s' failed: %w", filepath.Base(deployFile.Path), err)
} }
} }
} }
@@ -284,7 +284,7 @@ func (this *Upgrader) upgradeNSNodes(ctx context.Context, rpcClient *rpc.RPCClie
if !ok || stringutil.VersionCompare(remoteDeployFile.Version, deployFile.Version) < 0 { if !ok || stringutil.VersionCompare(remoteDeployFile.Version, deployFile.Version) < 0 {
err = this.uploadNodeDeployFile(ctx, rpcClient, deployFile.Path) err = this.uploadNodeDeployFile(ctx, rpcClient, deployFile.Path)
if err != nil { if err != nil {
return errors.New("upload deploy file '" + filepath.Base(deployFile.Path) + "' failed: " + err.Error()) return fmt.Errorf("upload deploy file '%s' failed: %w", filepath.Base(deployFile.Path), err)
} }
} }
} }

View File

@@ -5,6 +5,7 @@ package utils
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"reflect" "reflect"
) )
@@ -24,7 +25,36 @@ func JSONClone(v interface{}) (interface{}, error) {
return nv, nil return nv, nil
} }
// 判断JSON数据是否为null // JSONIsNull 判断JSON数据是否为null
func JSONIsNull(jsonData []byte) bool { func JSONIsNull(jsonData []byte) bool {
return len(jsonData) == 0 || bytes.Equal(jsonData, []byte("null")) return len(jsonData) == 0 || bytes.Equal(jsonData, []byte("null"))
} }
// JSONDecodeConfig 解码并重新编码
// 是为了去除原有JSON中不需要的数据
func JSONDecodeConfig(data []byte, ptr any) (encodeJSON []byte, err error) {
err = json.Unmarshal(data, ptr)
if err != nil {
return
}
encodeJSON, err = json.Marshal(ptr)
if err != nil {
return
}
// validate config
if ptr != nil {
config, ok := ptr.(interface {
Init() error
})
if ok {
initErr := config.Init()
if initErr != nil {
err = errors.New("validate config failed: " + initErr.Error())
}
}
}
return
}

View File

@@ -39,7 +39,7 @@ func (this *ServiceManager) setup() {
this.onceLocker.Do(func() { this.onceLocker.Do(func() {
logFile := files.NewFile(Tea.Root + "/logs/service.log") logFile := files.NewFile(Tea.Root + "/logs/service.log")
if logFile.Exists() { if logFile.Exists() {
logFile.Delete() _ = logFile.Delete()
} }
//logger //logger

View File

@@ -59,10 +59,10 @@ func (this *ServiceManager) Uninstall() error {
} }
// disable service // disable service
exec.Command(systemd, "disable", teaconst.SystemdServiceName+".service").Start() _ = exec.Command(systemd, "disable", teaconst.SystemdServiceName+".service").Start()
// reload // reload
exec.Command(systemd, "daemon-reload") _ = exec.Command(systemd, "daemon-reload").Start()
return files.NewFile(systemdServiceFile).Delete() return files.NewFile(systemdServiceFile).Delete()
} }
@@ -143,10 +143,10 @@ WantedBy=multi-user.target`
} }
// stop current systemd service if running // stop current systemd service if running
exec.Command(systemd, "stop", shortName+".service") _ = exec.Command(systemd, "stop", shortName+".service").Start()
// reload // reload
exec.Command(systemd, "daemon-reload") _ = exec.Command(systemd, "daemon-reload").Start()
// enable // enable
cmd := exec.Command(systemd, "enable", shortName+".service") cmd := exec.Command(systemd, "enable", shortName+".service")

View File

@@ -4,6 +4,7 @@ package utils
import ( import (
"fmt" "fmt"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"golang.org/x/sys/windows" "golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc" "golang.org/x/sys/windows/svc"
@@ -15,7 +16,7 @@ import (
func (this *ServiceManager) Install(exePath string, args []string) error { func (this *ServiceManager) Install(exePath string, args []string) error {
m, err := mgr.Connect() m, err := mgr.Connect()
if err != nil { if err != nil {
return fmt.Errorf("connecting: %s please 'Run as administrator' again", err.Error()) return fmt.Errorf("connecting: %w please 'Run as administrator' again", err)
} }
defer m.Disconnect() defer m.Disconnect()
s, err := m.OpenService(this.Name) s, err := m.OpenService(this.Name)
@@ -30,7 +31,7 @@ func (this *ServiceManager) Install(exePath string, args []string) error {
StartType: windows.SERVICE_AUTO_START, StartType: windows.SERVICE_AUTO_START,
}, args...) }, args...)
if err != nil { if err != nil {
return fmt.Errorf("creating: %s", err.Error()) return fmt.Errorf("creating: %w", err)
} }
defer s.Close() defer s.Close()
@@ -46,12 +47,12 @@ func (this *ServiceManager) Start() error {
defer m.Disconnect() defer m.Disconnect()
s, err := m.OpenService(this.Name) s, err := m.OpenService(this.Name)
if err != nil { if err != nil {
return fmt.Errorf("could not access service: %v", err) return fmt.Errorf("could not access service: %w", err)
} }
defer s.Close() defer s.Close()
err = s.Start("service") err = s.Start("service")
if err != nil { if err != nil {
return fmt.Errorf("could not start service: %v", err) return fmt.Errorf("could not start service: %w", err)
} }
return nil return nil
@@ -61,12 +62,12 @@ func (this *ServiceManager) Start() error {
func (this *ServiceManager) Uninstall() error { func (this *ServiceManager) Uninstall() error {
m, err := mgr.Connect() m, err := mgr.Connect()
if err != nil { if err != nil {
return fmt.Errorf("connecting: %s please 'Run as administrator' again", err.Error()) return fmt.Errorf("connecting: %w please 'Run as administrator' again", err)
} }
defer m.Disconnect() defer m.Disconnect()
s, err := m.OpenService(this.Name) s, err := m.OpenService(this.Name)
if err != nil { if err != nil {
return fmt.Errorf("open service: %s", err.Error()) return fmt.Errorf("open service: %w", err)
} }
// shutdown service // shutdown service
@@ -78,7 +79,7 @@ func (this *ServiceManager) Uninstall() error {
defer s.Close() defer s.Close()
err = s.Delete() err = s.Delete()
if err != nil { if err != nil {
return fmt.Errorf("deleting: %s", err.Error()) return fmt.Errorf("deleting: %w", err)
} }
return nil return nil
} }

View File

@@ -7,6 +7,7 @@ import (
"crypto/tls" "crypto/tls"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/iwind/TeaGo/Tea" "github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
@@ -111,13 +112,13 @@ func (this *UpgradeManager) Start() error {
url = strings.ReplaceAll(url, "${version}", teaconst.Version) url = strings.ReplaceAll(url, "${version}", teaconst.Version)
req, err := http.NewRequest(http.MethodGet, url, nil) req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil { if err != nil {
return errors.New("create url request failed: " + err.Error()) return fmt.Errorf("create url request failed: %w", err)
} }
req.Header.Set("User-Agent", "Edge-Admin/"+teaconst.Version) req.Header.Set("User-Agent", "Edge-Admin/"+teaconst.Version)
resp, err := this.client.Do(req) resp, err := this.client.Do(req)
if err != nil { if err != nil {
return errors.New("read latest version failed: " + err.Error()) return fmt.Errorf("read latest version failed: %w", err)
} }
defer func() { defer func() {
@@ -130,13 +131,13 @@ func (this *UpgradeManager) Start() error {
data, err := io.ReadAll(resp.Body) data, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return errors.New("read latest version failed: " + err.Error()) return fmt.Errorf("read latest version failed: %w", err)
} }
var m = maps.Map{} var m = maps.Map{}
err = json.Unmarshal(data, &m) err = json.Unmarshal(data, &m)
if err != nil { if err != nil {
return errors.New("invalid response data: " + err.Error() + ", origin data: " + string(data)) return fmt.Errorf("invalid response data: %w, origin data: %s", err, string(data))
} }
var code = m.GetInt("code") var code = m.GetInt("code")
@@ -172,13 +173,13 @@ func (this *UpgradeManager) Start() error {
{ {
req, err := http.NewRequest(http.MethodGet, downloadURL, nil) req, err := http.NewRequest(http.MethodGet, downloadURL, nil)
if err != nil { if err != nil {
return errors.New("create download request failed: " + err.Error()) return fmt.Errorf("create download request failed: %w", err)
} }
req.Header.Set("User-Agent", "Edge-Admin/"+teaconst.Version) req.Header.Set("User-Agent", "Edge-Admin/"+teaconst.Version)
resp, err := this.client.Do(req) resp, err := this.client.Do(req)
if err != nil { if err != nil {
return errors.New("download failed: " + downloadURL + ": " + err.Error()) return fmt.Errorf("download failed: '%s': %w", downloadURL, err)
} }
defer func() { defer func() {
@@ -201,7 +202,7 @@ func (this *UpgradeManager) Start() error {
fp, err := os.Create(destFile) fp, err := os.Create(destFile)
if err != nil { if err != nil {
return errors.New("create file failed: " + err.Error()) return fmt.Errorf("create file failed: %w", err)
} }
defer func() { defer func() {
@@ -217,7 +218,7 @@ func (this *UpgradeManager) Start() error {
if this.isCancelled { if this.isCancelled {
return nil return nil
} }
return errors.New("download failed: " + err.Error()) return fmt.Errorf("download failed: %w", err)
} }
_ = fp.Close() _ = fp.Close()
@@ -228,7 +229,7 @@ func (this *UpgradeManager) Start() error {
if err == nil && stat.IsDir() { if err == nil && stat.IsDir() {
err = os.RemoveAll(unzipDir) err = os.RemoveAll(unzipDir)
if err != nil { if err != nil {
return errors.New("remove old dir '" + unzipDir + "' failed: " + err.Error()) return fmt.Errorf("remove old dir '%s' failed: %w", unzipDir, err)
} }
} }
var unzipCmd = exec.Command(unzipExe, "-q", "-o", destFile, "-d", unzipDir) var unzipCmd = exec.Command(unzipExe, "-q", "-o", destFile, "-d", unzipDir)
@@ -236,18 +237,18 @@ func (this *UpgradeManager) Start() error {
unzipCmd.Stderr = unzipStderr unzipCmd.Stderr = unzipStderr
err = unzipCmd.Run() err = unzipCmd.Run()
if err != nil { if err != nil {
return errors.New("unzip installation file failed: " + err.Error() + ": " + unzipStderr.String()) return fmt.Errorf("unzip installation file failed: %w: %s", err, unzipStderr.String())
} }
installationFiles, err := filepath.Glob(unzipDir + "/edge-" + this.component + "/*") installationFiles, err := filepath.Glob(unzipDir + "/edge-" + this.component + "/*")
if err != nil { if err != nil {
return errors.New("lookup installation files failed: " + err.Error()) return fmt.Errorf("lookup installation files failed: %w", err)
} }
// cp to target dir // cp to target dir
currentExe, err := os.Executable() currentExe, err := os.Executable()
if err != nil { if err != nil {
return errors.New("reveal current executable file path failed: " + err.Error()) return fmt.Errorf("reveal current executable file path failed: %w", err)
} }
var targetDir = filepath.Dir(filepath.Dir(currentExe)) var targetDir = filepath.Dir(filepath.Dir(currentExe))
if !Tea.IsTesting() { if !Tea.IsTesting() {

View File

@@ -107,13 +107,13 @@ func MatchPath(action *actions.ActionObject, path string) bool {
// FindParentAction 查找父级Action // FindParentAction 查找父级Action
func FindParentAction(actionPtr actions.ActionWrapper) *ParentAction { func FindParentAction(actionPtr actions.ActionWrapper) *ParentAction {
parentActionValue := reflect.ValueOf(actionPtr).Elem().FieldByName("ParentAction") action, ok := actionPtr.(interface {
if parentActionValue.IsValid() { Parent() *ParentAction
parentAction, isOk := parentActionValue.Interface().(ParentAction) })
if isOk { if ok {
return &parentAction return action.Parent()
}
} }
return nil return nil
} }
@@ -140,7 +140,7 @@ func findStack(err string) string {
filename = filename[strings.Index(filename, "src"):] filename = filename[strings.Index(filename, "src"):]
} }
err += "\n\t\t" + string(filename) + ":" + fmt.Sprintf("%d", lineNo) err += "\n\t\t" + filename + ":" + fmt.Sprintf("%d", lineNo)
break break
} }
@@ -155,11 +155,11 @@ func parseAPIErr(action actions.ActionWrapper, err error) (apiNodeIsStarting boo
var apiEndpoints = []string{} var apiEndpoints = []string{}
apiConfig, apiConfigErr := configs.LoadAPIConfig() apiConfig, apiConfigErr := configs.LoadAPIConfig()
if apiConfigErr == nil && apiConfig != nil { if apiConfigErr == nil && apiConfig != nil {
apiEndpoints = append(apiEndpoints, apiConfig.RPC.Endpoints...) apiEndpoints = append(apiEndpoints, apiConfig.RPCEndpoints...)
} }
var isRPCConnError bool var isRPCConnError bool
err, isRPCConnError = rpcerrors.HumanError(err, apiEndpoints, Tea.ConfigFile("api.yaml")) _, isRPCConnError = rpcerrors.HumanError(err, apiEndpoints, Tea.ConfigFile(configs.ConfigFileName))
if isRPCConnError { if isRPCConnError {
// API节点是否正在启动 // API节点是否正在启动
var sock = gosock.NewTmpSock("edge-api") var sock = gosock.NewTmpSock("edge-api")

View File

@@ -67,5 +67,5 @@ func (this *OtpQrcodeAction) RunGet(params struct {
return return
} }
this.AddHeader("Content-Type", "image/png") this.AddHeader("Content-Type", "image/png")
this.Write(data) _, _ = this.Write(data)
} }

View File

@@ -297,7 +297,7 @@ func (this *DetailAction) RunGet(params struct {
} }
// 缓存硬盘 & 内存容量 // 缓存硬盘 & 内存容量
var maxCacheDiskCapacity maps.Map = nil var maxCacheDiskCapacity maps.Map
if node.MaxCacheDiskCapacity != nil { if node.MaxCacheDiskCapacity != nil {
maxCacheDiskCapacity = maps.Map{ maxCacheDiskCapacity = maps.Map{
"count": node.MaxCacheDiskCapacity.Count, "count": node.MaxCacheDiskCapacity.Count,
@@ -310,7 +310,7 @@ func (this *DetailAction) RunGet(params struct {
} }
} }
var maxCacheMemoryCapacity maps.Map = nil var maxCacheMemoryCapacity maps.Map
if node.MaxCacheMemoryCapacity != nil { if node.MaxCacheMemoryCapacity != nil {
maxCacheMemoryCapacity = maps.Map{ maxCacheMemoryCapacity = maps.Map{
"count": node.MaxCacheMemoryCapacity.Count, "count": node.MaxCacheMemoryCapacity.Count,
@@ -389,6 +389,7 @@ func (this *DetailAction) RunGet(params struct {
"exePath": status.ExePath, "exePath": status.ExePath,
"apiSuccessPercent": status.APISuccessPercent, "apiSuccessPercent": status.APISuccessPercent,
"apiAvgCostSeconds": status.APIAvgCostSeconds, "apiAvgCostSeconds": status.APIAvgCostSeconds,
"diskWritingSpeedMB": status.DiskWritingSpeedMB,
}, },
"group": groupMap, "group": groupMap,

View File

@@ -2,9 +2,11 @@ package node
import ( import (
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -109,6 +111,26 @@ func (this *InstallAction) RunGet(params struct {
var installerFiles = clusterutils.ListInstallerFiles() var installerFiles = clusterutils.ListInstallerFiles()
this.Data["installerFiles"] = installerFiles this.Data["installerFiles"] = installerFiles
// SSH主机地址
this.Data["sshAddr"] = ""
if node.NodeLogin != nil && node.NodeLogin.Type == "ssh" && !utils.JSONIsNull(node.NodeLogin.Params) {
var loginParams = maps.Map{}
err = json.Unmarshal(node.NodeLogin.Params, &loginParams)
if err != nil {
this.ErrorPage(err)
return
}
var host = loginParams.GetString("host")
if len(host) > 0 {
var port = loginParams.GetString("port")
if port == "0" {
port = "22"
}
this.Data["sshAddr"] = configutils.QuoteIP(host) + ":" + port
}
}
this.Show() this.Show()
} }

View File

@@ -33,7 +33,7 @@ func (this *IndexAction) RunGet(params struct {
} }
// 缓存硬盘 & 内存容量 // 缓存硬盘 & 内存容量
var maxCacheDiskCapacity maps.Map = nil var maxCacheDiskCapacity maps.Map
if node.MaxCacheDiskCapacity != nil { if node.MaxCacheDiskCapacity != nil {
maxCacheDiskCapacity = maps.Map{ maxCacheDiskCapacity = maps.Map{
"count": node.MaxCacheDiskCapacity.Count, "count": node.MaxCacheDiskCapacity.Count,
@@ -46,7 +46,7 @@ func (this *IndexAction) RunGet(params struct {
} }
} }
var maxCacheMemoryCapacity maps.Map = nil var maxCacheMemoryCapacity maps.Map
if node.MaxCacheMemoryCapacity != nil { if node.MaxCacheMemoryCapacity != nil {
maxCacheMemoryCapacity = maps.Map{ maxCacheMemoryCapacity = maps.Map{
"count": node.MaxCacheMemoryCapacity.Count, "count": node.MaxCacheMemoryCapacity.Count,

View File

@@ -48,7 +48,7 @@ func (this *IndexAction) RunGet(params struct {
} }
var grantMap = maps.Map{} var grantMap = maps.Map{}
grantId := loginParams.GetInt64("grantId") var grantId = loginParams.GetInt64("grantId")
if grantId > 0 { if grantId > 0 {
grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId}) grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId})
if err != nil { if err != nil {

View File

@@ -10,6 +10,8 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"regexp"
) )
type IndexAction struct { type IndexAction struct {
@@ -41,9 +43,14 @@ func (this *IndexAction) RunGet(params struct {
} }
this.Data["config"] = config this.Data["config"] = config
var httpAllDomainMismatchActionContentHTML = "" var httpAllDomainMismatchActionContentHTML string
if config.HTTPAll.DomainMismatchAction != nil { var httpAllDomainMismatchActionStatusCode = "404"
if config.HTTPAll.DomainMismatchAction != nil && config.HTTPAll.DomainMismatchAction.Options != nil {
httpAllDomainMismatchActionContentHTML = config.HTTPAll.DomainMismatchAction.Options.GetString("contentHTML") httpAllDomainMismatchActionContentHTML = config.HTTPAll.DomainMismatchAction.Options.GetString("contentHTML")
var statusCode = config.HTTPAll.DomainMismatchAction.Options.GetInt("statusCode")
if statusCode > 0 {
httpAllDomainMismatchActionStatusCode = types.String(statusCode)
}
} else { } else {
httpAllDomainMismatchActionContentHTML = `<!DOCTYPE html> httpAllDomainMismatchActionContentHTML = `<!DOCTYPE html>
<html lang="en"> <html lang="en">
@@ -67,6 +74,7 @@ p { color: grey; }
} }
this.Data["httpAllDomainMismatchActionContentHTML"] = httpAllDomainMismatchActionContentHTML this.Data["httpAllDomainMismatchActionContentHTML"] = httpAllDomainMismatchActionContentHTML
this.Data["httpAllDomainMismatchActionStatusCode"] = httpAllDomainMismatchActionStatusCode
this.Show() this.Show()
} }
@@ -76,6 +84,7 @@ func (this *IndexAction) RunPost(params struct {
HttpAllMatchDomainStrictly bool HttpAllMatchDomainStrictly bool
HttpAllDomainMismatchActionContentHTML string HttpAllDomainMismatchActionContentHTML string
HttpAllDomainMismatchActionStatusCode string
HttpAllAllowMismatchDomainsJSON []byte HttpAllAllowMismatchDomainsJSON []byte
HttpAllAllowNodeIP bool HttpAllAllowNodeIP bool
HttpAllDefaultDomain string HttpAllDefaultDomain string
@@ -121,11 +130,18 @@ func (this *IndexAction) RunPost(params struct {
} }
} }
var domainMisMatchStatusCodeString = params.HttpAllDomainMismatchActionStatusCode
if !regexp.MustCompile(`^\d{3}$`).MatchString(domainMisMatchStatusCodeString) {
this.FailField("httpAllDomainMismatchActionContentStatusCode", "请输入正确的状态码")
return
}
var domainMisMatchStatusCode = types.Int(domainMisMatchStatusCodeString)
config.HTTPAll.MatchDomainStrictly = params.HttpAllMatchDomainStrictly config.HTTPAll.MatchDomainStrictly = params.HttpAllMatchDomainStrictly
config.HTTPAll.DomainMismatchAction = &serverconfigs.DomainMismatchAction{ config.HTTPAll.DomainMismatchAction = &serverconfigs.DomainMismatchAction{
Code: serverconfigs.DomainMismatchActionPage, Code: serverconfigs.DomainMismatchActionPage,
Options: maps.Map{ Options: maps.Map{
"statusCode": 404, "statusCode": domainMisMatchStatusCode,
"contentHTML": params.HttpAllDomainMismatchActionContentHTML, "contentHTML": params.HttpAllDomainMismatchActionContentHTML,
}, },
} }

View File

@@ -10,7 +10,6 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/health" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/health"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/metrics" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/metrics"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/services" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/services"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/toa"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/waf" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/waf"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/webp" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/webp"
clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils" clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
@@ -43,10 +42,6 @@ func init() {
GetPost("", new(dns.IndexAction)). GetPost("", new(dns.IndexAction)).
Post("/randomName", new(dns.RandomNameAction)). Post("/randomName", new(dns.RandomNameAction)).
// TOA
Prefix("/clusters/cluster/settings/toa").
GetPost("", new(toa.IndexAction)).
// 系统服务设置 // 系统服务设置
Prefix("/clusters/cluster/settings/services"). Prefix("/clusters/cluster/settings/services").
GetPost("", new(services.IndexAction)). GetPost("", new(services.IndexAction)).

View File

@@ -1,83 +0,0 @@
package toa
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "")
this.SecondMenu("toa")
}
func (this *IndexAction) RunGet(params struct {
ClusterId int64
}) {
toaResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterTOA(this.AdminContext(), &pb.FindEnabledNodeClusterTOARequest{NodeClusterId: params.ClusterId})
if err != nil {
this.ErrorPage(err)
return
}
if len(toaResp.ToaJSON) == 0 {
this.Data["toa"] = nodeconfigs.DefaultTOAConfig()
} else {
config := &nodeconfigs.TOAConfig{}
err = json.Unmarshal(toaResp.ToaJSON, config)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["toa"] = config
}
this.Show()
}
func (this *IndexAction) RunPost(params struct {
ClusterId int64
IsOn bool
AutoSetup bool
OptionType uint8
MinQueueId uint8
MaxQueueId uint8
Must *actions.Must
CSRF *actionutils.CSRF
}) {
defer this.CreateLogInfo(codes.NodeTOA_LogUpdateClusterTOA, params.ClusterId)
config := &nodeconfigs.TOAConfig{
IsOn: params.IsOn,
Debug: false, // 暂时不允许打开调试
OptionType: params.OptionType,
MinQueueId: params.MinQueueId,
MaxQueueId: params.MaxQueueId,
AutoSetup: params.AutoSetup,
}
configJSON, err := json.Marshal(config)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().NodeClusterRPC().UpdateNodeClusterTOA(this.AdminContext(), &pb.UpdateNodeClusterTOARequest{
NodeClusterId: params.ClusterId,
ToaJSON: configJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -19,7 +19,7 @@ func (this *Helper) BeforeAction(action *actions.ActionObject) {
action.Data["teaMenu"] = "db" action.Data["teaMenu"] = "db"
selectedTabbar, _ := action.Data["mainTab"] var selectedTabbar = action.Data["mainTab"]
var tabbar = actionutils.NewTabbar() var tabbar = actionutils.NewTabbar()
tabbar.Add(this.Lang(action, codes.DBNode_TabNodes), "", "/db", "", selectedTabbar == "db") tabbar.Add(this.Lang(action, codes.DBNode_TabNodes), "", "/db", "", selectedTabbar == "db")

View File

@@ -63,6 +63,10 @@ func (this *LogsAction) RunGet(params struct {
Offset: page.Offset, Offset: page.Offset,
Size: page.Size, Size: page.Size,
}) })
if err != nil {
this.ErrorPage(err)
return
}
logs := []maps.Map{} logs := []maps.Map{}
for _, log := range logsResp.NodeLogs { for _, log := range logsResp.NodeLogs {

View File

@@ -101,9 +101,7 @@ func ValidateRecordValue(recordType dnsconfigs.RecordType, value string) (messag
return return
} }
case dnsconfigs.RecordTypeCNAME: case dnsconfigs.RecordTypeCNAME:
if strings.HasSuffix(value, ".") { value = strings.TrimSuffix(value, ".")
value = value[:len(value)-1]
}
if !strings.Contains(value, ".") || !ValidateDomainFormat(value) { if !strings.Contains(value, ".") || !ValidateDomainFormat(value) {
message = "请输入正确的域名" message = "请输入正确的域名"
return return
@@ -118,17 +116,13 @@ func ValidateRecordValue(recordType dnsconfigs.RecordType, value string) (messag
return return
} }
case dnsconfigs.RecordTypeNS: case dnsconfigs.RecordTypeNS:
if strings.HasSuffix(value, ".") { value = strings.TrimSuffix(value, ".")
value = value[:len(value)-1]
}
if !strings.Contains(value, ".") || !ValidateDomainFormat(value) { if !strings.Contains(value, ".") || !ValidateDomainFormat(value) {
message = "请输入正确的DNS服务器域名" message = "请输入正确的DNS服务器域名"
return return
} }
case dnsconfigs.RecordTypeMX: case dnsconfigs.RecordTypeMX:
if strings.HasSuffix(value, ".") { value = strings.TrimSuffix(value, ".")
value = value[:len(value)-1]
}
if !strings.Contains(value, ".") || !ValidateDomainFormat(value) { if !strings.Contains(value, ".") || !ValidateDomainFormat(value) {
message = "请输入正确的邮件服务器域名" message = "请输入正确的邮件服务器域名"
return return

View File

@@ -28,7 +28,7 @@ func (this *IndexAction) RunGet(params struct {
// 格式化域名 // 格式化域名
var domain = params.Domain var domain = params.Domain
domain = regexp.MustCompile(`^(www\.)`).ReplaceAllString(params.Domain, "") domain = regexp.MustCompile(`^(www\.)`).ReplaceAllString(domain, "")
domain = strings.ToLower(domain) domain = strings.ToLower(domain)
countResp, err := this.RPC().DNSProviderRPC().CountAllEnabledDNSProviders(this.AdminContext(), &pb.CountAllEnabledDNSProvidersRequest{ countResp, err := this.RPC().DNSProviderRPC().CountAllEnabledDNSProviders(this.AdminContext(), &pb.CountAllEnabledDNSProvidersRequest{

View File

@@ -57,6 +57,6 @@ func (this *FileAction) RunGet(params struct {
if chunkResp.FileChunk == nil { if chunkResp.FileChunk == nil {
continue continue
} }
this.Write(chunkResp.FileChunk.Data) _, _ = this.Write(chunkResp.FileChunk.Data)
} }
} }

View File

@@ -123,5 +123,5 @@ func (this *ExportExcelAction) RunGet(params struct {
} }
this.AddHeader("Content-Length", strconv.Itoa(buf.Len())) this.AddHeader("Content-Length", strconv.Itoa(buf.Len()))
this.Write(buf.Bytes()) _, _ = this.Write(buf.Bytes())
} }

View File

@@ -36,7 +36,7 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
if addrId > 0 { if addrId > 0 {
resultAddrIds = append(resultAddrIds, addrId) resultAddrIds = append(resultAddrIds, addrId)
var isOn = false var isOn bool
if !addr.Has("isOn") { // 兼容老版本 if !addr.Has("isOn") { // 兼容老版本
isOn = true isOn = true
} else { } else {

View File

@@ -101,14 +101,9 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
apiNode := apiNodeResp.ApiNode apiNode := apiNodeResp.ApiNode
apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{ apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{
RPC: struct { RPCEndpoints: apiNode.AccessAddrs,
Endpoints []string `yaml:"endpoints"` NodeId: apiNode.UniqueId,
DisableUpdate bool `yaml:"disableUpdate"` Secret: apiNode.Secret,
}{
Endpoints: apiNode.AccessAddrs,
},
NodeId: apiNode.UniqueId,
Secret: apiNode.Secret,
}, false) }, false)
if err != nil { if err != nil {
locker.Lock() locker.Lock()
@@ -282,14 +277,9 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
apiNode := apiNodeResp.ApiNode apiNode := apiNodeResp.ApiNode
apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{ apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{
RPC: struct { RPCEndpoints: apiNode.AccessAddrs,
Endpoints []string `yaml:"endpoints"` NodeId: apiNode.UniqueId,
DisableUpdate bool `yaml:"disableUpdate"` Secret: apiNode.Secret,
}{
Endpoints: apiNode.AccessAddrs,
},
NodeId: apiNode.UniqueId,
Secret: apiNode.Secret,
}, false) }, false)
if err != nil { if err != nil {
locker.Lock() locker.Lock()

View File

@@ -1,4 +1,4 @@
package recover package recovers
import ( import (
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"

View File

@@ -1,6 +1,6 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. // Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package recover package recovers
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"

View File

@@ -1,4 +1,4 @@
package recover package recovers
import "github.com/iwind/TeaGo" import "github.com/iwind/TeaGo"

View File

@@ -1,6 +1,6 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. // Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package recover package recovers
import ( import (
"bytes" "bytes"
@@ -35,14 +35,9 @@ func (this *UpdateHostsAction) RunPost(params struct {
} }
client, err := rpc.NewRPCClient(&configs.APIConfig{ client, err := rpc.NewRPCClient(&configs.APIConfig{
RPC: struct { RPCEndpoints: []string{params.Protocol + "://" + configutils.QuoteIP(params.Host) + ":" + params.Port},
Endpoints []string `yaml:"endpoints"` NodeId: params.NodeId,
DisableUpdate bool `yaml:"disableUpdate"` Secret: params.NodeSecret,
}{
Endpoints: []string{params.Protocol + "://" + configutils.QuoteIP(params.Host) + ":" + params.Port},
},
NodeId: params.NodeId,
Secret: params.NodeSecret,
}, false) }, false)
if err != nil { if err != nil {
this.FailField("host", "测试API节点时出错请检查配置错误信息"+err.Error()) this.FailField("host", "测试API节点时出错请检查配置错误信息"+err.Error())
@@ -165,23 +160,18 @@ func (this *UpdateHostsAction) RunPost(params struct {
} }
} }
// 修改api.yaml // 修改api_admin.yaml
var apiConfig = &configs.APIConfig{ var apiConfig = &configs.APIConfig{
RPC: struct { RPCEndpoints: endpoints,
Endpoints []string `yaml:"endpoints"` NodeId: adminAPIToken.NodeId,
DisableUpdate bool `yaml:"disableUpdate"` Secret: adminAPIToken.Secret,
}{
Endpoints: endpoints,
},
NodeId: adminAPIToken.NodeId,
Secret: adminAPIToken.Secret,
} }
err = apiConfig.WriteFile(Tea.Root + "/configs/api.yaml") err = apiConfig.WriteFile(Tea.Root + "/configs/" + configs.ConfigFileName)
if err != nil { if err != nil {
this.Fail("保存configs/api.yaml失败:" + err.Error()) this.Fail("保存configs/" + configs.ConfigFileName + "失败:" + err.Error())
} }
// 加载api.yaml // 加载api_admin.yaml
rpcClient, err := rpc.SharedRPC() rpcClient, err := rpc.SharedRPC()
if err != nil { if err != nil {
this.Fail("初始化RPC失败" + err.Error()) this.Fail("初始化RPC失败" + err.Error())

View File

@@ -1,4 +1,4 @@
package recover package recovers
import ( import (
"encoding/json" "encoding/json"
@@ -42,14 +42,9 @@ func (this *ValidateApiAction) RunPost(params struct {
Field("nodeSecret", params.NodeSecret). Field("nodeSecret", params.NodeSecret).
Require("请输入节点secret") Require("请输入节点secret")
client, err := rpc.NewRPCClient(&configs.APIConfig{ client, err := rpc.NewRPCClient(&configs.APIConfig{
RPC: struct { RPCEndpoints: []string{params.Protocol + "://" + configutils.QuoteIP(params.Host) + ":" + params.Port},
Endpoints []string `yaml:"endpoints"` NodeId: params.NodeId,
DisableUpdate bool `yaml:"disableUpdate"` Secret: params.NodeSecret,
}{
Endpoints: []string{params.Protocol + "://" + configutils.QuoteIP(params.Host) + ":" + params.Port},
},
NodeId: params.NodeId,
Secret: params.NodeSecret,
}, false) }, false)
if err != nil { if err != nil {
this.FailField("host", "测试API节点时出错请检查配置错误信息"+err.Error()) this.FailField("host", "测试API节点时出错请检查配置错误信息"+err.Error())

View File

@@ -36,5 +36,5 @@ func (this *DownloadCertAction) RunGet(params struct {
} }
this.AddHeader("Content-Disposition", "attachment; filename=\"cert-"+strconv.FormatInt(params.CertId, 10)+".pem\";") this.AddHeader("Content-Disposition", "attachment; filename=\"cert-"+strconv.FormatInt(params.CertId, 10)+".pem\";")
this.Write(certConfig.CertData) _, _ = this.Write(certConfig.CertData)
} }

View File

@@ -36,5 +36,5 @@ func (this *DownloadKeyAction) RunGet(params struct {
} }
this.AddHeader("Content-Disposition", "attachment; filename=\"key-"+strconv.FormatInt(params.CertId, 10)+".pem\";") this.AddHeader("Content-Disposition", "attachment; filename=\"key-"+strconv.FormatInt(params.CertId, 10)+".pem\";")
this.Write(certConfig.KeyData) _, _ = this.Write(certConfig.KeyData)
} }

View File

@@ -50,12 +50,12 @@ func (this *IndexAction) RunGet(params struct {
} }
this.Data["user"] = userMap this.Data["user"] = userMap
var countAll = int64(0) var countAll int64
var countCA = int64(0) var countCA int64
var countAvailable = int64(0) var countAvailable int64
var countExpired = int64(0) var countExpired int64
var count7Days = int64(0) var count7Days int64
var count30Days = int64(0) var count30Days int64
// 计算数量 // 计算数量
{ {

View File

@@ -172,6 +172,11 @@ func (this *SelectPopupAction) RunGet(params struct {
}) })
} }
if err != nil {
this.ErrorPage(err)
return
}
if listResp == nil { if listResp == nil {
this.ErrorPage(errors.New("'listResp' should not be nil")) this.ErrorPage(errors.New("'listResp' should not be nil"))
return return

View File

@@ -1,6 +1,7 @@
package certs package certs
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
@@ -120,7 +121,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
// 校验 // 校验
certConfig.IsCA = params.IsCA certConfig.IsCA = params.IsCA
err = certConfig.Init(nil) err = certConfig.Init(context.TODO())
if err != nil { if err != nil {
if params.IsCA { if params.IsCA {
this.Fail("证书校验错误:" + err.Error()) this.Fail("证书校验错误:" + err.Error())

View File

@@ -4,6 +4,7 @@ package certs
import ( import (
"bytes" "bytes"
"context"
"crypto/tls" "crypto/tls"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
@@ -156,7 +157,7 @@ func (this *UploadBatchPopupAction) RunPost(params struct {
CertData: certData, CertData: certData,
KeyData: keyData, KeyData: keyData,
} }
err := certConfig.Init(nil) err := certConfig.Init(context.TODO())
if err != nil { if err != nil {
this.Fail("证书验证失败:" + err.Error()) this.Fail("证书验证失败:" + err.Error())
return return

View File

@@ -1,6 +1,7 @@
package certs package certs
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
@@ -60,8 +61,8 @@ func (this *UploadPopupAction) RunPost(params struct {
Field("name", params.Name). Field("name", params.Name).
Require("请输入证书说明") Require("请输入证书说明")
var certData = []byte{} var certData []byte
var keyData = []byte{} var keyData []byte
if params.TextMode { if params.TextMode {
if len(params.CertText) == 0 { if len(params.CertText) == 0 {
@@ -104,7 +105,7 @@ func (this *UploadPopupAction) RunPost(params struct {
CertData: certData, CertData: certData,
KeyData: keyData, KeyData: keyData,
} }
err := certConfig.Init(nil) err := certConfig.Init(context.TODO())
if err != nil { if err != nil {
if params.IsCA { if params.IsCA {
this.Fail("证书校验错误:" + err.Error()) this.Fail("证书校验错误:" + err.Error())

View File

@@ -35,5 +35,5 @@ func (this *ViewCertAction) RunGet(params struct {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
this.Write(certConfig.CertData) _, _ = this.Write(certConfig.CertData)
} }

View File

@@ -30,5 +30,5 @@ func (this *ViewKeyAction) RunGet(params struct {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
this.Write(certConfig.KeyData) _, _ = this.Write(certConfig.KeyData)
} }

View File

@@ -2,6 +2,7 @@ package cache
import ( import (
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -21,6 +22,7 @@ func (this *CreatePopupAction) Init() {
func (this *CreatePopupAction) RunGet(params struct{}) { func (this *CreatePopupAction) RunGet(params struct{}) {
this.Data["types"] = serverconfigs.AllCachePolicyStorageTypes this.Data["types"] = serverconfigs.AllCachePolicyStorageTypes
this.Show() this.Show()
} }
@@ -33,9 +35,11 @@ func (this *CreatePopupAction) RunPost(params struct {
FileMemoryCapacityJSON []byte FileMemoryCapacityJSON []byte
FileOpenFileCacheMax int FileOpenFileCacheMax int
FileEnableSendfile bool FileEnableSendfile bool
FileMinFreeSizeJSON []byte
CapacityJSON []byte CapacityJSON []byte
MaxSizeJSON []byte MaxSizeJSON []byte
FetchTimeoutJSON []byte
SyncCompressionCache bool SyncCompressionCache bool
Description string Description string
@@ -48,14 +52,14 @@ func (this *CreatePopupAction) RunPost(params struct {
Require("请输入策略名称") Require("请输入策略名称")
// 校验选项 // 校验选项
var options interface{} var options any
switch params.Type { switch params.Type {
case serverconfigs.CachePolicyStorageFile: case serverconfigs.CachePolicyStorageFile:
params.Must. params.Must.
Field("fileDir", params.FileDir). Field("fileDir", params.FileDir).
Require("请输入缓存目录") Require("请输入缓存目录")
memoryCapacity := &shared.SizeCapacity{} var memoryCapacity = &shared.SizeCapacity{}
if len(params.FileMemoryCapacityJSON) > 0 { if len(params.FileMemoryCapacityJSON) > 0 {
err := json.Unmarshal(params.FileMemoryCapacityJSON, memoryCapacity) err := json.Unmarshal(params.FileMemoryCapacityJSON, memoryCapacity)
if err != nil { if err != nil {
@@ -72,6 +76,19 @@ func (this *CreatePopupAction) RunPost(params struct {
} }
} }
var minFreeSize = &shared.SizeCapacity{}
var minFreeSizeJSON = params.FileMinFreeSizeJSON
if !utils.JSONIsNull(minFreeSizeJSON) {
_, err := utils.JSONDecodeConfig(minFreeSizeJSON, minFreeSize)
if err != nil {
this.ErrorPage(err)
return
}
if minFreeSize.Count < 0 {
minFreeSize.Count = 0
}
}
options = &serverconfigs.HTTPFileCacheStorage{ options = &serverconfigs.HTTPFileCacheStorage{
Dir: params.FileDir, Dir: params.FileDir,
MemoryPolicy: &serverconfigs.HTTPCachePolicy{ MemoryPolicy: &serverconfigs.HTTPCachePolicy{
@@ -79,6 +96,7 @@ func (this *CreatePopupAction) RunPost(params struct {
}, },
OpenFileCache: openFileCacheConfig, OpenFileCache: openFileCacheConfig,
EnableSendfile: params.FileEnableSendfile, EnableSendfile: params.FileEnableSendfile,
MinFreeSize: minFreeSize,
} }
case serverconfigs.CachePolicyStorageMemory: case serverconfigs.CachePolicyStorageMemory:
options = &serverconfigs.HTTPMemoryCacheStorage{} options = &serverconfigs.HTTPMemoryCacheStorage{}
@@ -97,6 +115,7 @@ func (this *CreatePopupAction) RunPost(params struct {
Description: params.Description, Description: params.Description,
CapacityJSON: params.CapacityJSON, CapacityJSON: params.CapacityJSON,
MaxSizeJSON: params.MaxSizeJSON, MaxSizeJSON: params.MaxSizeJSON,
FetchTimeoutJSON: params.FetchTimeoutJSON,
Type: params.Type, Type: params.Type,
OptionsJSON: optionsJSON, OptionsJSON: optionsJSON,
SyncCompressionCache: params.SyncCompressionCache, SyncCompressionCache: params.SyncCompressionCache,

View File

@@ -5,7 +5,6 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"net/http" "net/http"
"reflect"
) )
type Helper struct { type Helper struct {
@@ -27,11 +26,11 @@ func (this *Helper) BeforeAction(actionPtr actions.ActionWrapper) {
cachePolicyId := action.ParamInt64("cachePolicyId") cachePolicyId := action.ParamInt64("cachePolicyId")
action.Data["cachePolicyId"] = cachePolicyId action.Data["cachePolicyId"] = cachePolicyId
parentActionValue := reflect.ValueOf(actionPtr).Elem().FieldByName("ParentAction") parentActionObj, ok := actionPtr.(interface {
if parentActionValue.IsValid() { Parent() *actionutils.ParentAction
parentAction, isOk := parentActionValue.Interface().(actionutils.ParentAction) })
if isOk { if ok {
action.Data["cachePolicyName"] = cacheutils.FindCachePolicyNameWithoutError(&parentAction, cachePolicyId) var parentAction = parentActionObj.Parent()
} action.Data["cachePolicyName"] = cacheutils.FindCachePolicyNameWithoutError(parentAction, cachePolicyId)
} }
} }

View File

@@ -26,6 +26,12 @@ func (this *PolicyAction) RunGet(params struct {
} }
this.Data["cachePolicy"] = cachePolicy this.Data["cachePolicy"] = cachePolicy
// 预热超时时间
this.Data["fetchTimeoutString"] = ""
if cachePolicy.FetchTimeout != nil && cachePolicy.FetchTimeout.Count > 0 {
this.Data["fetchTimeoutString"] = cachePolicy.FetchTimeout.Description()
}
this.Data["typeName"] = serverconfigs.FindCachePolicyStorageName(cachePolicy.Type) this.Data["typeName"] = serverconfigs.FindCachePolicyStorageName(cachePolicy.Type)
// 正在使用此策略的集群 // 正在使用此策略的集群
@@ -34,7 +40,7 @@ func (this *PolicyAction) RunGet(params struct {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
clusterMaps := []maps.Map{} var clusterMaps = []maps.Map{}
for _, cluster := range clustersResp.NodeClusters { for _, cluster := range clustersResp.NodeClusters {
clusterMaps = append(clusterMaps, maps.Map{ clusterMaps = append(clusterMaps, maps.Map{
"id": cluster.Id, "id": cluster.Id,

View File

@@ -2,6 +2,7 @@ package cache
import ( import (
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -38,6 +39,18 @@ func (this *UpdateAction) RunGet(params struct {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
// fix min free size
if cachePolicy.Type == serverconfigs.CachePolicyStorageFile && cachePolicy.Options != nil {
_, ok := cachePolicy.Options["minFreeSize"]
if !ok {
cachePolicy.Options["minFreeSize"] = &shared.SizeCapacity{
Count: 0,
Unit: shared.SizeCapacityUnitGB,
}
}
}
this.Data["cachePolicy"] = cachePolicy this.Data["cachePolicy"] = cachePolicy
// 其他选项 // 其他选项
@@ -57,10 +70,12 @@ func (this *UpdateAction) RunPost(params struct {
FileMemoryCapacityJSON []byte FileMemoryCapacityJSON []byte
FileOpenFileCacheMax int FileOpenFileCacheMax int
FileEnableSendfile bool FileEnableSendfile bool
FileMinFreeSizeJSON []byte
CapacityJSON []byte CapacityJSON []byte
MaxSizeJSON []byte MaxSizeJSON []byte
SyncCompressionCache bool SyncCompressionCache bool
FetchTimeoutJSON []byte
Description string Description string
IsOn bool IsOn bool
@@ -84,7 +99,7 @@ func (this *UpdateAction) RunPost(params struct {
Field("fileDir", params.FileDir). Field("fileDir", params.FileDir).
Require("请输入缓存目录") Require("请输入缓存目录")
memoryCapacity := &shared.SizeCapacity{} var memoryCapacity = &shared.SizeCapacity{}
if len(params.FileMemoryCapacityJSON) > 0 { if len(params.FileMemoryCapacityJSON) > 0 {
err := json.Unmarshal(params.FileMemoryCapacityJSON, memoryCapacity) err := json.Unmarshal(params.FileMemoryCapacityJSON, memoryCapacity)
if err != nil { if err != nil {
@@ -101,6 +116,19 @@ func (this *UpdateAction) RunPost(params struct {
} }
} }
var minFreeSize = &shared.SizeCapacity{}
var minFreeSizeJSON = params.FileMinFreeSizeJSON
if !utils.JSONIsNull(minFreeSizeJSON) {
_, err := utils.JSONDecodeConfig(minFreeSizeJSON, minFreeSize)
if err != nil {
this.ErrorPage(err)
return
}
if minFreeSize.Count < 0 {
minFreeSize.Count = 0
}
}
options = &serverconfigs.HTTPFileCacheStorage{ options = &serverconfigs.HTTPFileCacheStorage{
Dir: params.FileDir, Dir: params.FileDir,
MemoryPolicy: &serverconfigs.HTTPCachePolicy{ MemoryPolicy: &serverconfigs.HTTPCachePolicy{
@@ -108,6 +136,7 @@ func (this *UpdateAction) RunPost(params struct {
}, },
OpenFileCache: openFileCacheConfig, OpenFileCache: openFileCacheConfig,
EnableSendfile: params.FileEnableSendfile, EnableSendfile: params.FileEnableSendfile,
MinFreeSize: minFreeSize,
} }
case serverconfigs.CachePolicyStorageMemory: case serverconfigs.CachePolicyStorageMemory:
options = &serverconfigs.HTTPMemoryCacheStorage{} options = &serverconfigs.HTTPMemoryCacheStorage{}
@@ -122,7 +151,7 @@ func (this *UpdateAction) RunPost(params struct {
} }
// 校验缓存条件 // 校验缓存条件
refs := []*serverconfigs.HTTPCacheRef{} var refs = []*serverconfigs.HTTPCacheRef{}
if len(params.RefsJSON) > 0 { if len(params.RefsJSON) > 0 {
err = json.Unmarshal(params.RefsJSON, &refs) err = json.Unmarshal(params.RefsJSON, &refs)
if err != nil { if err != nil {
@@ -146,6 +175,7 @@ func (this *UpdateAction) RunPost(params struct {
Type: params.Type, Type: params.Type,
OptionsJSON: optionsJSON, OptionsJSON: optionsJSON,
SyncCompressionCache: params.SyncCompressionCache, SyncCompressionCache: params.SyncCompressionCache,
FetchTimeoutJSON: params.FetchTimeoutJSON,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -76,14 +76,6 @@ func (this *IndexAction) RunPost(params struct {
this.Fail("配置校验失败:" + err.Error()) this.Fail("配置校验失败:" + err.Error())
} }
// 允许不匹配的域名
allowMismatchDomains := []string{}
for _, domain := range params.AllowMismatchDomains {
if len(domain) > 0 {
allowMismatchDomains = append(allowMismatchDomains, domain)
}
}
// TCP端口范围 // TCP端口范围
if params.TcpAllPortRangeMin < 1024 { if params.TcpAllPortRangeMin < 1024 {
params.TcpAllPortRangeMin = 1024 params.TcpAllPortRangeMin = 1024

View File

@@ -5,7 +5,6 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
) )
@@ -21,7 +20,7 @@ func (this *CreateRulePopupAction) RunGet(params struct {
Type string Type string
}) { }) {
// check points // check points
checkpointList := []maps.Map{} var checkpointList = []maps.Map{}
for _, checkpoint := range firewallconfigs.AllCheckpoints { for _, checkpoint := range firewallconfigs.AllCheckpoints {
if (params.Type == "inbound" && checkpoint.IsRequest) || params.Type == "outbound" { if (params.Type == "inbound" && checkpoint.IsRequest) || params.Type == "outbound" {
checkpointList = append(checkpointList, maps.Map{ checkpointList = append(checkpointList, maps.Map{
@@ -38,15 +37,17 @@ func (this *CreateRulePopupAction) RunGet(params struct {
} }
// operators // operators
this.Data["operators"] = lists.Map(firewallconfigs.AllRuleOperators, func(k int, v interface{}) interface{} { var operatorMaps = []maps.Map{}
def := v.(*firewallconfigs.RuleOperatorDefinition) for _, operator := range firewallconfigs.AllRuleOperators {
return maps.Map{ operatorMaps = append(operatorMaps, maps.Map{
"name": def.Name, "name": operator.Name,
"code": def.Code, "code": operator.Code,
"description": def.Description, "description": operator.Description,
"case": def.CaseInsensitive, "case": operator.CaseInsensitive,
} "dataType": operator.DataType,
}) })
}
this.Data["operators"] = operatorMaps
this.Data["checkpoints"] = checkpointList this.Data["checkpoints"] = checkpointList

View File

@@ -31,7 +31,7 @@ func (this *ExportDownloadAction) RunGet(params struct {
if ok { if ok {
this.AddHeader("Content-Disposition", "attachment; filename=\"WAF-"+types.String(params.PolicyId)+".json\";") this.AddHeader("Content-Disposition", "attachment; filename=\"WAF-"+types.String(params.PolicyId)+".json\";")
this.AddHeader("Content-Length", strconv.Itoa(len(data))) this.AddHeader("Content-Length", strconv.Itoa(len(data)))
this.Write(data) _, _ = this.Write(data)
} else { } else {
this.WriteString("找不到要导出的内容") this.WriteString("找不到要导出的内容")
return return

View File

@@ -40,10 +40,13 @@ func (this *IndexAction) RunGet(params struct {
var deniedCountryIds = []int64{} var deniedCountryIds = []int64{}
var allowedCountryIds = []int64{} var allowedCountryIds = []int64{}
var countryHTML string
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil { if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
deniedCountryIds = policyConfig.Inbound.Region.DenyCountryIds deniedCountryIds = policyConfig.Inbound.Region.DenyCountryIds
allowedCountryIds = policyConfig.Inbound.Region.AllowCountryIds allowedCountryIds = policyConfig.Inbound.Region.AllowCountryIds
countryHTML = policyConfig.Inbound.Region.CountryHTML
} }
this.Data["countryHTML"] = countryHTML
countriesResp, err := this.RPC().RegionCountryRPC().FindAllRegionCountries(this.AdminContext(), &pb.FindAllRegionCountriesRequest{}) countriesResp, err := this.RPC().RegionCountryRPC().FindAllRegionCountries(this.AdminContext(), &pb.FindAllRegionCountriesRequest{})
if err != nil { if err != nil {
@@ -91,6 +94,8 @@ func (this *IndexAction) RunPost(params struct {
ExceptURLPatternsJSON []byte ExceptURLPatternsJSON []byte
OnlyURLPatternsJSON []byte OnlyURLPatternsJSON []byte
CountryHTML string
Must *actions.Must Must *actions.Must
}) { }) {
// 日志 // 日志
@@ -128,6 +133,13 @@ func (this *IndexAction) RunPost(params struct {
} }
policyConfig.Inbound.Region.CountryExceptURLPatterns = exceptURLPatterns policyConfig.Inbound.Region.CountryExceptURLPatterns = exceptURLPatterns
// 自定义提示
if len(params.CountryHTML) > 32<<10 {
this.Fail("提示内容长度不能超出32K")
return
}
policyConfig.Inbound.Region.CountryHTML = params.CountryHTML
// 限制URL // 限制URL
var onlyURLPatterns = []*shared.URLPattern{} var onlyURLPatterns = []*shared.URLPattern{}
if len(params.OnlyURLPatternsJSON) > 0 { if len(params.OnlyURLPatternsJSON) > 0 {

View File

@@ -40,10 +40,13 @@ func (this *ProvincesAction) RunGet(params struct {
var deniedProvinceIds = []int64{} var deniedProvinceIds = []int64{}
var allowedProvinceIds = []int64{} var allowedProvinceIds = []int64{}
var provinceHTML string
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil { if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
deniedProvinceIds = policyConfig.Inbound.Region.DenyProvinceIds deniedProvinceIds = policyConfig.Inbound.Region.DenyProvinceIds
allowedProvinceIds = policyConfig.Inbound.Region.AllowProvinceIds allowedProvinceIds = policyConfig.Inbound.Region.AllowProvinceIds
provinceHTML = policyConfig.Inbound.Region.ProvinceHTML
} }
this.Data["provinceHTML"] = provinceHTML
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{ provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{
RegionCountryId: regionconfigs.RegionChinaId, RegionCountryId: regionconfigs.RegionChinaId,
@@ -92,6 +95,8 @@ func (this *ProvincesAction) RunPost(params struct {
ExceptURLPatternsJSON []byte ExceptURLPatternsJSON []byte
OnlyURLPatternsJSON []byte OnlyURLPatternsJSON []byte
ProvinceHTML string
Must *actions.Must Must *actions.Must
}) { }) {
// 日志 // 日志
@@ -140,6 +145,13 @@ func (this *ProvincesAction) RunPost(params struct {
} }
policyConfig.Inbound.Region.ProvinceOnlyURLPatterns = onlyURLPatterns policyConfig.Inbound.Region.ProvinceOnlyURLPatterns = onlyURLPatterns
// 自定义提示
if len(params.ProvinceHTML) > 32<<10 {
this.Fail("提示内容长度不能超出32K")
return
}
policyConfig.Inbound.Region.ProvinceHTML = params.ProvinceHTML
inboundJSON, err := json.Marshal(policyConfig.Inbound) inboundJSON, err := json.Marshal(policyConfig.Inbound)
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -1,6 +1,7 @@
package waf package waf
import ( import (
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -29,7 +30,7 @@ func (this *PolicyAction) RunGet(params struct {
return return
} }
internalGroups := []maps.Map{} var internalGroups = []maps.Map{}
if firewallPolicy.Inbound != nil { if firewallPolicy.Inbound != nil {
for _, group := range firewallPolicy.Inbound.Groups { for _, group := range firewallPolicy.Inbound.Groups {
internalGroups = append(internalGroups, maps.Map{ internalGroups = append(internalGroups, maps.Map{
@@ -86,18 +87,22 @@ func (this *PolicyAction) RunGet(params struct {
} }
this.Data["firewallPolicy"] = maps.Map{ this.Data["firewallPolicy"] = maps.Map{
"id": firewallPolicy.Id, "id": firewallPolicy.Id,
"name": firewallPolicy.Name, "name": firewallPolicy.Name,
"isOn": firewallPolicy.IsOn, "isOn": firewallPolicy.IsOn,
"description": firewallPolicy.Description, "description": firewallPolicy.Description,
"mode": firewallPolicy.Mode, "mode": firewallPolicy.Mode,
"modeInfo": firewallconfigs.FindFirewallMode(firewallPolicy.Mode), "modeInfo": firewallconfigs.FindFirewallMode(firewallPolicy.Mode),
"groups": internalGroups, "groups": internalGroups,
"blockOptions": firewallPolicy.BlockOptions, "blockOptions": firewallPolicy.BlockOptions,
"captchaOptions": firewallPolicy.CaptchaOptions, "captchaOptions": firewallPolicy.CaptchaOptions,
"useLocalFirewall": firewallPolicy.UseLocalFirewall, "useLocalFirewall": firewallPolicy.UseLocalFirewall,
"synFlood": firewallPolicy.SYNFlood, "synFlood": firewallPolicy.SYNFlood,
"log": firewallPolicy.Log, "log": firewallPolicy.Log,
"maxRequestBodySize": firewallPolicy.MaxRequestBodySize,
"maxRequestBodySizeFormat": numberutils.FormatBytes(firewallPolicy.MaxRequestBodySize),
"denyCountryHTML": firewallPolicy.DenyCountryHTML,
"denyProvinceHTML": firewallPolicy.DenyProvinceHTML,
} }
// 正在使用此策略的集群 // 正在使用此策略的集群

View File

@@ -52,6 +52,10 @@ func (this *SortSetsAction) RunPost(params struct {
FirewallRuleGroupId: params.GroupId, FirewallRuleGroupId: params.GroupId,
FirewallRuleSetsJSON: newRefsJSON, FirewallRuleSetsJSON: newRefsJSON,
}) })
if err != nil {
this.ErrorPage(err)
return
}
this.Success() this.Success()
} }

View File

@@ -9,6 +9,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"net/http" "net/http"
) )
@@ -64,16 +65,19 @@ func (this *UpdateAction) RunGet(params struct {
} }
this.Data["firewallPolicy"] = maps.Map{ this.Data["firewallPolicy"] = maps.Map{
"id": firewallPolicy.Id, "id": firewallPolicy.Id,
"name": firewallPolicy.Name, "name": firewallPolicy.Name,
"description": firewallPolicy.Description, "description": firewallPolicy.Description,
"isOn": firewallPolicy.IsOn, "isOn": firewallPolicy.IsOn,
"mode": firewallPolicy.Mode, "mode": firewallPolicy.Mode,
"blockOptions": firewallPolicy.BlockOptions, "blockOptions": firewallPolicy.BlockOptions,
"captchaOptions": firewallPolicy.CaptchaOptions, "captchaOptions": firewallPolicy.CaptchaOptions,
"useLocalFirewall": firewallPolicy.UseLocalFirewall, "useLocalFirewall": firewallPolicy.UseLocalFirewall,
"synFloodConfig": firewallPolicy.SYNFlood, "synFloodConfig": firewallPolicy.SYNFlood,
"log": firewallPolicy.Log, "log": firewallPolicy.Log,
"maxRequestBodySize": types.String(firewallPolicy.MaxRequestBodySize),
"denyCountryHTML": firewallPolicy.DenyCountryHTML,
"denyProvinceHTML": firewallPolicy.DenyProvinceHTML,
} }
// 预置分组 // 预置分组
@@ -110,6 +114,9 @@ func (this *UpdateAction) RunPost(params struct {
UseLocalFirewall bool UseLocalFirewall bool
SynFloodJSON []byte SynFloodJSON []byte
LogJSON []byte LogJSON []byte
MaxRequestBodySize int64
DenyCountryHTML string
DenyProvinceHTML string
Must *actions.Must Must *actions.Must
}) { }) {
@@ -134,6 +141,11 @@ func (this *UpdateAction) RunPost(params struct {
this.Fail("验证码动作参数校验失败:" + err.Error()) this.Fail("验证码动作参数校验失败:" + err.Error())
} }
// 最大内容尺寸
if params.MaxRequestBodySize < 0 {
params.MaxRequestBodySize = 0
}
_, err = this.RPC().HTTPFirewallPolicyRPC().UpdateHTTPFirewallPolicy(this.AdminContext(), &pb.UpdateHTTPFirewallPolicyRequest{ _, err = this.RPC().HTTPFirewallPolicyRPC().UpdateHTTPFirewallPolicy(this.AdminContext(), &pb.UpdateHTTPFirewallPolicyRequest{
HttpFirewallPolicyId: params.FirewallPolicyId, HttpFirewallPolicyId: params.FirewallPolicyId,
IsOn: params.IsOn, IsOn: params.IsOn,
@@ -146,6 +158,9 @@ func (this *UpdateAction) RunPost(params struct {
UseLocalFirewall: params.UseLocalFirewall, UseLocalFirewall: params.UseLocalFirewall,
SynFloodJSON: params.SynFloodJSON, SynFloodJSON: params.SynFloodJSON,
LogJSON: params.LogJSON, LogJSON: params.LogJSON,
MaxRequestBodySize: params.MaxRequestBodySize,
DenyCountryHTML: params.DenyCountryHTML,
DenyProvinceHTML: params.DenyProvinceHTML,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -285,7 +285,7 @@ func (this *CreateAction) RunPost(params struct {
return return
} }
if len(dupResp.DuplicatedServerNames) > 0 { if len(dupResp.DuplicatedServerNames) > 0 {
this.Fail("域名 " + strings.Join(dupResp.DuplicatedServerNames, ", ") + " 已经被其他服务所占用,不能重复使用") this.Fail("域名 " + strings.Join(dupResp.DuplicatedServerNames, ", ") + " 已经被其他网站所占用,不能重复使用")
} }
} }
} }
@@ -347,7 +347,7 @@ func (this *CreateAction) RunPost(params struct {
var rootJSON []byte var rootJSON []byte
var err error var err error
if len(params.WebRoot) > 0 { if len(params.WebRoot) > 0 {
var rootConfig = &serverconfigs.HTTPRootConfig{} var rootConfig = serverconfigs.NewHTTPRootConfig()
rootConfig.IsOn = true rootConfig.IsOn = true
rootConfig.Dir = params.WebRoot rootConfig.Dir = params.WebRoot
rootConfig.Indexes = []string{"index.html", "index.htm"} rootConfig.Indexes = []string{"index.html", "index.htm"}

View File

@@ -1,6 +1,7 @@
package httpReverseProxy package httpReverseProxy
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
@@ -73,7 +74,7 @@ func (this *SettingAction) RunPost(params struct {
return return
} }
err = reverseProxyConfig.Init(nil) err = reverseProxyConfig.Init(context.TODO())
if err != nil { if err != nil {
this.Fail("配置校验失败:" + err.Error()) this.Fail("配置校验失败:" + err.Error())
} }

View File

@@ -2,7 +2,6 @@ package reverseProxy
import ( import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders" "github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/locations/locationutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers" "github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
"github.com/iwind/TeaGo" "github.com/iwind/TeaGo"
@@ -12,7 +11,6 @@ func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) { TeaGo.BeforeStart(func(server *TeaGo.Server) {
server. server.
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)). Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
Helper(locationutils.NewLocationHelper()).
Helper(serverutils.NewServerHelper()). Helper(serverutils.NewServerHelper()).
Data("mainTab", "setting"). Data("mainTab", "setting").
Prefix("/servers/groups/group/settings"). Prefix("/servers/groups/group/settings").

View File

@@ -1,6 +1,7 @@
package tcpReverseProxy package tcpReverseProxy
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
@@ -73,7 +74,7 @@ func (this *SettingAction) RunPost(params struct {
return return
} }
err = reverseProxyConfig.Init(nil) err = reverseProxyConfig.Init(context.TODO())
if err != nil { if err != nil {
this.Fail("配置校验失败:" + err.Error()) this.Fail("配置校验失败:" + err.Error())
} }

View File

@@ -1,6 +1,7 @@
package udpReverseProxy package udpReverseProxy
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
@@ -73,7 +74,7 @@ func (this *SettingAction) RunPost(params struct {
return return
} }
err = reverseProxyConfig.Init(nil) err = reverseProxyConfig.Init(context.TODO())
if err != nil { if err != nil {
this.Fail("配置校验失败:" + err.Error()) this.Fail("配置校验失败:" + err.Error())
} }

View File

@@ -102,6 +102,10 @@ func (this *IndexAction) RunPost(params struct {
RequestSameOrigin: websocketConfig.RequestSameOrigin, RequestSameOrigin: websocketConfig.RequestSameOrigin,
RequestOrigin: websocketConfig.RequestOrigin, RequestOrigin: websocketConfig.RequestOrigin,
}) })
if err != nil {
this.ErrorPage(err)
return
}
} }
websocketRef.WebsocketId = websocketConfig.Id websocketRef.WebsocketId = websocketConfig.Id

View File

@@ -31,7 +31,7 @@ func (this *ExportDataAction) RunGet(params struct {
defer this.CreateLogInfo(codes.IPList_LogExportIPList, params.ListId) defer this.CreateLogInfo(codes.IPList_LogExportIPList, params.ListId)
var err error var err error
var ext = "" var ext string
var jsonMaps = []maps.Map{} var jsonMaps = []maps.Map{}
var xlsxFile *xlsx.File var xlsxFile *xlsx.File
var xlsxSheet *xlsx.Sheet var xlsxSheet *xlsx.Sheet
@@ -146,5 +146,5 @@ func (this *ExportDataAction) RunGet(params struct {
this.AddHeader("Content-Disposition", "attachment; filename=\"ip-list-"+numberutils.FormatInt64(params.ListId)+ext+"\";") this.AddHeader("Content-Disposition", "attachment; filename=\"ip-list-"+numberutils.FormatInt64(params.ListId)+ext+"\";")
this.AddHeader("Content-Length", strconv.Itoa(len(data))) this.AddHeader("Content-Length", strconv.Itoa(len(data)))
this.Write(data) _, _ = this.Write(data)
} }

View File

@@ -1,4 +1,4 @@
package delete package deletes
import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" import ( "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"

View File

@@ -1,4 +1,4 @@
package delete package deletes
import ( import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders" "github.com/TeaOSLab/EdgeAdmin/internal/configloaders"

View File

@@ -2,11 +2,13 @@ package cache
import ( import (
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
@@ -51,10 +53,20 @@ func (this *IndexAction) RunGet(params struct {
return return
} }
if cachePolicy != nil { if cachePolicy != nil {
var maxBytes = &shared.SizeCapacity{}
if !utils.JSONIsNull(cachePolicy.MaxBytesJSON) {
err = json.Unmarshal(cachePolicy.MaxBytesJSON, maxBytes)
if err != nil {
this.ErrorPage(err)
return
}
}
this.Data["cachePolicy"] = maps.Map{ this.Data["cachePolicy"] = maps.Map{
"id": cachePolicy.Id, "id": cachePolicy.Id,
"name": cachePolicy.Name, "name": cachePolicy.Name,
"isOn": cachePolicy.IsOn, "isOn": cachePolicy.IsOn,
"maxBytes": maxBytes,
} }
} else { } else {
this.Data["cachePolicy"] = nil this.Data["cachePolicy"] = nil
@@ -73,7 +85,7 @@ func (this *IndexAction) RunPost(params struct {
defer this.CreateLogInfo(codes.ServerCache_LogUpdateCacheSettings, params.WebId) defer this.CreateLogInfo(codes.ServerCache_LogUpdateCacheSettings, params.WebId)
// 校验配置 // 校验配置
cacheConfig := &serverconfigs.HTTPCacheConfig{} var cacheConfig = &serverconfigs.HTTPCacheConfig{}
err := json.Unmarshal(params.CacheJSON, cacheConfig) err := json.Unmarshal(params.CacheJSON, cacheConfig)
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -1,6 +1,7 @@
package http package http
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils"
@@ -53,7 +54,7 @@ func (this *IndexAction) RunGet(params struct {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
_ = httpsConfig.Init(nil) _ = httpsConfig.Init(context.TODO())
for _, port := range httpsConfig.AllPorts() { for _, port := range httpsConfig.AllPorts() {
if lists.ContainsInt(httpPorts, port) { if lists.ContainsInt(httpPorts, port) {
conflictingPorts = append(conflictingPorts, port) conflictingPorts = append(conflictingPorts, port)

View File

@@ -1,6 +1,7 @@
package https package https
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
@@ -43,7 +44,7 @@ func (this *IndexAction) RunGet(params struct {
httpsConfig.IsOn = true httpsConfig.IsOn = true
} }
_ = httpsConfig.Init(nil) _ = httpsConfig.Init(context.TODO())
var httpsPorts = httpsConfig.AllPorts() var httpsPorts = httpsConfig.AllPorts()
// 检查http和https端口冲突 // 检查http和https端口冲突

View File

@@ -32,18 +32,18 @@ func (this *RequestCertPopupAction) RunGet(params struct {
return return
} }
serverNameConfigs := []*serverconfigs.ServerNameConfig{} var serverNameConfigs = []*serverconfigs.ServerNameConfig{}
err = json.Unmarshal(serverNamesResp.ServerNamesJSON, &serverNameConfigs) err = json.Unmarshal(serverNamesResp.ServerNamesJSON, &serverNameConfigs)
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
excludeServerNames := []string{} var excludeServerNames = []string{}
if len(params.ExcludeServerNames) > 0 { if len(params.ExcludeServerNames) > 0 {
excludeServerNames = strings.Split(params.ExcludeServerNames, ",") excludeServerNames = strings.Split(params.ExcludeServerNames, ",")
} }
serverNames := []string{} var serverNames = []string{}
for _, c := range serverNameConfigs { for _, c := range serverNameConfigs {
if len(c.SubNames) == 0 { if len(c.SubNames) == 0 {
if domainutils.ValidateDomainFormat(c.Name) && !lists.ContainsString(excludeServerNames, c.Name) { if domainutils.ValidateDomainFormat(c.Name) && !lists.ContainsString(excludeServerNames, c.Name) {
@@ -64,7 +64,12 @@ func (this *RequestCertPopupAction) RunGet(params struct {
AdminId: this.AdminId(), AdminId: this.AdminId(),
UserId: 0, UserId: 0,
}) })
userMaps := []maps.Map{} if err != nil {
this.ErrorPage(err)
return
}
var userMaps = []maps.Map{}
for _, user := range acmeUsersResp.AcmeUsers { for _, user := range acmeUsersResp.AcmeUsers {
description := user.Description description := user.Description
if len(description) > 0 { if len(description) > 0 {

View File

@@ -2,11 +2,13 @@ package cache
import ( import (
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
) )
@@ -38,10 +40,20 @@ func (this *IndexAction) RunGet(params struct {
return return
} }
if cachePolicy != nil { if cachePolicy != nil {
var maxBytes = &shared.SizeCapacity{}
if !utils.JSONIsNull(cachePolicy.MaxBytesJSON) {
err = json.Unmarshal(cachePolicy.MaxBytesJSON, maxBytes)
if err != nil {
this.ErrorPage(err)
return
}
}
this.Data["cachePolicy"] = maps.Map{ this.Data["cachePolicy"] = maps.Map{
"id": cachePolicy.Id, "id": cachePolicy.Id,
"name": cachePolicy.Name, "name": cachePolicy.Name,
"isOn": cachePolicy.IsOn, "isOn": cachePolicy.IsOn,
"maxBytes": maxBytes,
} }
} else { } else {
this.Data["cachePolicy"] = nil this.Data["cachePolicy"] = nil

View File

@@ -52,6 +52,10 @@ func (this *IndexAction) RunGet(params struct {
HttpWebId: webId, HttpWebId: webId,
HeaderJSON: refJSON, HeaderJSON: refJSON,
}) })
if err != nil {
this.ErrorPage(err)
return
}
isChanged = true isChanged = true
} }
if webConfig.ResponseHeaderPolicy == nil { if webConfig.ResponseHeaderPolicy == nil {
@@ -75,6 +79,10 @@ func (this *IndexAction) RunGet(params struct {
HttpWebId: webId, HttpWebId: webId,
HeaderJSON: refJSON, HeaderJSON: refJSON,
}) })
if err != nil {
this.ErrorPage(err)
return
}
isChanged = true isChanged = true
} }

View File

@@ -8,7 +8,6 @@ import (
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
"net/http" "net/http"
"reflect"
) )
type LocationHelper struct { type LocationHelper struct {
@@ -35,19 +34,19 @@ func (this *LocationHelper) BeforeAction(actionPtr actions.ActionWrapper) {
// 路径信息 // 路径信息
var currentLocationConfig *serverconfigs.HTTPLocationConfig = nil var currentLocationConfig *serverconfigs.HTTPLocationConfig = nil
parentActionValue := reflect.ValueOf(actionPtr).Elem().FieldByName("ParentAction") parentActionValue, ok := actionPtr.(interface {
if parentActionValue.IsValid() { Parent() *actionutils.ParentAction
parentAction, isOk := parentActionValue.Interface().(actionutils.ParentAction) })
if isOk { if ok {
var locationId = action.ParamInt64("locationId") var parentAction = parentActionValue.Parent()
locationConfig, isOk := FindLocationConfig(&parentAction, locationId) var locationId = action.ParamInt64("locationId")
if !isOk { locationConfig, isOk := FindLocationConfig(parentAction, locationId)
return if !isOk {
} return
action.Data["locationId"] = locationId
action.Data["locationConfig"] = locationConfig
currentLocationConfig = locationConfig
} }
action.Data["locationId"] = locationId
action.Data["locationConfig"] = locationConfig
currentLocationConfig = locationConfig
} }
// 左侧菜单 // 左侧菜单

View File

@@ -1,6 +1,7 @@
package locationutils package locationutils
import ( import (
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/utils"
@@ -30,7 +31,7 @@ func FindLocationConfig(parentAction *actionutils.ParentAction, locationId int64
return return
} }
err = locationConfig.Init(nil) err = locationConfig.Init(context.TODO())
if err != nil { if err != nil {
parentAction.ErrorPage(err) parentAction.ErrorPage(err)
return return

View File

@@ -1,6 +1,7 @@
package reverseProxy package reverseProxy
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
@@ -64,7 +65,7 @@ func (this *SettingAction) RunPost(params struct {
return return
} }
err = reverseProxyConfig.Init(nil) err = reverseProxyConfig.Init(context.TODO())
if err != nil { if err != nil {
this.Fail("配置校验失败:" + err.Error()) this.Fail("配置校验失败:" + err.Error())
} }

View File

@@ -94,6 +94,10 @@ func (this *IndexAction) RunPost(params struct {
RequestSameOrigin: websocketConfig.RequestSameOrigin, RequestSameOrigin: websocketConfig.RequestSameOrigin,
RequestOrigin: websocketConfig.RequestOrigin, RequestOrigin: websocketConfig.RequestOrigin,
}) })
if err != nil {
this.ErrorPage(err)
return
}
} }
websocketRef.WebsocketId = websocketConfig.Id websocketRef.WebsocketId = websocketConfig.Id

View File

@@ -31,7 +31,7 @@ func (this *AddPopupAction) RunGet(params struct {
this.Data["reverseProxyId"] = params.ReverseProxyId this.Data["reverseProxyId"] = params.ReverseProxyId
this.Data["originType"] = params.OriginType this.Data["originType"] = params.OriginType
var serverType = "" var serverType string
if params.ServerId > 0 { if params.ServerId > 0 {
serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ServerId: params.ServerId}) serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ServerId: params.ServerId})
if err != nil { if err != nil {

View File

@@ -37,7 +37,7 @@ func (this *UpdatePopupAction) RunGet(params struct {
this.Data["reverseProxyId"] = params.ReverseProxyId this.Data["reverseProxyId"] = params.ReverseProxyId
this.Data["originId"] = params.OriginId this.Data["originId"] = params.OriginId
var serverType = "" var serverType string
if params.ServerId > 0 { if params.ServerId > 0 {
serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{
ServerId: params.ServerId, ServerId: params.ServerId,

View File

@@ -105,7 +105,7 @@ func (this *IndexAction) RunPost(params struct {
return return
} }
if !urlReg.MatchString(shutdownConfig.URL) { if shutdownConfig.IsOn /** 只有启用的时候才校验 **/ && !urlReg.MatchString(shutdownConfig.URL) {
this.Fail("临时关闭页面中 '" + shutdownConfig.URL + "' 不是一个正确的URL请进行修改") this.Fail("临时关闭页面中 '" + shutdownConfig.URL + "' 不是一个正确的URL请进行修改")
return return
} }

View File

@@ -1,6 +1,7 @@
package reverseProxy package reverseProxy
import ( import (
"context"
"encoding/json" "encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes" "github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
@@ -63,7 +64,7 @@ func (this *SettingAction) RunPost(params struct {
return return
} }
err = reverseProxyConfig.Init(nil) err = reverseProxyConfig.Init(context.TODO())
if err != nil { if err != nil {
this.Fail("配置校验失败:" + err.Error()) this.Fail("配置校验失败:" + err.Error())
} }

View File

@@ -120,7 +120,7 @@ func (this *IndexAction) RunPost(params struct {
return return
} }
if len(dupResp.DuplicatedServerNames) > 0 { if len(dupResp.DuplicatedServerNames) > 0 {
this.Fail("域名 " + strings.Join(dupResp.DuplicatedServerNames, ", ") + " 已经被其他服务所占用,不能重复使用") this.Fail("域名 " + strings.Join(dupResp.DuplicatedServerNames, ", ") + " 已经被其他网站所占用,不能重复使用")
} }
} }

View File

@@ -158,11 +158,11 @@ func (this *ProvincesAction) RunPost(params struct {
} }
policyConfig.Inbound.Region.ProvinceOnlyURLPatterns = onlyURLPatterns policyConfig.Inbound.Region.ProvinceOnlyURLPatterns = onlyURLPatterns
// 自定义提示
if len(params.ProvinceHTML) > 32<<10 { if len(params.ProvinceHTML) > 32<<10 {
this.Fail("提示内容长度不能超出32K") this.Fail("提示内容长度不能超出32K")
return return
} }
policyConfig.Inbound.Region.ProvinceHTML = params.ProvinceHTML policyConfig.Inbound.Region.ProvinceHTML = params.ProvinceHTML
err = policyConfig.Init() err = policyConfig.Init()

View File

@@ -107,6 +107,10 @@ func (this *IndexAction) RunPost(params struct {
RequestSameOrigin: websocketConfig.RequestSameOrigin, RequestSameOrigin: websocketConfig.RequestSameOrigin,
RequestOrigin: websocketConfig.RequestOrigin, RequestOrigin: websocketConfig.RequestOrigin,
}) })
if err != nil {
this.ErrorPage(err)
return
}
} }
websocketRef.WebsocketId = websocketConfig.Id websocketRef.WebsocketId = websocketConfig.Id

View File

@@ -43,8 +43,8 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
action.Data["leftMenuItemIsDisabled"] = false action.Data["leftMenuItemIsDisabled"] = false
} }
action.Data["leftMenuItems"] = []maps.Map{} action.Data["leftMenuItems"] = []maps.Map{}
mainTab, _ := action.Data["mainTab"] var mainTab = action.Data["mainTab"]
secondMenuItem, _ := action.Data["secondMenuItem"] var secondMenuItem = action.Data["secondMenuItem"]
serverId := action.ParamInt64("serverId") serverId := action.ParamInt64("serverId")
if serverId == 0 { if serverId == 0 {
@@ -108,7 +108,7 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
action.Data["serverFamily"] = family action.Data["serverFamily"] = family
// TABBAR // TABBAR
selectedTabbar, _ := action.Data["mainTab"] var selectedTabbar = action.Data["mainTab"]
var tabbar = actionutils.NewTabbar() var tabbar = actionutils.NewTabbar()
tabbar.Add("", "", "/servers", "left arrow", false) tabbar.Add("", "", "/servers", "left arrow", false)
if len(serverConfig.Name) > 0 { if len(serverConfig.Name) > 0 {
@@ -227,11 +227,6 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
"isActive": secondMenuItem == "basic", "isActive": secondMenuItem == "basic",
"isOff": !serverConfig.IsOn, "isOff": !serverConfig.IsOn,
}, },
{
"name": this.Lang(actionPtr, codes.Server_MenuSettingDNS),
"url": "/servers/server/settings/dns?serverId=" + serverIdString,
"isActive": secondMenuItem == "dns",
},
} }
// HTTP // HTTP
@@ -242,6 +237,11 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
"isActive": secondMenuItem == "serverName", "isActive": secondMenuItem == "serverName",
"isOn": len(serverConfig.ServerNames) > 0, "isOn": len(serverConfig.ServerNames) > 0,
}) })
menuItems = append(menuItems, maps.Map{
"name": this.Lang(actionPtr, codes.Server_MenuSettingDNS),
"url": "/servers/server/settings/dns?serverId=" + serverIdString,
"isActive": secondMenuItem == "dns",
})
menuItems = append(menuItems, maps.Map{ menuItems = append(menuItems, maps.Map{
"name": this.Lang(actionPtr, codes.Server_MenuSettingHTTP), "name": this.Lang(actionPtr, codes.Server_MenuSettingHTTP),
"url": "/servers/server/settings/http?serverId=" + serverIdString, "url": "/servers/server/settings/http?serverId=" + serverIdString,
@@ -438,6 +438,11 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
"isOn": serverConfig.Web != nil && serverConfig.Web.MergeSlashes, "isOn": serverConfig.Web != nil && serverConfig.Web.MergeSlashes,
}) })
} else if serverConfig.IsTCPFamily() { } else if serverConfig.IsTCPFamily() {
menuItems = append(menuItems, maps.Map{
"name": this.Lang(actionPtr, codes.Server_MenuSettingDNS),
"url": "/servers/server/settings/dns?serverId=" + serverIdString,
"isActive": secondMenuItem == "dns",
})
menuItems = append(menuItems, maps.Map{ menuItems = append(menuItems, maps.Map{
"name": this.Lang(actionPtr, codes.Server_MenuSettingTCP), "name": this.Lang(actionPtr, codes.Server_MenuSettingTCP),
"url": "/servers/server/settings/tcp?serverId=" + serverIdString, "url": "/servers/server/settings/tcp?serverId=" + serverIdString,
@@ -457,6 +462,11 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
"isOn": serverConfig.ReverseProxyRef != nil && serverConfig.ReverseProxyRef.IsOn, "isOn": serverConfig.ReverseProxyRef != nil && serverConfig.ReverseProxyRef.IsOn,
}) })
} else if serverConfig.IsUnixFamily() { } else if serverConfig.IsUnixFamily() {
menuItems = append(menuItems, maps.Map{
"name": this.Lang(actionPtr, codes.Server_MenuSettingDNS),
"url": "/servers/server/settings/dns?serverId=" + serverIdString,
"isActive": secondMenuItem == "dns",
})
menuItems = append(menuItems, maps.Map{ menuItems = append(menuItems, maps.Map{
"name": this.Lang(actionPtr, codes.Server_MenuSettingUnix), "name": this.Lang(actionPtr, codes.Server_MenuSettingUnix),
"url": "/servers/server/settings/unix?serverId=" + serverIdString, "url": "/servers/server/settings/unix?serverId=" + serverIdString,
@@ -464,6 +474,11 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
"isOn": serverConfig.Unix != nil && serverConfig.Unix.IsOn && len(serverConfig.Unix.Listen) > 0, "isOn": serverConfig.Unix != nil && serverConfig.Unix.IsOn && len(serverConfig.Unix.Listen) > 0,
}) })
} else if serverConfig.IsUDPFamily() { } else if serverConfig.IsUDPFamily() {
menuItems = append(menuItems, maps.Map{
"name": this.Lang(actionPtr, codes.Server_MenuSettingDNS),
"url": "/servers/server/settings/dns?serverId=" + serverIdString,
"isActive": secondMenuItem == "dns",
})
menuItems = append(menuItems, maps.Map{ menuItems = append(menuItems, maps.Map{
"name": this.Lang(actionPtr, codes.Server_MenuSettingUDP), "name": this.Lang(actionPtr, codes.Server_MenuSettingUDP),
"url": "/servers/server/settings/udp?serverId=" + serverIdString, "url": "/servers/server/settings/udp?serverId=" + serverIdString,

View File

@@ -1,6 +1,7 @@
package api package api
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const" teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
@@ -82,7 +83,7 @@ func (this *IndexAction) RunGet(params struct{}) {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
_ = httpsConfig.Init(nil) _ = httpsConfig.Init(context.TODO())
if httpsConfig.IsOn && len(httpsConfig.Listen) > 0 { if httpsConfig.IsOn && len(httpsConfig.Listen) > 0 {
restAccessAddrs = append(restAccessAddrs, httpsConfig.FullAddresses()...) restAccessAddrs = append(restAccessAddrs, httpsConfig.FullAddresses()...)
} }

View File

@@ -59,8 +59,8 @@ func (this *LogsAction) RunGet(params struct {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
count := countResp.Count var count = countResp.Count
page := this.NewPage(count, 20) var page = this.NewPage(count, 20)
logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{ logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
NodeId: params.NodeId, NodeId: params.NodeId,
@@ -73,8 +73,12 @@ func (this *LogsAction) RunGet(params struct {
Offset: page.Offset, Offset: page.Offset,
Size: page.Size, Size: page.Size,
}) })
if err != nil {
this.ErrorPage(err)
return
}
logs := []maps.Map{} var logs = []maps.Map{}
for _, log := range logsResp.NodeLogs { for _, log := range logsResp.NodeLogs {
logs = append(logs, maps.Map{ logs = append(logs, maps.Map{
"tag": log.Tag, "tag": log.Tag,

View File

@@ -43,7 +43,7 @@ func (this *UpgradeCheckAction) RunPost(params struct {
} }
var newAPIConfig = apiConfig.Clone() var newAPIConfig = apiConfig.Clone()
newAPIConfig.RPC.Endpoints = node.AccessAddrs newAPIConfig.RPCEndpoints = node.AccessAddrs
rpcClient, err := rpc.NewRPCClient(newAPIConfig, false) rpcClient, err := rpc.NewRPCClient(newAPIConfig, false)
if err != nil { if err != nil {
this.Success() this.Success()

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