Compare commits
110 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3eaecf2ca0 | ||
|
|
07182639f3 | ||
|
|
046628eda4 | ||
|
|
8f0054b2b0 | ||
|
|
33f86a7730 | ||
|
|
2487c69136 | ||
|
|
492d24f28a | ||
|
|
9a355da75c | ||
|
|
8bae065572 | ||
|
|
efebb5a869 | ||
|
|
32cc745a85 | ||
|
|
42bfe3ffac | ||
|
|
de3a5f87cf | ||
|
|
bd1add6dea | ||
|
|
d275cc6a8b | ||
|
|
556b5bd2e9 | ||
|
|
e26cf2a19d | ||
|
|
94f5f1faf6 | ||
|
|
fb3c58bd60 | ||
|
|
e50c918e4d | ||
|
|
eb3ff3369c | ||
|
|
a07a08991f | ||
|
|
6fcc8f3401 | ||
|
|
36b38c6da4 | ||
|
|
7f2f86b7ea | ||
|
|
68514bc7ed | ||
|
|
f0dfab536c | ||
|
|
3b75c9999e | ||
|
|
084ddf4f5d | ||
|
|
6770b1fa72 | ||
|
|
118d39ed83 | ||
|
|
c24df4f876 | ||
|
|
0ae9c25d6f | ||
|
|
f99b2a9def | ||
|
|
caf9eeae2e | ||
|
|
6afecb5708 | ||
|
|
739d32e2e0 | ||
|
|
4e601298b0 | ||
|
|
74cffced3f | ||
|
|
f8cc76be35 | ||
|
|
dced2dd418 | ||
|
|
418fe97c67 | ||
|
|
1440f9b721 | ||
|
|
9504c086ea | ||
|
|
3a15d6475c | ||
|
|
18f3a00c0f | ||
|
|
5138bbe947 | ||
|
|
a309feb516 | ||
|
|
e9c172c261 | ||
|
|
6ac6842a8d | ||
|
|
71dc53ac1f | ||
|
|
4450fa1379 | ||
|
|
af0f9489c7 | ||
|
|
75b2b2bdb2 | ||
|
|
2d8224fd12 | ||
|
|
c3aea3ba72 | ||
|
|
ad1ff29ed2 | ||
|
|
9887bd99c7 | ||
|
|
9af9d0192d | ||
|
|
62933cf637 | ||
|
|
ee0837571d | ||
|
|
c2b12419c7 | ||
|
|
991aed7e8c | ||
|
|
528d5fc5a9 | ||
|
|
93569227f3 | ||
|
|
46812f9e42 | ||
|
|
61f043319d | ||
|
|
77140d01a0 | ||
|
|
beff326001 | ||
|
|
f2841b7328 | ||
|
|
2ba63b2484 | ||
|
|
f054241a73 | ||
|
|
b5007b9195 | ||
|
|
9deea64097 | ||
|
|
105777da21 | ||
|
|
e13743dfa8 | ||
|
|
35bdd3a41a | ||
|
|
464d757800 | ||
|
|
8076fcd148 | ||
|
|
53b1f07601 | ||
|
|
2626d78835 | ||
|
|
3442ddfae2 | ||
|
|
5ed863c5ec | ||
|
|
00f6387182 | ||
|
|
ca70e8f0c8 | ||
|
|
081e95b293 | ||
|
|
1282e610ba | ||
|
|
287c52cef4 | ||
|
|
dd421fec80 | ||
|
|
9b10bdaf0d | ||
|
|
4b916829a4 | ||
|
|
b33e9d9187 | ||
|
|
9d0d323b50 | ||
|
|
2872569ce0 | ||
|
|
cd2212b754 | ||
|
|
eb6525b8d9 | ||
|
|
10319a1e3d | ||
|
|
6bcfea9372 | ||
|
|
4699d1c2ee | ||
|
|
68f0b2efc3 | ||
|
|
b2af8e196b | ||
|
|
2e626a915f | ||
|
|
0127050d89 | ||
|
|
a25938022f | ||
|
|
c47b2973b0 | ||
|
|
efd3934470 | ||
|
|
fb7da4e07e | ||
|
|
d7d209f694 | ||
|
|
83a88299c2 | ||
|
|
bfae3b86cc |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -2,4 +2,7 @@
|
||||
*-plus.sh
|
||||
*_plus.html
|
||||
*_plus.js
|
||||
*@plus.js
|
||||
*@plus.js
|
||||
*_plus.less
|
||||
*_plus.css
|
||||
*_plus.css.map
|
||||
39
README.md
39
README.md
@@ -8,13 +8,42 @@
|
||||
* `简单` - 架构简单清晰,安装简单,使用简单,运维简单
|
||||
* `高扩展性` - 可以自由扩展新的节点,支持亿级数据
|
||||
|
||||
## 功能介绍
|
||||
* 多用户
|
||||
* 日志审计
|
||||
* 集群管理
|
||||
* HTTP/HTTPS/TCP/UDP等协议支持
|
||||
* WAF
|
||||
* 缓存
|
||||
* DNS自动解析
|
||||
* 多域名绑定
|
||||
* 免费证书申请
|
||||
* IP黑白名单
|
||||
* 访问日志
|
||||
* 统计
|
||||
* 内容压缩
|
||||
* Protocol Proxy协议
|
||||
* 本地静态文件
|
||||
* URL跳转
|
||||
* 路由规则
|
||||
* 重写规则
|
||||
* 访问控制
|
||||
* 字符编码
|
||||
* 自定义页面
|
||||
* 自定义HTTP Header
|
||||
* Websocket
|
||||
* WebP自动转换
|
||||
* Fastcgi
|
||||
* 请求限制
|
||||
* 流量限制
|
||||
|
||||
## 在线演示
|
||||
* [http://demo.goedge.cn](http://demo.goedge.cn)
|
||||
|
||||
## 文档
|
||||
* [新手指南](https://edge.teaos.cn/docs/QuickStart/Index.md)
|
||||
* [完整文档](https://edge.teaos.cn/docs)
|
||||
* [开发者指南](https://edge.teaos.cn/docs/Developer/Build.md)
|
||||
* [新手指南](https://goedge.cn/docs/QuickStart/Index.md)
|
||||
* [完整文档](https://goedge.cn/docs)
|
||||
* [开发者指南](https://goedge.cn/docs/Developer/Build.md)
|
||||
|
||||
## 架构
|
||||

|
||||
@@ -25,7 +54,7 @@
|
||||
* [管理平台](https://github.com/TeaOSLab/EdgeAdmin)
|
||||
|
||||
## 联系我们
|
||||
有什么问题和建议都可以加入QQ群 `659832182`。
|
||||
有什么问题和建议都可以加入QQ群 `659832182` 或者 [Telegram群](https://t.me/+5kVCMGxQhZxiODY9) 。
|
||||
|
||||
## 感谢
|
||||
* 感谢[Gitee](https://gitee.com/)提供国内源代码托管平台
|
||||
* 感谢 [Gitee](https://gitee.com/) 提供国内源代码托管平台
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
function build() {
|
||||
ROOT=$(dirname $0)
|
||||
JS_ROOT=$ROOT/../web/public/js
|
||||
NAME="edge-admin"
|
||||
DIST=$ROOT/"../dist/${NAME}"
|
||||
OS=${1}
|
||||
@@ -53,6 +54,13 @@ function build() {
|
||||
# generate files
|
||||
echo "generating files ..."
|
||||
go run -tags $TAG $ROOT/../cmd/edge-admin/main.go generate
|
||||
if [ `which uglifyjs` ]; then
|
||||
echo "compress to component.js ..."
|
||||
uglifyjs --compress --mangle -- ${JS_ROOT}/components.src.js > ${JS_ROOT}/components.js
|
||||
else
|
||||
echo "copy to component.js ..."
|
||||
cp ${JS_ROOT}/components.src.js ${JS_ROOT}/components.js
|
||||
fi
|
||||
|
||||
# create dir & copy files
|
||||
echo "copying ..."
|
||||
@@ -65,6 +73,8 @@ function build() {
|
||||
|
||||
cp -R $ROOT/../web $DIST/
|
||||
rm -f $DIST/web/tmp/*
|
||||
rm -rf $DIST/web/public/js/components
|
||||
rm -f $DIST/web/public/js/components.src.js
|
||||
cp $ROOT/configs/server.template.yaml $DIST/configs/
|
||||
|
||||
# change _plus.[ext] to .[ext]
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
JS_ROOT=../web/public/js
|
||||
|
||||
echo "generate component.src.js ..."
|
||||
go run -tags=community ../cmd/edge-admin/main.go generate
|
||||
|
||||
if [ `which uglifyjs` ]; then
|
||||
echo "compress to component.js ..."
|
||||
uglifyjs --compress --mangle -- ${JS_ROOT}/components.src.js > ${JS_ROOT}/components.js
|
||||
else
|
||||
echo "copy to component.js ..."
|
||||
cp ${JS_ROOT}/components.src.js ${JS_ROOT}/components.js
|
||||
fi
|
||||
|
||||
echo "ok"
|
||||
@@ -1,51 +1,108 @@
|
||||
package apps
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/sizes"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/files"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/utils/time"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type LogWriter struct {
|
||||
fileAppender *files.Appender
|
||||
fp *os.File
|
||||
c chan string
|
||||
}
|
||||
|
||||
func (this *LogWriter) Init() {
|
||||
// 创建目录
|
||||
dir := files.NewFile(Tea.LogDir())
|
||||
var dir = files.NewFile(Tea.LogDir())
|
||||
if !dir.Exists() {
|
||||
err := dir.Mkdir()
|
||||
if err != nil {
|
||||
log.Println("[error]" + err.Error())
|
||||
log.Println("[LOG]create log dir failed: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
logFile := files.NewFile(Tea.LogFile("run.log"))
|
||||
|
||||
// 打开要写入的日志文件
|
||||
appender, err := logFile.Appender()
|
||||
var logPath = Tea.LogFile("run.log")
|
||||
fp, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
log.Println("[LOG]open log file failed: " + err.Error())
|
||||
} else {
|
||||
this.fileAppender = appender
|
||||
this.fp = fp
|
||||
}
|
||||
|
||||
this.c = make(chan string, 1024)
|
||||
|
||||
// 异步写入文件
|
||||
var maxFileSize = 2 * sizes.G // 文件最大尺寸,超出此尺寸则清空
|
||||
if fp != nil {
|
||||
goman.New(func() {
|
||||
var totalSize int64 = 0
|
||||
stat, err := fp.Stat()
|
||||
if err == nil {
|
||||
totalSize = stat.Size()
|
||||
}
|
||||
|
||||
for message := range this.c {
|
||||
totalSize += int64(len(message))
|
||||
_, err := fp.WriteString(timeutil.Format("Y/m/d H:i:s ") + message + "\n")
|
||||
if err != nil {
|
||||
log.Println("[LOG]write log failed: " + err.Error())
|
||||
} else {
|
||||
// 如果太大则Truncate
|
||||
if totalSize > maxFileSize {
|
||||
_ = fp.Truncate(0)
|
||||
totalSize = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (this *LogWriter) Write(message string) {
|
||||
log.Println(message)
|
||||
backgroundEnv, _ := os.LookupEnv("EdgeBackground")
|
||||
if backgroundEnv != "on" {
|
||||
// 文件和行号
|
||||
var file string
|
||||
var line int
|
||||
if Tea.IsTesting() {
|
||||
var callDepth = 3
|
||||
var ok bool
|
||||
_, file, line, ok = runtime.Caller(callDepth)
|
||||
if ok {
|
||||
file = this.packagePath(file)
|
||||
}
|
||||
}
|
||||
|
||||
if this.fileAppender != nil {
|
||||
_, err := this.fileAppender.AppendString(timeutil.Format("Y/m/d H:i:s ") + message + "\n")
|
||||
if err != nil {
|
||||
log.Println("[error]" + err.Error())
|
||||
if len(file) > 0 {
|
||||
log.Println(message + " (" + file + ":" + strconv.Itoa(line) + ")")
|
||||
} else {
|
||||
log.Println(message)
|
||||
}
|
||||
}
|
||||
|
||||
this.c <- message
|
||||
}
|
||||
|
||||
func (this *LogWriter) Close() {
|
||||
if this.fileAppender != nil {
|
||||
_ = this.fileAppender.Close()
|
||||
if this.fp != nil {
|
||||
_ = this.fp.Close()
|
||||
}
|
||||
|
||||
close(this.c)
|
||||
}
|
||||
|
||||
func (this *LogWriter) packagePath(path string) string {
|
||||
var pieces = strings.Split(path, "/")
|
||||
if len(pieces) >= 2 {
|
||||
return strings.Join(pieces[len(pieces)-2:], "/")
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@ package configloaders
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
var sharedAdminUIConfig *systemconfigs.AdminUIConfig = nil
|
||||
@@ -45,6 +47,9 @@ func UpdateAdminUIConfig(uiConfig *systemconfigs.AdminUIConfig) error {
|
||||
}
|
||||
sharedAdminUIConfig = uiConfig
|
||||
|
||||
// timezone
|
||||
updateTimeZone(uiConfig)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -76,13 +81,17 @@ func loadAdminUIConfig() (*systemconfigs.AdminUIConfig, error) {
|
||||
return sharedAdminUIConfig, nil
|
||||
}
|
||||
|
||||
config := &systemconfigs.AdminUIConfig{}
|
||||
var config = &systemconfigs.AdminUIConfig{}
|
||||
err = json.Unmarshal(resp.ValueJSON, config)
|
||||
if err != nil {
|
||||
logs.Println("[UI_MANAGER]" + err.Error())
|
||||
sharedAdminUIConfig = defaultAdminUIConfig()
|
||||
return sharedAdminUIConfig, nil
|
||||
}
|
||||
|
||||
// timezone
|
||||
updateTimeZone(config)
|
||||
|
||||
sharedAdminUIConfig = config
|
||||
return sharedAdminUIConfig, nil
|
||||
}
|
||||
@@ -95,5 +104,16 @@ func defaultAdminUIConfig() *systemconfigs.AdminUIConfig {
|
||||
ShowVersion: true,
|
||||
ShowFinance: true,
|
||||
DefaultPageSize: 10,
|
||||
TimeZone: nodeconfigs.DefaultTimeZoneLocation,
|
||||
}
|
||||
}
|
||||
|
||||
// 修改时区
|
||||
func updateTimeZone(config *systemconfigs.AdminUIConfig) {
|
||||
if len(config.TimeZone) > 0 {
|
||||
location, err := time.LoadLocation(config.TimeZone)
|
||||
if err == nil && time.Local != location {
|
||||
time.Local = location
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
Version = "0.4.5"
|
||||
Version = "0.4.7.1"
|
||||
|
||||
APINodeVersion = "0.4.5"
|
||||
APINodeVersion = "0.4.7"
|
||||
|
||||
ProductName = "Edge Admin"
|
||||
ProcessName = "edge-admin"
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
func Generate() error {
|
||||
err := generateComponentsJSFile()
|
||||
if err != nil {
|
||||
return errors.New("generate 'components.js' failed: " + err.Error())
|
||||
return errors.New("generate 'components.src.js' failed: " + err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -115,7 +115,7 @@ func generateComponentsJSFile() error {
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
fp, err := os.OpenFile(filepath.Clean(Tea.PublicFile("/js/components.js")), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
|
||||
fp, err := os.OpenFile(filepath.Clean(Tea.PublicFile("/js/components.src.js")), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -13,9 +13,12 @@ import (
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
"github.com/iwind/TeaGo/sessions"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"github.com/iwind/gosock/pkg/gosock"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
@@ -58,6 +61,9 @@ func (this *AdminNode) Run() {
|
||||
return
|
||||
}
|
||||
|
||||
// 添加端口到防火墙
|
||||
this.addPortsToFirewall()
|
||||
|
||||
// 监听信号
|
||||
sigQueue := make(chan os.Signal)
|
||||
signal.Notify(sigQueue, syscall.SIGTERM, syscall.SIGINT, syscall.SIGKILL, syscall.SIGQUIT)
|
||||
@@ -201,6 +207,44 @@ https:
|
||||
return nil
|
||||
}
|
||||
|
||||
// 添加端口到防火墙
|
||||
func (this *AdminNode) addPortsToFirewall() {
|
||||
var configFile = Tea.ConfigFile("server.yaml")
|
||||
data, err := ioutil.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var config = &TeaGo.ServerConfig{}
|
||||
err = yaml.Unmarshal(data, config)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var ports = []int{}
|
||||
if config.Http.On {
|
||||
for _, listen := range config.Http.Listen {
|
||||
_, portString, _ := net.SplitHostPort(listen)
|
||||
var port = types.Int(portString)
|
||||
if port > 0 && !lists.ContainsInt(ports, port) {
|
||||
ports = append(ports, port)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if config.Https.On {
|
||||
for _, listen := range config.Https.Listen {
|
||||
_, portString, _ := net.SplitHostPort(listen)
|
||||
var port = types.Int(portString)
|
||||
if port > 0 && !lists.ContainsInt(ports, port) {
|
||||
ports = append(ports, port)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
utils.AddPortsToFirewall(ports)
|
||||
}
|
||||
|
||||
// 启动API节点
|
||||
func (this *AdminNode) startAPINode() {
|
||||
configPath := Tea.Root + "/edge-api/configs/api.yaml"
|
||||
|
||||
@@ -484,6 +484,10 @@ func (this *RPCClient) ServerStatBoardRPC() pb.ServerStatBoardServiceClient {
|
||||
return pb.NewServerStatBoardServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ServerDomainHourlyStatRPC() pb.ServerDomainHourlyStatServiceClient {
|
||||
return pb.NewServerDomainHourlyStatServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ServerStatBoardChartRPC() pb.ServerStatBoardChartServiceClient {
|
||||
return pb.NewServerStatBoardChartServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -496,6 +500,10 @@ func (this *RPCClient) UserPlanRPC() pb.UserPlanServiceClient {
|
||||
return pb.NewUserPlanServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) TrafficDailyStatRPC() pb.TrafficDailyStatServiceClient {
|
||||
return pb.NewTrafficDailyStatServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
// Context 构造Admin上下文
|
||||
func (this *RPCClient) Context(adminId int64) context.Context {
|
||||
ctx := context.Background()
|
||||
|
||||
28
internal/utils/firewall.go
Normal file
28
internal/utils/firewall.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func AddPortsToFirewall(ports []int) {
|
||||
for _, port := range ports {
|
||||
// Linux
|
||||
if runtime.GOOS == "linux" {
|
||||
// firewalld
|
||||
firewallCmd, _ := exec.LookPath("firewall-cmd")
|
||||
if len(firewallCmd) > 0 {
|
||||
err := exec.Command(firewallCmd, "--add-port="+types.String(port)+"/tcp").Run()
|
||||
if err == nil {
|
||||
logs.Println("ADMIN_NODE", "add port '"+types.String(port)+"' to firewalld")
|
||||
|
||||
_ = exec.Command(firewallCmd, "--add-port="+types.String(port)+"/tcp", "--permanent").Run()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,11 +46,31 @@ func FormatCount(count int64) string {
|
||||
if count < 1000 {
|
||||
return types.String(count)
|
||||
}
|
||||
if count < 1000 * 1000 {
|
||||
if count < 1000*1000 {
|
||||
return fmt.Sprintf("%.1fK", float32(count)/1000)
|
||||
}
|
||||
if count < 1000 * 1000 * 1000{
|
||||
if count < 1000*1000*1000 {
|
||||
return fmt.Sprintf("%.1fM", float32(count)/1000/1000)
|
||||
}
|
||||
return fmt.Sprintf("%.1fB", float32(count)/1000/1000/1000)
|
||||
}
|
||||
|
||||
func FormatFloat(f interface{}, decimal int) string {
|
||||
if f == nil {
|
||||
return ""
|
||||
}
|
||||
switch x := f.(type) {
|
||||
case float32, float64:
|
||||
var s = fmt.Sprintf("%."+types.String(decimal)+"f", x)
|
||||
return s
|
||||
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
|
||||
return types.String(x)
|
||||
case string:
|
||||
return x
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func FormatFloat2(f interface{}) string {
|
||||
return FormatFloat(f, 2)
|
||||
}
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package numberutils
|
||||
package numberutils_test
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFormatBytes(t *testing.T) {
|
||||
t.Log(FormatBytes(1))
|
||||
t.Log(FormatBytes(1000))
|
||||
t.Log(FormatBytes(1_000_000))
|
||||
t.Log(FormatBytes(1_000_000_000))
|
||||
t.Log(FormatBytes(1_000_000_000_000))
|
||||
t.Log(FormatBytes(1_000_000_000_000_000))
|
||||
t.Log(FormatBytes(1_000_000_000_000_000_000))
|
||||
t.Log(FormatBytes(9_000_000_000_000_000_000))
|
||||
t.Log(numberutils.FormatBytes(1))
|
||||
t.Log(numberutils.FormatBytes(1000))
|
||||
t.Log(numberutils.FormatBytes(1_000_000))
|
||||
t.Log(numberutils.FormatBytes(1_000_000_000))
|
||||
t.Log(numberutils.FormatBytes(1_000_000_000_000))
|
||||
t.Log(numberutils.FormatBytes(1_000_000_000_000_000))
|
||||
t.Log(numberutils.FormatBytes(1_000_000_000_000_000_000))
|
||||
t.Log(numberutils.FormatBytes(9_000_000_000_000_000_000))
|
||||
}
|
||||
|
||||
func TestFormatCount(t *testing.T) {
|
||||
t.Log(FormatCount(1))
|
||||
t.Log(FormatCount(1000))
|
||||
t.Log(FormatCount(1500))
|
||||
t.Log(FormatCount(1_000_000))
|
||||
t.Log(FormatCount(1_500_000))
|
||||
t.Log(FormatCount(1_000_000_000))
|
||||
t.Log(FormatCount(1_500_000_000))
|
||||
}
|
||||
t.Log(numberutils.FormatCount(1))
|
||||
t.Log(numberutils.FormatCount(1000))
|
||||
t.Log(numberutils.FormatCount(1500))
|
||||
t.Log(numberutils.FormatCount(1_000_000))
|
||||
t.Log(numberutils.FormatCount(1_500_000))
|
||||
t.Log(numberutils.FormatCount(1_000_000_000))
|
||||
t.Log(numberutils.FormatCount(1_500_000_000))
|
||||
}
|
||||
|
||||
func TestFormatFloat(t *testing.T) {
|
||||
t.Log(numberutils.FormatFloat(1, 2))
|
||||
t.Log(numberutils.FormatFloat(100.23456, 2))
|
||||
t.Log(numberutils.FormatFloat(100.000023, 2))
|
||||
t.Log(numberutils.FormatFloat(100.012, 2))
|
||||
}
|
||||
|
||||
10
internal/utils/sizes/sizes.go
Normal file
10
internal/utils/sizes/sizes.go
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package sizes
|
||||
|
||||
const (
|
||||
K int64 = 1024
|
||||
M = 1024 * K
|
||||
G = 1024 * M
|
||||
T = 1024 * G
|
||||
)
|
||||
17
internal/utils/sizes/sizes_test.go
Normal file
17
internal/utils/sizes/sizes_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package sizes_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/utils/sizes"
|
||||
"github.com/iwind/TeaGo/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSizes(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsTrue(sizes.K == 1024)
|
||||
a.IsTrue(sizes.M == 1024*1024)
|
||||
a.IsTrue(sizes.G == 1024*1024*1024)
|
||||
a.IsTrue(sizes.T == 1024*1024*1024*1024)
|
||||
}
|
||||
@@ -92,6 +92,7 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
"name": node.Name,
|
||||
"accessAddrs": node.AccessAddrs,
|
||||
"restAccessAddrs": restAccessAddrs,
|
||||
"isPrimary": node.IsPrimary,
|
||||
"status": maps.Map{
|
||||
"isActive": status.IsActive,
|
||||
"updatedAt": status.UpdatedAt,
|
||||
|
||||
@@ -129,6 +129,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"restAccessAddrs": restAccessAddrs,
|
||||
"hasHTTPS": hasHTTPS,
|
||||
"certs": certs,
|
||||
"isPrimary": node.IsPrimary,
|
||||
}
|
||||
|
||||
this.Show()
|
||||
|
||||
@@ -29,13 +29,13 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.ApiNode
|
||||
var node = nodeResp.ApiNode
|
||||
if node == nil {
|
||||
this.WriteString("要操作的节点不存在")
|
||||
return
|
||||
}
|
||||
|
||||
httpConfig := &serverconfigs.HTTPProtocolConfig{}
|
||||
var httpConfig = &serverconfigs.HTTPProtocolConfig{}
|
||||
if len(node.HttpJSON) > 0 {
|
||||
err = json.Unmarshal(node.HttpJSON, httpConfig)
|
||||
if err != nil {
|
||||
@@ -43,7 +43,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
}
|
||||
httpsConfig := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var httpsConfig = &serverconfigs.HTTPSProtocolConfig{}
|
||||
if len(node.HttpsJSON) > 0 {
|
||||
err = json.Unmarshal(node.HttpsJSON, httpsConfig)
|
||||
if err != nil {
|
||||
@@ -53,11 +53,11 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 监听地址
|
||||
listens := []*serverconfigs.NetworkAddressConfig{}
|
||||
var listens = []*serverconfigs.NetworkAddressConfig{}
|
||||
listens = append(listens, httpConfig.Listen...)
|
||||
listens = append(listens, httpsConfig.Listen...)
|
||||
|
||||
restHTTPConfig := &serverconfigs.HTTPProtocolConfig{}
|
||||
var restHTTPConfig = &serverconfigs.HTTPProtocolConfig{}
|
||||
if len(node.RestHTTPJSON) > 0 {
|
||||
err = json.Unmarshal(node.RestHTTPJSON, restHTTPConfig)
|
||||
if err != nil {
|
||||
@@ -65,7 +65,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
}
|
||||
restHTTPSConfig := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var restHTTPSConfig = &serverconfigs.HTTPSProtocolConfig{}
|
||||
if len(node.RestHTTPSJSON) > 0 {
|
||||
err = json.Unmarshal(node.RestHTTPSJSON, restHTTPSConfig)
|
||||
if err != nil {
|
||||
@@ -75,20 +75,20 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 监听地址
|
||||
restListens := []*serverconfigs.NetworkAddressConfig{}
|
||||
var restListens = []*serverconfigs.NetworkAddressConfig{}
|
||||
restListens = append(restListens, restHTTPConfig.Listen...)
|
||||
restListens = append(restListens, restHTTPSConfig.Listen...)
|
||||
|
||||
// 证书信息
|
||||
certs := []*sslconfigs.SSLCertConfig{}
|
||||
sslPolicyId := int64(0)
|
||||
var certs = []*sslconfigs.SSLCertConfig{}
|
||||
var sslPolicyId = int64(0)
|
||||
if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 {
|
||||
sslPolicyConfigResp, err := this.RPC().SSLPolicyRPC().FindEnabledSSLPolicyConfig(this.AdminContext(), &pb.FindEnabledSSLPolicyConfigRequest{SslPolicyId: httpsConfig.SSLPolicyRef.SSLPolicyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
sslPolicyConfigJSON := sslPolicyConfigResp.SslPolicyJSON
|
||||
var sslPolicyConfigJSON = sslPolicyConfigResp.SslPolicyJSON
|
||||
if len(sslPolicyConfigJSON) > 0 {
|
||||
sslPolicyId = httpsConfig.SSLPolicyRef.SSLPolicyId
|
||||
|
||||
@@ -102,7 +102,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
accessAddrs := []*serverconfigs.NetworkAddressConfig{}
|
||||
var accessAddrs = []*serverconfigs.NetworkAddressConfig{}
|
||||
if len(node.AccessAddrsJSON) > 0 {
|
||||
err = json.Unmarshal(node.AccessAddrsJSON, &accessAddrs)
|
||||
if err != nil {
|
||||
@@ -122,6 +122,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
"certs": certs,
|
||||
"sslPolicyId": sslPolicyId,
|
||||
"accessAddrs": accessAddrs,
|
||||
"isPrimary": node.IsPrimary,
|
||||
}
|
||||
|
||||
this.Show()
|
||||
@@ -139,6 +140,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
AccessAddrsJSON []byte
|
||||
Description string
|
||||
IsOn bool
|
||||
IsPrimary bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -146,11 +148,11 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
Field("name", params.Name).
|
||||
Require("请输入API节点名称")
|
||||
|
||||
httpConfig := &serverconfigs.HTTPProtocolConfig{}
|
||||
httpsConfig := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var httpConfig = &serverconfigs.HTTPProtocolConfig{}
|
||||
var httpsConfig = &serverconfigs.HTTPSProtocolConfig{}
|
||||
|
||||
// 监听地址
|
||||
listens := []*serverconfigs.NetworkAddressConfig{}
|
||||
var listens = []*serverconfigs.NetworkAddressConfig{}
|
||||
err := json.Unmarshal(params.ListensJSON, &listens)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -170,8 +172,8 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// Rest监听地址
|
||||
restHTTPConfig := &serverconfigs.HTTPProtocolConfig{}
|
||||
restHTTPSConfig := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var restHTTPConfig = &serverconfigs.HTTPProtocolConfig{}
|
||||
var restHTTPSConfig = &serverconfigs.HTTPSProtocolConfig{}
|
||||
if params.RestIsOn {
|
||||
restListens := []*serverconfigs.NetworkAddressConfig{}
|
||||
err = json.Unmarshal(params.RestListensJSON, &restListens)
|
||||
@@ -191,7 +193,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 证书
|
||||
certIds := []int64{}
|
||||
var certIds = []int64{}
|
||||
if len(params.CertIdsJSON) > 0 {
|
||||
err = json.Unmarshal(params.CertIdsJSON, &certIds)
|
||||
if err != nil {
|
||||
@@ -203,7 +205,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
this.Fail("请添加至少一个证书")
|
||||
}
|
||||
|
||||
certRefs := []*sslconfigs.SSLCertRef{}
|
||||
var certRefs = []*sslconfigs.SSLCertRef{}
|
||||
for _, certId := range certIds {
|
||||
certRefs = append(certRefs, &sslconfigs.SSLCertRef{
|
||||
IsOn: true,
|
||||
@@ -217,7 +219,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 创建策略
|
||||
sslPolicyId := params.SslPolicyId
|
||||
var sslPolicyId = params.SslPolicyId
|
||||
if sslPolicyId == 0 {
|
||||
if len(certIds) > 0 {
|
||||
sslPolicyCreateResp, err := this.RPC().SSLPolicyRPC().CreateSSLPolicy(this.AdminContext(), &pb.CreateSSLPolicyRequest{
|
||||
@@ -249,7 +251,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 访问地址
|
||||
accessAddrs := []*serverconfigs.NetworkAddressConfig{}
|
||||
var accessAddrs = []*serverconfigs.NetworkAddressConfig{}
|
||||
err = json.Unmarshal(params.AccessAddrsJSON, &accessAddrs)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -291,6 +293,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
RestHTTPSJSON: restHTTPSJSON,
|
||||
AccessAddrsJSON: params.AccessAddrsJSON,
|
||||
IsOn: params.IsOn,
|
||||
IsPrimary: params.IsPrimary,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -54,6 +54,7 @@ func init() {
|
||||
GetPost("/settings/dns", new(dns.IndexAction)).
|
||||
GetPost("/settings/system", new(system.IndexAction)).
|
||||
GetPost("/settings/ssh", new(ssh.IndexAction)).
|
||||
GetPost("/settings/ssh/test", new(ssh.TestAction)).
|
||||
GetPost("/settings/thresholds", new(thresholds.IndexAction)).
|
||||
|
||||
// 分组相关
|
||||
|
||||
@@ -33,7 +33,7 @@ func (this *DetailAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.Node
|
||||
var node = nodeResp.Node
|
||||
if node == nil {
|
||||
this.WriteString("找不到要操作的节点")
|
||||
return
|
||||
@@ -197,7 +197,7 @@ func (this *DetailAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 运行状态
|
||||
status := &nodeconfigs.NodeStatus{}
|
||||
var status = &nodeconfigs.NodeStatus{}
|
||||
if len(node.StatusJSON) > 0 {
|
||||
err = json.Unmarshal(node.StatusJSON, &status)
|
||||
if err != nil {
|
||||
@@ -285,6 +285,8 @@ func (this *DetailAction) RunGet(params struct {
|
||||
"isOn": node.IsOn,
|
||||
"records": recordMaps,
|
||||
"routes": routeMaps,
|
||||
"level": node.Level,
|
||||
"levelInfo": nodeconfigs.FindNodeLevel(int(node.Level)),
|
||||
|
||||
"status": maps.Map{
|
||||
"isActive": status.IsActive,
|
||||
@@ -298,9 +300,9 @@ func (this *DetailAction) RunGet(params struct {
|
||||
"buildVersion": status.BuildVersion,
|
||||
"cpuPhysicalCount": status.CPUPhysicalCount,
|
||||
"cpuLogicalCount": status.CPULogicalCount,
|
||||
"load1m": fmt.Sprintf("%.2f", status.Load1m),
|
||||
"load5m": fmt.Sprintf("%.2f", status.Load5m),
|
||||
"load15m": fmt.Sprintf("%.2f", status.Load15m),
|
||||
"load1m": numberutils.FormatFloat2(status.Load1m),
|
||||
"load5m": numberutils.FormatFloat2(status.Load5m),
|
||||
"load15m": numberutils.FormatFloat2(status.Load15m),
|
||||
"cacheTotalDiskSize": numberutils.FormatBytes(status.CacheTotalDiskSize),
|
||||
"cacheTotalMemorySize": numberutils.FormatBytes(status.CacheTotalMemorySize),
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/nodelogutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
@@ -43,7 +44,7 @@ func (this *LogsAction) RunGet(params struct {
|
||||
this.Data["tag"] = params.Tag
|
||||
|
||||
countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
|
||||
Role: "node",
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
NodeId: params.NodeId,
|
||||
DayFrom: params.DayFrom,
|
||||
DayTo: params.DayTo,
|
||||
|
||||
@@ -38,6 +38,7 @@ func InitNodeInfo(parentAction *actionutils.ParentAction, nodeId int64) (*pb.Nod
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
"group": groupMap,
|
||||
"level": node.Level,
|
||||
}
|
||||
var clusterId int64 = 0
|
||||
if node.NodeCluster != nil {
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"net"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -33,7 +35,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
// 登录信息
|
||||
var loginMap maps.Map = nil
|
||||
if node.NodeLogin != nil {
|
||||
loginParams := maps.Map{}
|
||||
var loginParams = maps.Map{}
|
||||
if len(node.NodeLogin.Params) > 0 {
|
||||
err = json.Unmarshal(node.NodeLogin.Params, &loginParams)
|
||||
if err != nil {
|
||||
@@ -42,7 +44,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
grantMap := maps.Map{}
|
||||
var grantMap = maps.Map{}
|
||||
grantId := loginParams.GetInt64("grantId")
|
||||
if grantId > 0 {
|
||||
grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId})
|
||||
@@ -70,6 +72,45 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
if loginMap == nil {
|
||||
addressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{NodeId: node.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if len(addressesResp.NodeIPAddresses) > 0 {
|
||||
loginMap = maps.Map{
|
||||
"id": 0,
|
||||
"name": "",
|
||||
"type": "ssh",
|
||||
"params": maps.Map{
|
||||
"host": addressesResp.NodeIPAddresses[0].Ip,
|
||||
"port": 22,
|
||||
"grantId": 0,
|
||||
},
|
||||
"grant": nil,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var loginParams = loginMap.GetMap("params")
|
||||
if len(loginParams.GetString("host")) == 0 {
|
||||
addressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{NodeId: node.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if len(addressesResp.NodeIPAddresses) > 0 {
|
||||
loginParams["host"] = addressesResp.NodeIPAddresses[0].Ip
|
||||
}
|
||||
}
|
||||
|
||||
if loginParams.GetInt("port") == 0 {
|
||||
loginParams["port"] = 22
|
||||
}
|
||||
|
||||
loginMap["params"] = loginParams
|
||||
}
|
||||
|
||||
var nodeMap = this.Data["node"].(maps.Map)
|
||||
nodeMap["login"] = loginMap
|
||||
|
||||
@@ -89,8 +130,13 @@ func (this *IndexAction) RunPost(params struct {
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改节点 %d SSH登录信息", params.NodeId)
|
||||
|
||||
// 检查IP地址
|
||||
if regexp.MustCompile(`^\d+\.\d+\.\d+\.\d+$`).MatchString(params.SshHost) && net.ParseIP(params.SshHost) == nil {
|
||||
this.Fail("SSH主机地址 '" + params.SshHost + "' IP格式错误")
|
||||
}
|
||||
|
||||
// TODO 检查登录授权
|
||||
loginInfo := &pb.NodeLogin{
|
||||
var loginInfo = &pb.NodeLogin{
|
||||
Id: params.LoginId,
|
||||
Name: "SSH",
|
||||
Type: "ssh",
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type TestAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *TestAction) RunPost(params struct {
|
||||
GrantId int64
|
||||
Host string
|
||||
Port int32
|
||||
}) {
|
||||
resp, err := this.RPC().NodeGrantRPC().TestNodeGrant(this.AdminContext(), &pb.TestNodeGrantRequest{
|
||||
NodeGrantId: params.GrantId,
|
||||
Host: params.Host,
|
||||
Port: params.Port,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["isOk"] = resp.IsOk
|
||||
this.Data["error"] = resp.Error
|
||||
this.Success()
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
type UpdateAction struct {
|
||||
@@ -37,7 +38,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.Node
|
||||
var node = nodeResp.Node
|
||||
if node == nil {
|
||||
this.WriteString("找不到要操作的节点")
|
||||
return
|
||||
@@ -97,7 +98,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
var m = maps.Map{
|
||||
var nodeMap = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"ipAddresses": ipAddressMaps,
|
||||
@@ -105,15 +106,16 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
"isOn": node.IsOn,
|
||||
"group": groupMap,
|
||||
"region": regionMap,
|
||||
"level": node.Level,
|
||||
}
|
||||
|
||||
if node.NodeCluster != nil {
|
||||
m["primaryCluster"] = maps.Map{
|
||||
nodeMap["primaryCluster"] = maps.Map{
|
||||
"id": node.NodeCluster.Id,
|
||||
"name": node.NodeCluster.Name,
|
||||
}
|
||||
} else {
|
||||
m["primaryCluster"] = nil
|
||||
nodeMap["primaryCluster"] = nil
|
||||
}
|
||||
|
||||
if len(node.SecondaryNodeClusters) > 0 {
|
||||
@@ -124,12 +126,14 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
"name": cluster.Name,
|
||||
})
|
||||
}
|
||||
m["secondaryClusters"] = secondaryClusterMaps
|
||||
nodeMap["secondaryClusters"] = secondaryClusterMaps
|
||||
} else {
|
||||
m["secondaryClusters"] = []interface{}{}
|
||||
nodeMap["secondaryClusters"] = []interface{}{}
|
||||
}
|
||||
|
||||
this.Data["node"] = m
|
||||
this.Data["node"] = nodeMap
|
||||
|
||||
this.Data["canUpdateLevel"] = this.CanUpdateLevel(2)
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -144,11 +148,12 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
PrimaryClusterId int64
|
||||
SecondaryClusterIds []byte
|
||||
IsOn bool
|
||||
Level int32
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
// 创建日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改节点 %d", params.NodeId)
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改节点 %d 基本信息", params.NodeId)
|
||||
|
||||
if params.NodeId <= 0 {
|
||||
this.Fail("要操作的节点不存在")
|
||||
@@ -186,6 +191,10 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 保存
|
||||
if !this.CanUpdateLevel(params.Level) {
|
||||
this.Fail("没有权限修改节点级别:" + types.String(params.Level))
|
||||
}
|
||||
|
||||
_, err := this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{
|
||||
NodeId: params.NodeId,
|
||||
NodeGroupId: params.GroupId,
|
||||
@@ -194,6 +203,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
NodeClusterId: params.PrimaryClusterId,
|
||||
SecondaryNodeClusterIds: secondaryClusterIds,
|
||||
IsOn: params.IsOn,
|
||||
Level: params.Level,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package node
|
||||
|
||||
func (this *UpdateAction) CanUpdateLevel(level int32) bool {
|
||||
return level <= 1
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package cluster
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -29,17 +31,21 @@ func (this *NodesAction) RunGet(params struct {
|
||||
InstalledState int
|
||||
ActiveState int
|
||||
Keyword string
|
||||
Level int32
|
||||
|
||||
CpuOrder string
|
||||
MemoryOrder string
|
||||
TrafficInOrder string
|
||||
TrafficOutOrder string
|
||||
LoadOrder string
|
||||
}) {
|
||||
this.Data["groupId"] = params.GroupId
|
||||
this.Data["regionId"] = params.RegionId
|
||||
this.Data["installState"] = params.InstalledState
|
||||
this.Data["activeState"] = params.ActiveState
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["level"] = params.Level
|
||||
this.Data["hasOrder"] = len(params.CpuOrder) > 0 || len(params.MemoryOrder) > 0 || len(params.TrafficInOrder) > 0 || len(params.TrafficOutOrder) > 0 || len(params.LoadOrder) > 0
|
||||
|
||||
// 集群是否已经设置了线路
|
||||
clusterDNSResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: params.ClusterId})
|
||||
@@ -63,6 +69,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeGroupId: params.GroupId,
|
||||
NodeRegionId: params.RegionId,
|
||||
Level: params.Level,
|
||||
InstallState: types.Int32(params.InstalledState),
|
||||
ActiveState: types.Int32(params.ActiveState),
|
||||
Keyword: params.Keyword,
|
||||
@@ -72,7 +79,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
page := this.NewPage(countResp.Count)
|
||||
var page = this.NewPage(countResp.Count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
var req = &pb.ListEnabledNodesMatchRequest{
|
||||
@@ -81,6 +88,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeGroupId: params.GroupId,
|
||||
NodeRegionId: params.RegionId,
|
||||
Level: params.Level,
|
||||
InstallState: types.Int32(params.InstalledState),
|
||||
ActiveState: types.Int32(params.ActiveState),
|
||||
Keyword: params.Keyword,
|
||||
@@ -101,13 +109,17 @@ func (this *NodesAction) RunGet(params struct {
|
||||
req.TrafficOutAsc = true
|
||||
} else if params.TrafficOutOrder == "desc" {
|
||||
req.TrafficOutDesc = true
|
||||
} else if params.LoadOrder == "asc" {
|
||||
req.LoadAsc = true
|
||||
} else if params.LoadOrder == "desc" {
|
||||
req.LoadDesc = true
|
||||
}
|
||||
nodesResp, err := this.RPC().NodeRPC().ListEnabledNodesMatch(this.AdminContext(), req)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
nodeMaps := []maps.Map{}
|
||||
var nodeMaps = []maps.Map{}
|
||||
for _, node := range nodesResp.Nodes {
|
||||
// 状态
|
||||
isSynced := false
|
||||
@@ -199,6 +211,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
||||
"trafficInBytes": status.TrafficInBytes,
|
||||
"trafficOutBytes": status.TrafficOutBytes,
|
||||
"load1m": numberutils.FormatFloat2(status.Load1m),
|
||||
},
|
||||
"cluster": maps.Map{
|
||||
"id": node.NodeCluster.Id,
|
||||
@@ -210,12 +223,13 @@ func (this *NodesAction) RunGet(params struct {
|
||||
"group": groupMap,
|
||||
"region": regionMap,
|
||||
"dnsRouteNames": dnsRouteNames,
|
||||
"level": node.Level,
|
||||
})
|
||||
}
|
||||
this.Data["nodes"] = nodeMaps
|
||||
|
||||
// 所有分组
|
||||
groupMaps := []maps.Map{}
|
||||
var groupMaps = []maps.Map{}
|
||||
groupsResp, err := this.RPC().NodeGroupRPC().FindAllEnabledNodeGroupsWithNodeClusterId(this.AdminContext(), &pb.FindAllEnabledNodeGroupsWithNodeClusterIdRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
})
|
||||
@@ -224,12 +238,12 @@ func (this *NodesAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
for _, group := range groupsResp.NodeGroups {
|
||||
countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesWithNodeGroupId(this.AdminContext(), &pb.CountAllEnabledNodesWithNodeGroupIdRequest{NodeGroupId: group.Id})
|
||||
countNodesInGroupResp, err := this.RPC().NodeRPC().CountAllEnabledNodesWithNodeGroupId(this.AdminContext(), &pb.CountAllEnabledNodesWithNodeGroupIdRequest{NodeGroupId: group.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
countNodes := countResp.Count
|
||||
countNodes := countNodesInGroupResp.Count
|
||||
groupName := group.Name
|
||||
if countNodes > 0 {
|
||||
groupName += "(" + strconv.FormatInt(countNodes, 10) + ")"
|
||||
@@ -248,7 +262,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
regionMaps := []maps.Map{}
|
||||
var regionMaps = []maps.Map{}
|
||||
for _, region := range regionsResp.NodeRegions {
|
||||
regionMaps = append(regionMaps, maps.Map{
|
||||
"id": region.Id,
|
||||
@@ -257,6 +271,12 @@ func (this *NodesAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["regions"] = regionMaps
|
||||
|
||||
// 级别
|
||||
this.Data["levels"] = []maps.Map{}
|
||||
if teaconst.IsPlus {
|
||||
this.Data["levels"] = nodeconfigs.FindAllNodeLevels()
|
||||
}
|
||||
|
||||
// 记录最近访问
|
||||
_, err = this.RPC().LatestItemRPC().IncreaseLatestItem(this.AdminContext(), &pb.IncreaseLatestItemRequest{
|
||||
ItemType: "cluster",
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
)
|
||||
|
||||
type RandomNameAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *RandomNameAction) RunPost(params struct{}) {
|
||||
this.Data["name"] = "cluster" + rands.HexString(8)
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/thresholds"
|
||||
"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/webp"
|
||||
clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
@@ -38,6 +39,7 @@ func init() {
|
||||
// DNS
|
||||
Prefix("/clusters/cluster/settings/dns").
|
||||
GetPost("", new(dns.IndexAction)).
|
||||
Post("/randomName", new(dns.RandomNameAction)).
|
||||
|
||||
// 消息
|
||||
Prefix("/clusters/cluster/settings/message").
|
||||
@@ -74,6 +76,9 @@ func init() {
|
||||
GetPost("/createPopup", new(metrics.CreatePopupAction)).
|
||||
Post("/delete", new(metrics.DeleteAction)).
|
||||
|
||||
// WebP
|
||||
Prefix("/clusters/cluster/settings/webp").
|
||||
GetPost("", new(webp.IndexAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package webp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "setting", "")
|
||||
this.SecondMenu("webp")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
}) {
|
||||
webpResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterWebPPolicy(this.AdminContext(), &pb.FindEnabledNodeClusterWebPPolicyRequest{NodeClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if len(webpResp.WebpPolicyJSON) == 0 {
|
||||
this.Data["webpPolicy"] = nodeconfigs.DefaultWebPImagePolicy
|
||||
} else {
|
||||
var config = &nodeconfigs.WebPImagePolicy{}
|
||||
err = json.Unmarshal(webpResp.WebpPolicyJSON, config)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["webpPolicy"] = config
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
IsOn bool
|
||||
RequireCache bool
|
||||
MinLengthJSON []byte
|
||||
MaxLengthJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改集群 %d 的WebP设置", params.ClusterId)
|
||||
|
||||
var config = &nodeconfigs.WebPImagePolicy{
|
||||
IsOn: params.IsOn,
|
||||
RequireCache: params.RequireCache,
|
||||
}
|
||||
|
||||
if len(params.MinLengthJSON) > 0 {
|
||||
var minLength = &shared.SizeCapacity{}
|
||||
err := json.Unmarshal(params.MinLengthJSON, minLength)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
config.MinLength = minLength
|
||||
}
|
||||
|
||||
if len(params.MaxLengthJSON) > 0 {
|
||||
var maxLength = &shared.SizeCapacity{}
|
||||
err := json.Unmarshal(params.MaxLengthJSON, maxLength)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
config.MaxLength = maxLength
|
||||
}
|
||||
|
||||
configJSON, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = this.RPC().NodeClusterRPC().UpdateNodeClusterWebPPolicy(this.AdminContext(), &pb.UpdateNodeClusterWebPPolicyRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
WebpPolicyJSON: configJSON,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"net"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type UpdateNodeSSHAction struct {
|
||||
@@ -31,7 +33,7 @@ func (this *UpdateNodeSSHAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
node := nodeResp.Node
|
||||
var node = nodeResp.Node
|
||||
this.Data["node"] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
@@ -43,7 +45,7 @@ func (this *UpdateNodeSSHAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// SSH
|
||||
loginParams := maps.Map{
|
||||
var loginParams = maps.Map{
|
||||
"host": "",
|
||||
"port": "",
|
||||
"grantId": 0,
|
||||
@@ -59,10 +61,22 @@ func (this *UpdateNodeSSHAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(loginParams.GetString("host")) == 0 {
|
||||
addressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{NodeId: node.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if len(addressesResp.NodeIPAddresses) > 0 {
|
||||
loginParams["host"] = addressesResp.NodeIPAddresses[0].Ip
|
||||
}
|
||||
}
|
||||
|
||||
this.Data["params"] = loginParams
|
||||
|
||||
// 认证信息
|
||||
grantId := loginParams.GetInt64("grantId")
|
||||
var grantId = loginParams.GetInt64("grantId")
|
||||
grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -101,7 +115,12 @@ func (this *UpdateNodeSSHAction) RunPost(params struct {
|
||||
this.Fail("需要选择或填写至少一个认证信息")
|
||||
}
|
||||
|
||||
login := &pb.NodeLogin{
|
||||
// 检查IP地址
|
||||
if regexp.MustCompile(`^\d+\.\d+\.\d+\.\d+$`).MatchString(params.SshHost) && net.ParseIP(params.SshHost) == nil {
|
||||
this.Fail("SSH主机地址 '" + params.SshHost + "' IP格式错误")
|
||||
}
|
||||
|
||||
var login = &pb.NodeLogin{
|
||||
Id: params.LoginId,
|
||||
Name: "SSH",
|
||||
Type: "ssh",
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// 单个集群的帮助
|
||||
// ClusterHelper 单个集群的帮助
|
||||
type ClusterHelper struct {
|
||||
}
|
||||
|
||||
@@ -65,18 +65,23 @@ func (this *ClusterHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNext
|
||||
tabbar.Add("集群节点", "", "/clusters/cluster/nodes?clusterId="+clusterIdString, "server", selectedTabbar == "node")
|
||||
tabbar.Add("集群设置", "", "/clusters/cluster/settings?clusterId="+clusterIdString, "setting", selectedTabbar == "setting")
|
||||
tabbar.Add("删除集群", "", "/clusters/cluster/delete?clusterId="+clusterIdString, "trash", selectedTabbar == "delete")
|
||||
|
||||
{
|
||||
m := tabbar.Add("当前集群:"+cluster.Name, "", "/clusters/cluster?clusterId="+clusterIdString, "", false)
|
||||
m["right"] = true
|
||||
}
|
||||
actionutils.SetTabbar(action, tabbar)
|
||||
|
||||
// 左侧菜单
|
||||
secondMenuItem := action.Data.GetString("secondMenuItem")
|
||||
switch selectedTabbar {
|
||||
case "setting":
|
||||
action.Data["leftMenuItems"] = this.createSettingMenu(cluster, clusterInfo, secondMenuItem)
|
||||
var menuItems = this.createSettingMenu(cluster, clusterInfo, secondMenuItem)
|
||||
action.Data["leftMenuItems"] = menuItems
|
||||
|
||||
// 当前菜单
|
||||
action.Data["leftMenuActiveItem"] = nil
|
||||
for _, item := range menuItems {
|
||||
if item.GetBool("isActive") {
|
||||
action.Data["leftMenuActiveItem"] = item
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +95,7 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
||||
"name": "基础设置",
|
||||
"url": "/clusters/cluster/settings?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "basic",
|
||||
"isOn": true,
|
||||
})
|
||||
items = append(items, maps.Map{
|
||||
"name": "缓存设置",
|
||||
@@ -124,6 +130,12 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
||||
"isActive": selectedItem == "dns",
|
||||
"isOn": cluster.DnsDomainId > 0 || len(cluster.DnsName) > 0,
|
||||
})
|
||||
items = append(items, maps.Map{
|
||||
"name": "WebP",
|
||||
"url": "/clusters/cluster/settings/webp?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "webp",
|
||||
"isOn": info != nil && info.WebpIsOn,
|
||||
})
|
||||
items = append(items, maps.Map{
|
||||
"name": "统计指标",
|
||||
"url": "/clusters/cluster/settings/metrics?clusterId=" + clusterId,
|
||||
@@ -157,6 +169,7 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
||||
"name": "系统服务",
|
||||
"url": "/clusters/cluster/settings/services?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "service",
|
||||
"isOn": info != nil && info.HasSystemServices,
|
||||
})
|
||||
{
|
||||
items = append(items, maps.Map{
|
||||
|
||||
@@ -27,7 +27,7 @@ func (this *CreateAction) RunGet(params struct{}) {
|
||||
}
|
||||
this.Data["hasDomains"] = hasDomainsResp.Exist
|
||||
|
||||
// 集群总数
|
||||
// 菜单:集群总数
|
||||
totalResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -35,6 +35,14 @@ func (this *CreateAction) RunGet(params struct{}) {
|
||||
}
|
||||
this.Data["totalNodeClusters"] = totalResp.Count
|
||||
|
||||
// 菜单:节点总数
|
||||
totalNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodes(this.AdminContext(), &pb.CountAllEnabledNodesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["totalNodes"] = totalNodesResp.Count
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package clusters
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -24,18 +21,26 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Keyword string
|
||||
SearchType string
|
||||
}) {
|
||||
isSearching := len(params.Keyword) > 0
|
||||
var isSearching = len(params.Keyword) > 0
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["searchType"] = params.SearchType
|
||||
this.Data["isSearching"] = isSearching
|
||||
|
||||
// 集群总数
|
||||
totalResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{})
|
||||
totalClustersResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["totalNodeClusters"] = totalResp.Count
|
||||
this.Data["totalNodeClusters"] = totalClustersResp.Count
|
||||
|
||||
// 节点总数
|
||||
totalNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodes(this.AdminContext(), &pb.CountAllEnabledNodesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["totalNodes"] = totalNodesResp.Count
|
||||
|
||||
// 常用的集群
|
||||
latestClusterMaps := []maps.Map{}
|
||||
@@ -54,12 +59,6 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["latestClusters"] = latestClusterMaps
|
||||
|
||||
// 搜索节点
|
||||
if params.SearchType == "node" && len(params.Keyword) > 0 {
|
||||
this.searchNodes(params.Keyword)
|
||||
return
|
||||
}
|
||||
|
||||
// 搜索集群
|
||||
countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{
|
||||
Keyword: params.Keyword,
|
||||
@@ -166,149 +165,3 @@ func (this *IndexAction) RunGet(params struct {
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) searchNodes(keyword string) {
|
||||
// 搜索节点
|
||||
countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
|
||||
Keyword: keyword,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
count := countResp.Count
|
||||
page := this.NewPage(count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
this.Data["countNodes"] = count
|
||||
|
||||
nodesResp, err := this.RPC().NodeRPC().ListEnabledNodesMatch(this.AdminContext(), &pb.ListEnabledNodesMatchRequest{
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
Keyword: keyword,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
nodeMaps := []maps.Map{}
|
||||
for _, node := range nodesResp.Nodes {
|
||||
// 状态
|
||||
isSynced := false
|
||||
status := &nodeconfigs.NodeStatus{}
|
||||
if len(node.StatusJSON) > 0 {
|
||||
err = json.Unmarshal(node.StatusJSON, &status)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
status.IsActive = status.IsActive && time.Now().Unix()-status.UpdatedAt <= 60 // N秒之内认为活跃
|
||||
isSynced = status.ConfigVersion == node.Version
|
||||
}
|
||||
|
||||
// IP
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
ipAddresses := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddresses = append(ipAddresses, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
"ip": addr.Ip,
|
||||
"canAccess": addr.CanAccess,
|
||||
"isOn": addr.IsOn,
|
||||
"isUp": addr.IsUp,
|
||||
})
|
||||
}
|
||||
|
||||
// 分组
|
||||
var groupMap maps.Map = nil
|
||||
if node.NodeGroup != nil {
|
||||
groupMap = maps.Map{
|
||||
"id": node.NodeGroup.Id,
|
||||
"name": node.NodeGroup.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// 区域
|
||||
var regionMap maps.Map = nil
|
||||
if node.NodeRegion != nil {
|
||||
regionMap = maps.Map{
|
||||
"id": node.NodeRegion.Id,
|
||||
"name": node.NodeRegion.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// DNS
|
||||
dnsRouteNames := []string{}
|
||||
for _, route := range node.DnsRoutes {
|
||||
dnsRouteNames = append(dnsRouteNames, route.Name)
|
||||
}
|
||||
|
||||
// 从集群
|
||||
var secondaryClusterMaps []maps.Map
|
||||
for _, secondaryCluster := range node.SecondaryNodeClusters {
|
||||
secondaryClusterMaps = append(secondaryClusterMaps, maps.Map{
|
||||
"id": secondaryCluster.Id,
|
||||
"name": secondaryCluster.Name,
|
||||
"isOn": secondaryCluster.IsOn,
|
||||
})
|
||||
}
|
||||
|
||||
nodeMaps = append(nodeMaps, maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"isInstalled": node.IsInstalled,
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
"installStatus": maps.Map{
|
||||
"isRunning": node.InstallStatus.IsRunning,
|
||||
"isFinished": node.InstallStatus.IsFinished,
|
||||
"isOk": node.InstallStatus.IsOk,
|
||||
"error": node.InstallStatus.Error,
|
||||
},
|
||||
"status": maps.Map{
|
||||
"isActive": status.IsActive,
|
||||
"updatedAt": status.UpdatedAt,
|
||||
"hostname": status.Hostname,
|
||||
"cpuUsage": status.CPUUsage,
|
||||
"cpuUsageText": fmt.Sprintf("%.2f%%", status.CPUUsage*100),
|
||||
"memUsage": status.MemoryUsage,
|
||||
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
||||
},
|
||||
"cluster": maps.Map{
|
||||
"id": node.NodeCluster.Id,
|
||||
"name": node.NodeCluster.Name,
|
||||
},
|
||||
"secondaryClusters": secondaryClusterMaps,
|
||||
"isSynced": isSynced,
|
||||
"ipAddresses": ipAddresses,
|
||||
"group": groupMap,
|
||||
"region": regionMap,
|
||||
"dnsRouteNames": dnsRouteNames,
|
||||
})
|
||||
}
|
||||
this.Data["nodes"] = nodeMaps
|
||||
|
||||
this.Data["clusters"] = []maps.Map{}
|
||||
|
||||
// 搜索集群
|
||||
{
|
||||
countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{
|
||||
Keyword: keyword,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["countClusters"] = countResp.Count
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ func init() {
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/create", new(CreateAction)).
|
||||
Post("/pin", new(PinAction)).
|
||||
Get("/nodes", new(NodesAction)).
|
||||
|
||||
// 只要登录即可访问的Action
|
||||
EndHelpers().
|
||||
|
||||
@@ -1,19 +1,28 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package servers
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type FixLogAction struct {
|
||||
type FixAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *FixLogAction) RunPost(params struct {
|
||||
func (this *FixAction) RunPost(params struct {
|
||||
LogIds []int64
|
||||
}) {
|
||||
var logIdStrings = []string{}
|
||||
for _, logId := range params.LogIds {
|
||||
logIdStrings = append(logIdStrings, types.String(logId))
|
||||
}
|
||||
|
||||
defer this.CreateLogInfo("设置日志 %s 为已修复", strings.Join(logIdStrings, ", "))
|
||||
|
||||
_, err := this.RPC().NodeLogRPC().FixNodeLogs(this.AdminContext(), &pb.FixNodeLogsRequest{NodeLogIds: params.LogIds})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
25
internal/web/actions/default/clusters/logs/fixAll.go
Normal file
25
internal/web/actions/default/clusters/logs/fixAll.go
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type FixAllAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *FixAllAction) RunPost(params struct {
|
||||
}) {
|
||||
defer this.CreateLogInfo("设置所有日志为已修复")
|
||||
|
||||
_, err := this.RPC().NodeLogRPC().FixAllNodeLogs(this.AdminContext(), &pb.FixAllNodeLogsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -3,8 +3,10 @@ package logs
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/nodelogutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
)
|
||||
@@ -14,8 +16,11 @@ type IndexAction struct {
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
if this.ParamString("type") == "unread" {
|
||||
var paramType = this.ParamString("type")
|
||||
if paramType == "unread" {
|
||||
this.FirstMenu("unread")
|
||||
} else if paramType == "needFix" {
|
||||
this.FirstMenu("needFix")
|
||||
} else {
|
||||
this.FirstMenu("index")
|
||||
}
|
||||
@@ -26,7 +31,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
DayTo string
|
||||
Keyword string
|
||||
Level string
|
||||
Type string
|
||||
Type string // unread, needFix
|
||||
Tag string
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
@@ -40,6 +45,13 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
|
||||
var fixedState configutils.BoolState = 0
|
||||
var allServers = false
|
||||
if params.Type == "needFix" {
|
||||
fixedState = configutils.BoolStateNo
|
||||
allServers = true
|
||||
}
|
||||
|
||||
// 常见标签
|
||||
this.Data["tags"] = nodelogutils.FindNodeCommonTags()
|
||||
|
||||
@@ -54,6 +66,18 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["countUnreadLogs"] = countUnreadResp.Count
|
||||
|
||||
// 需要修复数量
|
||||
countNeedFixResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
AllServers: true,
|
||||
FixedState: int32(configutils.BoolStateNo),
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["countNeedFixLogs"] = countNeedFixResp.Count
|
||||
|
||||
// 日志数量
|
||||
countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
@@ -65,13 +89,15 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Level: params.Level,
|
||||
IsUnread: params.Type == "unread",
|
||||
Tag: params.Tag,
|
||||
FixedState: int32(fixedState),
|
||||
AllServers: allServers,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
count := countResp.Count
|
||||
page := this.NewPage(count)
|
||||
var count = countResp.Count
|
||||
var page = this.NewPage(count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
|
||||
@@ -84,6 +110,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Level: params.Level,
|
||||
IsUnread: params.Type == "unread",
|
||||
Tag: params.Tag,
|
||||
FixedState: int32(fixedState),
|
||||
AllServers: allServers,
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
})
|
||||
@@ -92,14 +120,14 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
logs := []maps.Map{}
|
||||
var logs = []maps.Map{}
|
||||
for _, log := range logsResp.NodeLogs {
|
||||
// 节点信息
|
||||
nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: log.NodeId})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
node := nodeResp.Node
|
||||
var node = nodeResp.Node
|
||||
if node == nil || node.NodeCluster == nil {
|
||||
continue
|
||||
}
|
||||
@@ -118,6 +146,11 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
var isFixed = true
|
||||
if !log.IsFixed && log.ServerId > 0 && lists.ContainsString([]string{"success", "warning", "error"}, log.Level) {
|
||||
isFixed = false
|
||||
}
|
||||
|
||||
logs = append(logs, maps.Map{
|
||||
"id": log.Id,
|
||||
"tag": log.Tag,
|
||||
@@ -127,6 +160,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"isToday": timeutil.FormatTime("Y-m-d", log.CreatedAt) == timeutil.Format("Y-m-d"),
|
||||
"count": log.Count,
|
||||
"isRead": log.IsRead,
|
||||
"isFixed": isFixed,
|
||||
"node": maps.Map{
|
||||
"id": node.Id,
|
||||
"cluster": maps.Map{
|
||||
|
||||
@@ -16,6 +16,8 @@ func init() {
|
||||
Get("", new(IndexAction)).
|
||||
Post("/readLogs", new(ReadLogsAction)).
|
||||
Post("/readAllLogs", new(ReadAllLogsAction)).
|
||||
Post("/fix", new(FixAction)).
|
||||
Post("/fixAll", new(FixAllAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
293
internal/web/actions/default/clusters/nodes.go
Normal file
293
internal/web/actions/default/clusters/nodes.go
Normal file
@@ -0,0 +1,293 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package clusters
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type NodesAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *NodesAction) Init() {
|
||||
this.Nav("", "", "node")
|
||||
}
|
||||
|
||||
func (this *NodesAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
GroupId int64
|
||||
RegionId int64
|
||||
InstalledState int
|
||||
ActiveState int
|
||||
Keyword string
|
||||
Level int32
|
||||
|
||||
CpuOrder string
|
||||
MemoryOrder string
|
||||
TrafficInOrder string
|
||||
TrafficOutOrder string
|
||||
LoadOrder string
|
||||
}) {
|
||||
this.Data["groupId"] = params.GroupId
|
||||
this.Data["regionId"] = params.RegionId
|
||||
this.Data["installState"] = params.InstalledState
|
||||
this.Data["activeState"] = params.ActiveState
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["level"] = params.Level
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
this.Data["hasOrder"] = len(params.CpuOrder) > 0 || len(params.MemoryOrder) > 0 || len(params.TrafficInOrder) > 0 || len(params.TrafficOutOrder) > 0 || len(params.LoadOrder) > 0
|
||||
|
||||
// 集群是否已经设置了线路
|
||||
clusterDNSResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["hasClusterDNS"] = clusterDNSResp.Domain != nil
|
||||
|
||||
// 数量
|
||||
countAllResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["countAll"] = countAllResp.Count
|
||||
|
||||
countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeGroupId: params.GroupId,
|
||||
NodeRegionId: params.RegionId,
|
||||
Level: params.Level,
|
||||
InstallState: types.Int32(params.InstalledState),
|
||||
ActiveState: types.Int32(params.ActiveState),
|
||||
Keyword: params.Keyword,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
var page = this.NewPage(countResp.Count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
var req = &pb.ListEnabledNodesMatchRequest{
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeGroupId: params.GroupId,
|
||||
NodeRegionId: params.RegionId,
|
||||
Level: params.Level,
|
||||
InstallState: types.Int32(params.InstalledState),
|
||||
ActiveState: types.Int32(params.ActiveState),
|
||||
Keyword: params.Keyword,
|
||||
}
|
||||
if params.CpuOrder == "asc" {
|
||||
req.CpuAsc = true
|
||||
} else if params.CpuOrder == "desc" {
|
||||
req.CpuDesc = true
|
||||
} else if params.MemoryOrder == "asc" {
|
||||
req.MemoryAsc = true
|
||||
} else if params.MemoryOrder == "desc" {
|
||||
req.MemoryDesc = true
|
||||
} else if params.TrafficInOrder == "asc" {
|
||||
req.TrafficInAsc = true
|
||||
} else if params.TrafficInOrder == "desc" {
|
||||
req.TrafficInDesc = true
|
||||
} else if params.TrafficOutOrder == "asc" {
|
||||
req.TrafficOutAsc = true
|
||||
} else if params.TrafficOutOrder == "desc" {
|
||||
req.TrafficOutDesc = true
|
||||
} else if params.LoadOrder == "asc" {
|
||||
req.LoadAsc = true
|
||||
} else if params.LoadOrder == "desc" {
|
||||
req.LoadDesc = true
|
||||
}
|
||||
nodesResp, err := this.RPC().NodeRPC().ListEnabledNodesMatch(this.AdminContext(), req)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var nodeMaps = []maps.Map{}
|
||||
for _, node := range nodesResp.Nodes {
|
||||
// 状态
|
||||
isSynced := false
|
||||
status := &nodeconfigs.NodeStatus{}
|
||||
if len(node.StatusJSON) > 0 {
|
||||
err = json.Unmarshal(node.StatusJSON, &status)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
continue
|
||||
}
|
||||
status.IsActive = status.IsActive && time.Now().Unix()-status.UpdatedAt <= 60 // N秒之内认为活跃
|
||||
isSynced = status.ConfigVersion == node.Version
|
||||
}
|
||||
|
||||
// IP
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
ipAddresses := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddresses = append(ipAddresses, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
"ip": addr.Ip,
|
||||
"canAccess": addr.CanAccess,
|
||||
"isUp": addr.IsUp,
|
||||
"isOn": addr.IsOn,
|
||||
})
|
||||
}
|
||||
|
||||
// 分组
|
||||
var groupMap maps.Map = nil
|
||||
if node.NodeGroup != nil {
|
||||
groupMap = maps.Map{
|
||||
"id": node.NodeGroup.Id,
|
||||
"name": node.NodeGroup.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// 区域
|
||||
var regionMap maps.Map = nil
|
||||
if node.NodeRegion != nil {
|
||||
regionMap = maps.Map{
|
||||
"id": node.NodeRegion.Id,
|
||||
"name": node.NodeRegion.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// DNS
|
||||
dnsRouteNames := []string{}
|
||||
for _, route := range node.DnsRoutes {
|
||||
dnsRouteNames = append(dnsRouteNames, route.Name)
|
||||
}
|
||||
|
||||
// 从集群
|
||||
var secondaryClusterMaps []maps.Map
|
||||
for _, secondaryCluster := range node.SecondaryNodeClusters {
|
||||
secondaryClusterMaps = append(secondaryClusterMaps, maps.Map{
|
||||
"id": secondaryCluster.Id,
|
||||
"name": secondaryCluster.Name,
|
||||
"isOn": secondaryCluster.IsOn,
|
||||
})
|
||||
}
|
||||
|
||||
nodeMaps = append(nodeMaps, maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"isInstalled": node.IsInstalled,
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
"installStatus": maps.Map{
|
||||
"isRunning": node.InstallStatus.IsRunning,
|
||||
"isFinished": node.InstallStatus.IsFinished,
|
||||
"isOk": node.InstallStatus.IsOk,
|
||||
"error": node.InstallStatus.Error,
|
||||
},
|
||||
"status": maps.Map{
|
||||
"isActive": status.IsActive,
|
||||
"updatedAt": status.UpdatedAt,
|
||||
"hostname": status.Hostname,
|
||||
"cpuUsage": status.CPUUsage,
|
||||
"cpuUsageText": numberutils.FormatFloat2(status.CPUUsage * 100),
|
||||
"memUsage": status.MemoryUsage,
|
||||
"memUsageText": numberutils.FormatFloat2(status.MemoryUsage * 100),
|
||||
"trafficInBytes": status.TrafficInBytes,
|
||||
"trafficOutBytes": status.TrafficOutBytes,
|
||||
"load1m": numberutils.FormatFloat2(status.Load1m),
|
||||
},
|
||||
"cluster": maps.Map{
|
||||
"id": node.NodeCluster.Id,
|
||||
"name": node.NodeCluster.Name,
|
||||
},
|
||||
"secondaryClusters": secondaryClusterMaps,
|
||||
"isSynced": isSynced,
|
||||
"ipAddresses": ipAddresses,
|
||||
"group": groupMap,
|
||||
"region": regionMap,
|
||||
"dnsRouteNames": dnsRouteNames,
|
||||
"level": node.Level,
|
||||
})
|
||||
}
|
||||
this.Data["nodes"] = nodeMaps
|
||||
|
||||
// 所有分组
|
||||
var groupMaps = []maps.Map{}
|
||||
groupsResp, err := this.RPC().NodeGroupRPC().FindAllEnabledNodeGroupsWithNodeClusterId(this.AdminContext(), &pb.FindAllEnabledNodeGroupsWithNodeClusterIdRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, group := range groupsResp.NodeGroups {
|
||||
countNodesInGroupResp, err := this.RPC().NodeRPC().CountAllEnabledNodesWithNodeGroupId(this.AdminContext(), &pb.CountAllEnabledNodesWithNodeGroupIdRequest{NodeGroupId: group.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
countNodes := countNodesInGroupResp.Count
|
||||
groupName := group.Name
|
||||
if countNodes > 0 {
|
||||
groupName += "(" + strconv.FormatInt(countNodes, 10) + ")"
|
||||
}
|
||||
groupMaps = append(groupMaps, maps.Map{
|
||||
"id": group.Id,
|
||||
"name": groupName,
|
||||
"countNodes": countNodes,
|
||||
})
|
||||
}
|
||||
this.Data["groups"] = groupMaps
|
||||
|
||||
// 所有区域
|
||||
regionsResp, err := this.RPC().NodeRegionRPC().FindAllEnabledAndOnNodeRegions(this.AdminContext(), &pb.FindAllEnabledAndOnNodeRegionsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var regionMaps = []maps.Map{}
|
||||
for _, region := range regionsResp.NodeRegions {
|
||||
regionMaps = append(regionMaps, maps.Map{
|
||||
"id": region.Id,
|
||||
"name": region.Name,
|
||||
})
|
||||
}
|
||||
this.Data["regions"] = regionMaps
|
||||
|
||||
// 级别
|
||||
this.Data["levels"] = []maps.Map{}
|
||||
if teaconst.IsPlus {
|
||||
this.Data["levels"] = nodeconfigs.FindAllNodeLevels()
|
||||
}
|
||||
|
||||
// 集群总数
|
||||
totalClustersResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["totalNodeClusters"] = totalClustersResp.Count
|
||||
|
||||
// 节点总数
|
||||
this.Data["totalNodes"] = countResp.Count
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -1,3 +1,8 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package providers
|
||||
|
||||
import (
|
||||
@@ -60,8 +65,9 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
Type string
|
||||
|
||||
// DNSPod
|
||||
ParamId string
|
||||
ParamToken string
|
||||
ParamId string
|
||||
ParamToken string
|
||||
ParamRegion string
|
||||
|
||||
// AliDNS
|
||||
ParamAccessKeyId string
|
||||
@@ -76,8 +82,8 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
ParamApiSecret string
|
||||
|
||||
// CloudFlare
|
||||
CloudFlareAPIKey string
|
||||
CloudFlareEmail string
|
||||
ParamCloudFlareAPIKey string
|
||||
ParamCloudFlareEmail string
|
||||
|
||||
// Local EdgeDNS
|
||||
ParamLocalEdgeDNSClusterId int64
|
||||
@@ -106,6 +112,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
|
||||
apiParams["id"] = params.ParamId
|
||||
apiParams["token"] = params.ParamToken
|
||||
apiParams["region"] = params.ParamRegion
|
||||
case "alidns":
|
||||
params.Must.
|
||||
Field("paramAccessKeyId", params.ParamAccessKeyId).
|
||||
@@ -135,12 +142,12 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
apiParams["apiSecret"] = params.ParamApiSecret
|
||||
case "cloudFlare":
|
||||
params.Must.
|
||||
Field("cloudFlareAPIKey", params.CloudFlareAPIKey).
|
||||
Field("paramCloudFlareAPIKey", params.ParamCloudFlareAPIKey).
|
||||
Require("请输入API密钥").
|
||||
Field("cloudFlareEmail", params.CloudFlareEmail).
|
||||
Field("paramCloudFlareEmail", params.ParamCloudFlareEmail).
|
||||
Email("请输入正确格式的邮箱地址")
|
||||
apiParams["apiKey"] = params.CloudFlareAPIKey
|
||||
apiParams["email"] = params.CloudFlareEmail
|
||||
apiParams["apiKey"] = params.ParamCloudFlareAPIKey
|
||||
apiParams["email"] = params.ParamCloudFlareEmail
|
||||
case "localEdgeDNS":
|
||||
params.Must.
|
||||
Field("ParamLocalEdgeDNSClusterId", params.ParamLocalEdgeDNSClusterId).
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -17,12 +19,20 @@ func (this *IndexAction) Init() {
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
Keyword string
|
||||
Domain string
|
||||
}) {
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["domain"] = params.Domain
|
||||
|
||||
// 格式化域名
|
||||
var domain = params.Domain
|
||||
domain = regexp.MustCompile(`^(www\.)`).ReplaceAllString(params.Domain, "")
|
||||
domain = strings.ToLower(domain)
|
||||
|
||||
countResp, err := this.RPC().DNSProviderRPC().CountAllEnabledDNSProviders(this.AdminContext(), &pb.CountAllEnabledDNSProvidersRequest{
|
||||
AdminId: this.AdminId(),
|
||||
Keyword: params.Keyword,
|
||||
Domain: domain,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -35,6 +45,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
providersResp, err := this.RPC().DNSProviderRPC().ListEnabledDNSProviders(this.AdminContext(), &pb.ListEnabledDNSProvidersRequest{
|
||||
AdminId: this.AdminId(),
|
||||
Keyword: params.Keyword,
|
||||
Domain: domain,
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
})
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package providers
|
||||
|
||||
import (
|
||||
@@ -89,8 +92,9 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Type string
|
||||
|
||||
// DNSPod
|
||||
ParamId string
|
||||
ParamToken string
|
||||
ParamId string
|
||||
ParamToken string
|
||||
ParamRegion string
|
||||
|
||||
// AliDNS
|
||||
ParamAccessKeyId string
|
||||
@@ -105,8 +109,8 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
ParamApiSecret string
|
||||
|
||||
// CloudFlare
|
||||
CloudFlareAPIKey string
|
||||
CloudFlareEmail string
|
||||
ParamCloudFlareAPIKey string
|
||||
ParamCloudFlareEmail string
|
||||
|
||||
// Local EdgeDNS
|
||||
ParamLocalEdgeDNSClusterId int64
|
||||
@@ -137,6 +141,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
|
||||
apiParams["id"] = params.ParamId
|
||||
apiParams["token"] = params.ParamToken
|
||||
apiParams["region"] = params.ParamRegion
|
||||
case "alidns":
|
||||
params.Must.
|
||||
Field("paramAccessKeyId", params.ParamAccessKeyId).
|
||||
@@ -166,12 +171,12 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
apiParams["apiSecret"] = params.ParamApiSecret
|
||||
case "cloudFlare":
|
||||
params.Must.
|
||||
Field("cloudFlareAPIKey", params.CloudFlareAPIKey).
|
||||
Field("paramCloudFlareAPIKey", params.ParamCloudFlareAPIKey).
|
||||
Require("请输入API密钥").
|
||||
Field("cloudFlareEmail", params.CloudFlareEmail).
|
||||
Field("paramCloudFlareEmail", params.ParamCloudFlareEmail).
|
||||
Email("请输入正确格式的邮箱地址")
|
||||
apiParams["apiKey"] = params.CloudFlareAPIKey
|
||||
apiParams["email"] = params.CloudFlareEmail
|
||||
apiParams["apiKey"] = params.ParamCloudFlareAPIKey
|
||||
apiParams["email"] = params.ParamCloudFlareEmail
|
||||
case "localEdgeDNS":
|
||||
params.Must.
|
||||
Field("ParamLocalEdgeDNSClusterId", params.ParamLocalEdgeDNSClusterId).
|
||||
|
||||
@@ -27,7 +27,7 @@ func (this *ExportExcelAction) RunGet(params struct {
|
||||
}) {
|
||||
logsResp, err := this.RPC().LogRPC().ListLogs(this.AdminContext(), &pb.ListLogsRequest{
|
||||
Offset: 0,
|
||||
Size: 1000, // 日志最大导出1000条,TODO 将来可以配置
|
||||
Size: 10000, // 日志最大导出10000条,TODO 将来可以配置
|
||||
DayFrom: params.DayFrom,
|
||||
DayTo: params.DayTo,
|
||||
Keyword: params.Keyword,
|
||||
@@ -38,7 +38,7 @@ func (this *ExportExcelAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
wb := xlsx.NewFile()
|
||||
var wb = xlsx.NewFile()
|
||||
sheet, err := wb.AddSheet("default")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -47,7 +47,7 @@ func (this *ExportExcelAction) RunGet(params struct {
|
||||
|
||||
// 头部
|
||||
{
|
||||
row := sheet.AddRow()
|
||||
var row = sheet.AddRow()
|
||||
row.SetHeight(25)
|
||||
row.AddCell().SetString("ID")
|
||||
row.AddCell().SetString("日期")
|
||||
@@ -61,8 +61,8 @@ func (this *ExportExcelAction) RunGet(params struct {
|
||||
|
||||
// 数据
|
||||
for _, log := range logsResp.Logs {
|
||||
regionName := ""
|
||||
ispName := ""
|
||||
var regionName = ""
|
||||
var ispName = ""
|
||||
regionResp, err := this.RPC().IPLibraryRPC().LookupIPRegion(this.AdminContext(), &pb.LookupIPRegionRequest{Ip: log.Ip})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -86,7 +86,7 @@ func (this *ExportExcelAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
row := sheet.AddRow()
|
||||
var row = sheet.AddRow()
|
||||
row.SetHeight(25)
|
||||
row.AddCell().SetInt64(log.Id)
|
||||
row.AddCell().SetString(timeutil.FormatTime("Y-m-d H:i:s", log.CreatedAt))
|
||||
@@ -106,7 +106,7 @@ func (this *ExportExcelAction) RunGet(params struct {
|
||||
this.AddHeader("Content-Disposition", "attachment; filename=\"LOG-"+timeutil.Format("YmdHis")+".xlsx\"")
|
||||
this.AddHeader("Cache-Control", "max-age=0")
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
var buf = bytes.NewBuffer([]byte{})
|
||||
err = wb.Write(buf)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ipbox
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/cmd"
|
||||
)
|
||||
|
||||
type CreatePopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) RunGet(params struct{}) {
|
||||
this.Data["types"] = serverconfigs.FindAllAccessLogStorageTypes()
|
||||
this.Data["syslogPriorities"] = serverconfigs.AccessLogSyslogStoragePriorities
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) RunPost(params struct {
|
||||
Name string
|
||||
Type string
|
||||
|
||||
// file
|
||||
FilePath string
|
||||
FileAutoCreate bool
|
||||
|
||||
// es
|
||||
EsEndpoint string
|
||||
EsIndex string
|
||||
EsMappingType string
|
||||
EsUsername string
|
||||
EsPassword string
|
||||
|
||||
// mysql
|
||||
MysqlHost string
|
||||
MysqlPort int
|
||||
MysqlUsername string
|
||||
MysqlPassword string
|
||||
MysqlDatabase string
|
||||
MysqlTable string
|
||||
MysqlLogField string
|
||||
|
||||
// tcp
|
||||
TcpNetwork string
|
||||
TcpAddr string
|
||||
|
||||
// syslog
|
||||
SyslogProtocol string
|
||||
SyslogServerAddr string
|
||||
SyslogServerPort int
|
||||
SyslogSocket string
|
||||
SyslogTag string
|
||||
SyslogPriority int
|
||||
|
||||
// command
|
||||
CommandCommand string
|
||||
CommandArgs string
|
||||
CommandDir string
|
||||
|
||||
IsPublic bool
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
var policyId int64 = 0
|
||||
defer func() {
|
||||
this.CreateLogInfo("创建访问日志策略 %d", policyId)
|
||||
}()
|
||||
|
||||
params.Must.
|
||||
Field("name", params.Name).
|
||||
Require("请输入日志策略的名称").
|
||||
Field("type", params.Type).
|
||||
Require("请选择存储类型")
|
||||
|
||||
var options interface{} = nil
|
||||
switch params.Type {
|
||||
case serverconfigs.AccessLogStorageTypeFile:
|
||||
params.Must.
|
||||
Field("filePath", params.FilePath).
|
||||
Require("请输入日志文件路径")
|
||||
|
||||
storage := new(serverconfigs.AccessLogFileStorageConfig)
|
||||
storage.Path = params.FilePath
|
||||
storage.AutoCreate = params.FileAutoCreate
|
||||
options = storage
|
||||
case serverconfigs.AccessLogStorageTypeES:
|
||||
params.Must.
|
||||
Field("esEndpoint", params.EsEndpoint).
|
||||
Require("请输入Endpoint").
|
||||
Field("esIndex", params.EsIndex).
|
||||
Require("请输入Index名称").
|
||||
Field("esMappingType", params.EsMappingType).
|
||||
Require("请输入Mapping名称")
|
||||
|
||||
storage := new(serverconfigs.AccessLogESStorageConfig)
|
||||
storage.Endpoint = params.EsEndpoint
|
||||
storage.Index = params.EsIndex
|
||||
storage.MappingType = params.EsMappingType
|
||||
storage.Username = params.EsUsername
|
||||
storage.Password = params.EsPassword
|
||||
options = storage
|
||||
case serverconfigs.AccessLogStorageTypeTCP:
|
||||
params.Must.
|
||||
Field("tcpNetwork", params.TcpNetwork).
|
||||
Require("请选择网络协议").
|
||||
Field("tcpAddr", params.TcpAddr).
|
||||
Require("请输入网络地址")
|
||||
|
||||
storage := new(serverconfigs.AccessLogTCPStorageConfig)
|
||||
storage.Network = params.TcpNetwork
|
||||
storage.Addr = params.TcpAddr
|
||||
options = storage
|
||||
case serverconfigs.AccessLogStorageTypeSyslog:
|
||||
switch params.SyslogProtocol {
|
||||
case serverconfigs.AccessLogSyslogStorageProtocolTCP, serverconfigs.AccessLogSyslogStorageProtocolUDP:
|
||||
params.Must.
|
||||
Field("syslogServerAddr", params.SyslogServerAddr).
|
||||
Require("请输入网络地址")
|
||||
case serverconfigs.AccessLogSyslogStorageProtocolSocket:
|
||||
params.Must.
|
||||
Field("syslogSocket", params.SyslogSocket).
|
||||
Require("请输入Socket路径")
|
||||
}
|
||||
|
||||
storage := new(serverconfigs.AccessLogSyslogStorageConfig)
|
||||
storage.Protocol = params.SyslogProtocol
|
||||
storage.ServerAddr = params.SyslogServerAddr
|
||||
storage.ServerPort = params.SyslogServerPort
|
||||
storage.Socket = params.SyslogSocket
|
||||
storage.Tag = params.SyslogTag
|
||||
storage.Priority = params.SyslogPriority
|
||||
options = storage
|
||||
case serverconfigs.AccessLogStorageTypeCommand:
|
||||
params.Must.
|
||||
Field("commandCommand", params.CommandCommand).
|
||||
Require("请输入可执行命令")
|
||||
|
||||
storage := new(serverconfigs.AccessLogCommandStorageConfig)
|
||||
storage.Command = params.CommandCommand
|
||||
storage.Args = cmd.ParseArgs(params.CommandArgs)
|
||||
storage.Dir = params.CommandDir
|
||||
options = storage
|
||||
}
|
||||
|
||||
if options == nil {
|
||||
this.Fail("找不到选择的存储类型")
|
||||
}
|
||||
|
||||
optionsJSON, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
createResp, err := this.RPC().HTTPAccessLogPolicyRPC().CreateHTTPAccessLogPolicy(this.AdminContext(), &pb.CreateHTTPAccessLogPolicyRequest{
|
||||
Name: params.Name,
|
||||
Type: params.Type,
|
||||
OptionsJSON: optionsJSON,
|
||||
CondsJSON: nil, // TODO
|
||||
IsPublic: params.IsPublic,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
policyId = createResp.HttpAccessLogPolicyId
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ipbox
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type DeleteAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *DeleteAction) RunPost(params struct {
|
||||
PolicyId int64
|
||||
}) {
|
||||
defer this.CreateLogInfo("删除访问日志策略 %d", params.PolicyId)
|
||||
|
||||
_, err := this.RPC().HTTPAccessLogPolicyRPC().DeleteHTTPAccessLogPolicy(this.AdminContext(), &pb.DeleteHTTPAccessLogPolicyRequest{HttpAccessLogPolicyId: params.PolicyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ipbox
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "index")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct{}) {
|
||||
countResp, err := this.RPC().HTTPAccessLogPolicyRPC().CountAllEnabledHTTPAccessLogPolicies(this.AdminContext(), &pb.CountAllEnabledHTTPAccessLogPoliciesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
page := this.NewPage(countResp.Count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
policiesResp, err := this.RPC().HTTPAccessLogPolicyRPC().ListEnabledHTTPAccessLogPolicies(this.AdminContext(), &pb.ListEnabledHTTPAccessLogPoliciesRequest{
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
})
|
||||
var policyMaps = []maps.Map{}
|
||||
for _, policy := range policiesResp.HttpAccessLogPolicies {
|
||||
var optionsMap = maps.Map{}
|
||||
if len(policy.OptionsJSON) > 0 {
|
||||
err = json.Unmarshal(policy.OptionsJSON, &optionsMap)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
policyMaps = append(policyMaps, maps.Map{
|
||||
"id": policy.Id,
|
||||
"name": policy.Name,
|
||||
"type": policy.Type,
|
||||
"typeName": serverconfigs.FindAccessLogStorageTypeName(policy.Type),
|
||||
"isOn": policy.IsOn,
|
||||
"isPublic": policy.IsPublic,
|
||||
"options": optionsMap,
|
||||
})
|
||||
}
|
||||
this.Data["policies"] = policyMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ipbox
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/accesslogs/policyutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
)
|
||||
|
||||
type PolicyAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *PolicyAction) Init() {
|
||||
this.Nav("", "", "policy")
|
||||
}
|
||||
|
||||
func (this *PolicyAction) RunGet(params struct {
|
||||
PolicyId int64
|
||||
}) {
|
||||
err := policyutils.InitPolicy(this.Parent(), params.PolicyId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
var policyMap = this.Data.GetMap("policy")
|
||||
if policyMap.GetString("type") == serverconfigs.AccessLogStorageTypeSyslog {
|
||||
this.Data["syslogPriorityName"] = serverconfigs.FindAccessLogSyslogStoragePriorityName(policyMap.GetMap("options").GetInt("priority"))
|
||||
} else {
|
||||
this.Data["syslogPriorityName"] = ""
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package policyutils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
// InitPolicy 初始化访问日志策略
|
||||
func InitPolicy(parent *actionutils.ParentAction, policyId int64) error {
|
||||
rpcClient, err := rpc.SharedRPC()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
policyResp, err := rpcClient.HTTPAccessLogPolicyRPC().FindEnabledHTTPAccessLogPolicy(parent.AdminContext(), &pb.FindEnabledHTTPAccessLogPolicyRequest{HttpAccessLogPolicyId: policyId})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var policy = policyResp.HttpAccessLogPolicy
|
||||
if policy == nil {
|
||||
return errors.New("can not find policy '" + types.String(policyId) + "'")
|
||||
}
|
||||
|
||||
var options = maps.Map{}
|
||||
if len(policy.OptionsJSON) > 0 {
|
||||
err = json.Unmarshal(policy.OptionsJSON, &options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
parent.Data["policy"] = maps.Map{
|
||||
"id": policy.Id,
|
||||
"name": policy.Name,
|
||||
"type": policy.Type,
|
||||
"typeName": serverconfigs.FindAccessLogStorageTypeName(policy.Type),
|
||||
"isOn": policy.IsOn,
|
||||
"isPublic": policy.IsPublic,
|
||||
"options": options,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ipbox
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/accesslogs/policyutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
)
|
||||
|
||||
type TestAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *TestAction) Init() {
|
||||
this.Nav("", "", "test")
|
||||
}
|
||||
|
||||
func (this *TestAction) RunGet(params struct {
|
||||
PolicyId int64
|
||||
}) {
|
||||
err := policyutils.InitPolicy(this.Parent(), params.PolicyId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *TestAction) RunPost(params struct {
|
||||
PolicyId int64
|
||||
BodyJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
defer this.CreateLogInfo("测试向访问日志策略 %d 写入数据", params.PolicyId)
|
||||
|
||||
var accessLog = &pb.HTTPAccessLog{}
|
||||
err := json.Unmarshal(params.BodyJSON, accessLog)
|
||||
if err != nil {
|
||||
this.Fail("发送内容不是有效的JSON:" + err.Error())
|
||||
}
|
||||
|
||||
_, err = this.RPC().HTTPAccessLogPolicyRPC().WriteHTTPAccessLogPolicy(this.AdminContext(), &pb.WriteHTTPAccessLogPolicyRequest{
|
||||
HttpAccessLogPolicyId: params.PolicyId,
|
||||
HttpAccessLog: accessLog,
|
||||
})
|
||||
if err != nil {
|
||||
this.Fail("发送失败:" + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ipbox
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/accesslogs/policyutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/cmd"
|
||||
)
|
||||
|
||||
type UpdateAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *UpdateAction) Init() {
|
||||
this.Nav("", "", "update")
|
||||
}
|
||||
|
||||
func (this *UpdateAction) RunGet(params struct {
|
||||
PolicyId int64
|
||||
}) {
|
||||
err := policyutils.InitPolicy(this.Parent(), params.PolicyId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["types"] = serverconfigs.FindAllAccessLogStorageTypes()
|
||||
this.Data["syslogPriorities"] = serverconfigs.AccessLogSyslogStoragePriorities
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *UpdateAction) RunPost(params struct {
|
||||
PolicyId int64
|
||||
Name string
|
||||
|
||||
// file
|
||||
FilePath string
|
||||
FileAutoCreate bool
|
||||
|
||||
// es
|
||||
EsEndpoint string
|
||||
EsIndex string
|
||||
EsMappingType string
|
||||
EsUsername string
|
||||
EsPassword string
|
||||
|
||||
// mysql
|
||||
MysqlHost string
|
||||
MysqlPort int
|
||||
MysqlUsername string
|
||||
MysqlPassword string
|
||||
MysqlDatabase string
|
||||
MysqlTable string
|
||||
MysqlLogField string
|
||||
|
||||
// tcp
|
||||
TcpNetwork string
|
||||
TcpAddr string
|
||||
|
||||
// syslog
|
||||
SyslogProtocol string
|
||||
SyslogServerAddr string
|
||||
SyslogServerPort int
|
||||
SyslogSocket string
|
||||
SyslogTag string
|
||||
SyslogPriority int
|
||||
|
||||
// command
|
||||
CommandCommand string
|
||||
CommandArgs string
|
||||
CommandDir string
|
||||
|
||||
IsOn bool
|
||||
IsPublic bool
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改访问日志策略 %d", params.PolicyId)
|
||||
|
||||
policyResp, err := this.RPC().HTTPAccessLogPolicyRPC().FindEnabledHTTPAccessLogPolicy(this.AdminContext(), &pb.FindEnabledHTTPAccessLogPolicyRequest{HttpAccessLogPolicyId: params.PolicyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var policy = policyResp.HttpAccessLogPolicy
|
||||
if policy == nil {
|
||||
this.Fail("找不到要修改的策略")
|
||||
return
|
||||
}
|
||||
|
||||
params.Must.
|
||||
Field("name", params.Name).
|
||||
Require("请输入日志策略的名称")
|
||||
|
||||
var options interface{} = nil
|
||||
switch policy.Type {
|
||||
case serverconfigs.AccessLogStorageTypeFile:
|
||||
params.Must.
|
||||
Field("filePath", params.FilePath).
|
||||
Require("请输入日志文件路径")
|
||||
|
||||
storage := new(serverconfigs.AccessLogFileStorageConfig)
|
||||
storage.Path = params.FilePath
|
||||
storage.AutoCreate = params.FileAutoCreate
|
||||
options = storage
|
||||
case serverconfigs.AccessLogStorageTypeES:
|
||||
params.Must.
|
||||
Field("esEndpoint", params.EsEndpoint).
|
||||
Require("请输入Endpoint").
|
||||
Field("esIndex", params.EsIndex).
|
||||
Require("请输入Index名称").
|
||||
Field("esMappingType", params.EsMappingType).
|
||||
Require("请输入Mapping名称")
|
||||
|
||||
storage := new(serverconfigs.AccessLogESStorageConfig)
|
||||
storage.Endpoint = params.EsEndpoint
|
||||
storage.Index = params.EsIndex
|
||||
storage.MappingType = params.EsMappingType
|
||||
storage.Username = params.EsUsername
|
||||
storage.Password = params.EsPassword
|
||||
options = storage
|
||||
case serverconfigs.AccessLogStorageTypeTCP:
|
||||
params.Must.
|
||||
Field("tcpNetwork", params.TcpNetwork).
|
||||
Require("请选择网络协议").
|
||||
Field("tcpAddr", params.TcpAddr).
|
||||
Require("请输入网络地址")
|
||||
|
||||
storage := new(serverconfigs.AccessLogTCPStorageConfig)
|
||||
storage.Network = params.TcpNetwork
|
||||
storage.Addr = params.TcpAddr
|
||||
options = storage
|
||||
case serverconfigs.AccessLogStorageTypeSyslog:
|
||||
switch params.SyslogProtocol {
|
||||
case serverconfigs.AccessLogSyslogStorageProtocolTCP, serverconfigs.AccessLogSyslogStorageProtocolUDP:
|
||||
params.Must.
|
||||
Field("syslogServerAddr", params.SyslogServerAddr).
|
||||
Require("请输入网络地址")
|
||||
case serverconfigs.AccessLogSyslogStorageProtocolSocket:
|
||||
params.Must.
|
||||
Field("syslogSocket", params.SyslogSocket).
|
||||
Require("请输入Socket路径")
|
||||
}
|
||||
|
||||
storage := new(serverconfigs.AccessLogSyslogStorageConfig)
|
||||
storage.Protocol = params.SyslogProtocol
|
||||
storage.ServerAddr = params.SyslogServerAddr
|
||||
storage.ServerPort = params.SyslogServerPort
|
||||
storage.Socket = params.SyslogSocket
|
||||
storage.Tag = params.SyslogTag
|
||||
storage.Priority = params.SyslogPriority
|
||||
options = storage
|
||||
case serverconfigs.AccessLogStorageTypeCommand:
|
||||
params.Must.
|
||||
Field("commandCommand", params.CommandCommand).
|
||||
Require("请输入可执行命令")
|
||||
|
||||
storage := new(serverconfigs.AccessLogCommandStorageConfig)
|
||||
storage.Command = params.CommandCommand
|
||||
storage.Args = cmd.ParseArgs(params.CommandArgs)
|
||||
storage.Dir = params.CommandDir
|
||||
options = storage
|
||||
}
|
||||
|
||||
if options == nil {
|
||||
this.Fail("找不到选择的存储类型")
|
||||
}
|
||||
|
||||
optionsJSON, err := json.Marshal(options)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
_, err = this.RPC().HTTPAccessLogPolicyRPC().UpdateHTTPAccessLogPolicy(this.AdminContext(), &pb.UpdateHTTPAccessLogPolicyRequest{
|
||||
HttpAccessLogPolicyId: params.PolicyId,
|
||||
Name: params.Name,
|
||||
OptionsJSON: optionsJSON,
|
||||
CondsJSON: nil, // TODO
|
||||
IsOn: params.IsOn,
|
||||
IsPublic: params.IsPublic,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -70,13 +70,13 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
certConfigJSON := certConfigResp.SslCertJSON
|
||||
var certConfigJSON = certConfigResp.SslCertJSON
|
||||
if len(certConfigJSON) == 0 {
|
||||
this.NotFound("cert", params.CertId)
|
||||
return
|
||||
}
|
||||
|
||||
certConfig := &sslconfigs.SSLCertConfig{}
|
||||
var certConfig = &sslconfigs.SSLCertConfig{}
|
||||
err = json.Unmarshal(certConfigJSON, certConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -99,7 +99,6 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if params.CertFile != nil {
|
||||
certConfig.CertData, err = params.CertFile.Read()
|
||||
if err != nil {
|
||||
@@ -132,6 +131,13 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
this.Fail("证书格式错误:无法读取到证书有效期")
|
||||
}
|
||||
|
||||
if certConfig.TimeBeginAt < 0 {
|
||||
this.Fail("证书校验错误:有效期开始时间过小,不能小于1970年1月1日")
|
||||
}
|
||||
if certConfig.TimeEndAt < 0 {
|
||||
this.Fail("证书校验错误:有效期结束时间过小,不能小于1970年1月1日")
|
||||
}
|
||||
|
||||
// 保存
|
||||
_, err = this.RPC().SSLCertRPC().UpdateSSLCert(this.AdminContext(), &pb.UpdateSSLCertRequest{
|
||||
SslCertId: params.CertId,
|
||||
|
||||
@@ -41,8 +41,8 @@ func (this *UploadPopupAction) RunPost(params struct {
|
||||
Field("name", params.Name).
|
||||
Require("请输入证书说明")
|
||||
|
||||
certData := []byte{}
|
||||
keyData := []byte{}
|
||||
var certData = []byte{}
|
||||
var keyData = []byte{}
|
||||
|
||||
if params.TextMode {
|
||||
if len(params.CertText) == 0 {
|
||||
@@ -80,12 +80,12 @@ func (this *UploadPopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 校验
|
||||
sslConfig := &sslconfigs.SSLCertConfig{
|
||||
var certConfig = &sslconfigs.SSLCertConfig{
|
||||
IsCA: params.IsCA,
|
||||
CertData: certData,
|
||||
KeyData: keyData,
|
||||
}
|
||||
err := sslConfig.Init()
|
||||
err := certConfig.Init()
|
||||
if err != nil {
|
||||
if params.IsCA {
|
||||
this.Fail("证书校验错误:" + err.Error())
|
||||
@@ -93,10 +93,17 @@ func (this *UploadPopupAction) RunPost(params struct {
|
||||
this.Fail("证书或密钥校验错误:" + err.Error())
|
||||
}
|
||||
}
|
||||
if len(timeutil.Format("Y", sslConfig.TimeEnd())) != 4 {
|
||||
if len(timeutil.Format("Y", certConfig.TimeEnd())) != 4 {
|
||||
this.Fail("证书格式错误:无法读取到证书有效期")
|
||||
}
|
||||
|
||||
if certConfig.TimeBeginAt < 0 {
|
||||
this.Fail("证书校验错误:有效期开始时间过小,不能小于1970年1月1日")
|
||||
}
|
||||
if certConfig.TimeEndAt < 0 {
|
||||
this.Fail("证书校验错误:有效期结束时间过小,不能小于1970年1月1日")
|
||||
}
|
||||
|
||||
// 保存
|
||||
createResp, err := this.RPC().SSLCertRPC().CreateSSLCert(this.AdminContext(), &pb.CreateSSLCertRequest{
|
||||
IsOn: params.IsOn,
|
||||
@@ -106,10 +113,10 @@ func (this *UploadPopupAction) RunPost(params struct {
|
||||
IsCA: params.IsCA,
|
||||
CertData: certData,
|
||||
KeyData: keyData,
|
||||
TimeBeginAt: sslConfig.TimeBeginAt,
|
||||
TimeEndAt: sslConfig.TimeEndAt,
|
||||
DnsNames: sslConfig.DNSNames,
|
||||
CommonNames: sslConfig.CommonNames,
|
||||
TimeBeginAt: certConfig.TimeBeginAt,
|
||||
TimeEndAt: certConfig.TimeEndAt,
|
||||
DnsNames: certConfig.DNSNames,
|
||||
CommonNames: certConfig.CommonNames,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -117,13 +124,13 @@ func (this *UploadPopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 查询已创建的证书并返回,方便调用者进行后续处理
|
||||
certId := createResp.SslCertId
|
||||
var certId = createResp.SslCertId
|
||||
configResp, err := this.RPC().SSLCertRPC().FindEnabledSSLCertConfig(this.AdminContext(), &pb.FindEnabledSSLCertConfigRequest{SslCertId: certId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
certConfig := &sslconfigs.SSLCertConfig{}
|
||||
certConfig = &sslconfigs.SSLCertConfig{}
|
||||
err = json.Unmarshal(configResp.SslCertJSON, certConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -32,6 +32,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
FileDir string
|
||||
FileMemoryCapacityJSON []byte
|
||||
FileOpenFileCacheMax int
|
||||
FileEnableSendfile bool
|
||||
|
||||
CapacityJSON []byte
|
||||
MaxSizeJSON []byte
|
||||
@@ -77,7 +78,8 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
MemoryPolicy: &serverconfigs.HTTPCachePolicy{
|
||||
Capacity: memoryCapacity,
|
||||
},
|
||||
OpenFileCache: openFileCacheConfig,
|
||||
OpenFileCache: openFileCacheConfig,
|
||||
EnableSendfile: params.FileEnableSendfile,
|
||||
}
|
||||
case serverconfigs.CachePolicyStorageMemory:
|
||||
options = &serverconfigs.HTTPMemoryCacheStorage{}
|
||||
|
||||
@@ -26,13 +26,13 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
configJSON := configResp.HttpCachePolicyJSON
|
||||
var configJSON = configResp.HttpCachePolicyJSON
|
||||
if len(configJSON) == 0 {
|
||||
this.NotFound("cachePolicy", params.CachePolicyId)
|
||||
return
|
||||
}
|
||||
|
||||
cachePolicy := &serverconfigs.HTTPCachePolicy{}
|
||||
var cachePolicy = &serverconfigs.HTTPCachePolicy{}
|
||||
err = json.Unmarshal(configJSON, cachePolicy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -56,6 +56,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
FileDir string
|
||||
FileMemoryCapacityJSON []byte
|
||||
FileOpenFileCacheMax int
|
||||
FileEnableSendfile bool
|
||||
|
||||
CapacityJSON []byte
|
||||
MaxSizeJSON []byte
|
||||
@@ -106,7 +107,8 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
MemoryPolicy: &serverconfigs.HTTPCachePolicy{
|
||||
Capacity: memoryCapacity,
|
||||
},
|
||||
OpenFileCache: openFileCacheConfig,
|
||||
OpenFileCache: openFileCacheConfig,
|
||||
EnableSendfile: params.FileEnableSendfile,
|
||||
}
|
||||
case serverconfigs.CachePolicyStorageMemory:
|
||||
options = &serverconfigs.HTTPMemoryCacheStorage{}
|
||||
|
||||
@@ -25,6 +25,7 @@ func (this *LogAction) RunGet(params struct {
|
||||
RequestId string
|
||||
FirewallPolicyId int64
|
||||
GroupId int64
|
||||
Partition int32 `default:"-1"`
|
||||
}) {
|
||||
if len(params.Day) == 0 {
|
||||
params.Day = timeutil.Format("Y-m-d")
|
||||
@@ -33,15 +34,18 @@ func (this *LogAction) RunGet(params struct {
|
||||
this.Data["path"] = this.Request.URL.Path
|
||||
this.Data["day"] = params.Day
|
||||
this.Data["groupId"] = params.GroupId
|
||||
this.Data["accessLogs"] = []interface{}{}
|
||||
this.Data["accessLogs"] = []maps.Map{}
|
||||
this.Data["partition"] = params.Partition
|
||||
|
||||
day := params.Day
|
||||
ipList := []string{}
|
||||
var day = params.Day
|
||||
var ipList = []string{}
|
||||
var wafMaps = []maps.Map{}
|
||||
if len(day) > 0 && regexp.MustCompile(`\d{4}-\d{2}-\d{2}`).MatchString(day) {
|
||||
day = strings.ReplaceAll(day, "-", "")
|
||||
size := int64(10)
|
||||
var size = int64(20)
|
||||
|
||||
resp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
FirewallPolicyId: params.FirewallPolicyId,
|
||||
FirewallRuleGroupId: params.GroupId,
|
||||
@@ -58,11 +62,31 @@ func (this *LogAction) RunGet(params struct {
|
||||
} else {
|
||||
this.Data["accessLogs"] = resp.HttpAccessLogs
|
||||
for _, accessLog := range resp.HttpAccessLogs {
|
||||
// IP
|
||||
if len(accessLog.RemoteAddr) > 0 {
|
||||
if !lists.ContainsString(ipList, accessLog.RemoteAddr) {
|
||||
ipList = append(ipList, accessLog.RemoteAddr)
|
||||
}
|
||||
}
|
||||
|
||||
// WAF信息集合
|
||||
if accessLog.FirewallPolicyId > 0 && accessLog.FirewallRuleGroupId > 0 && accessLog.FirewallRuleSetId > 0 {
|
||||
// 检查Set是否已经存在
|
||||
var existSet = false
|
||||
for _, wafMap := range wafMaps {
|
||||
if wafMap.GetInt64("setId") == accessLog.FirewallRuleSetId {
|
||||
existSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !existSet {
|
||||
wafMaps = append(wafMaps, maps.Map{
|
||||
"policyId": accessLog.FirewallPolicyId,
|
||||
"groupId": accessLog.FirewallRuleGroupId,
|
||||
"setId": accessLog.FirewallRuleSetId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["hasMore"] = resp.HasMore
|
||||
@@ -74,6 +98,7 @@ func (this *LogAction) RunGet(params struct {
|
||||
if len(params.RequestId) > 0 {
|
||||
this.Data["hasPrev"] = true
|
||||
prevResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
FirewallPolicyId: params.FirewallPolicyId,
|
||||
FirewallRuleGroupId: params.GroupId,
|
||||
@@ -131,5 +156,79 @@ func (this *LogAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["regions"] = regionMap
|
||||
|
||||
// WAF相关
|
||||
var wafInfos = map[int64]maps.Map{} // set id => WAF Map
|
||||
var wafPolicyCacheMap = map[int64]*pb.HTTPFirewallPolicy{} // id => *pb.HTTPFirewallPolicy
|
||||
var wafGroupCacheMap = map[int64]*pb.HTTPFirewallRuleGroup{} // id => *pb.HTTPFirewallRuleGroup
|
||||
var wafSetCacheMap = map[int64]*pb.HTTPFirewallRuleSet{} // id => *pb.HTTPFirewallRuleSet
|
||||
for _, wafMap := range wafMaps {
|
||||
var policyId = wafMap.GetInt64("policyId")
|
||||
var groupId = wafMap.GetInt64("groupId")
|
||||
var setId = wafMap.GetInt64("setId")
|
||||
if policyId > 0 {
|
||||
pbPolicy, ok := wafPolicyCacheMap[policyId]
|
||||
if !ok {
|
||||
policyResp, err := this.RPC().HTTPFirewallPolicyRPC().FindEnabledHTTPFirewallPolicy(this.AdminContext(), &pb.FindEnabledHTTPFirewallPolicyRequest{HttpFirewallPolicyId: policyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbPolicy = policyResp.HttpFirewallPolicy
|
||||
wafPolicyCacheMap[policyId] = pbPolicy
|
||||
}
|
||||
if pbPolicy != nil {
|
||||
wafMap = maps.Map{
|
||||
"policy": maps.Map{
|
||||
"id": pbPolicy.Id,
|
||||
"name": pbPolicy.Name,
|
||||
"serverId": pbPolicy.ServerId,
|
||||
},
|
||||
}
|
||||
if groupId > 0 {
|
||||
pbGroup, ok := wafGroupCacheMap[groupId]
|
||||
if !ok {
|
||||
groupResp, err := this.RPC().HTTPFirewallRuleGroupRPC().FindEnabledHTTPFirewallRuleGroup(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleGroupRequest{FirewallRuleGroupId: groupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbGroup = groupResp.FirewallRuleGroup
|
||||
wafGroupCacheMap[groupId] = pbGroup
|
||||
}
|
||||
|
||||
if pbGroup != nil {
|
||||
wafMap["group"] = maps.Map{
|
||||
"id": pbGroup.Id,
|
||||
"name": pbGroup.Name,
|
||||
}
|
||||
|
||||
if setId > 0 {
|
||||
pbSet, ok := wafSetCacheMap[setId]
|
||||
if !ok {
|
||||
setResp, err := this.RPC().HTTPFirewallRuleSetRPC().FindEnabledHTTPFirewallRuleSet(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleSetRequest{FirewallRuleSetId: setId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbSet = setResp.FirewallRuleSet
|
||||
wafSetCacheMap[setId] = pbSet
|
||||
}
|
||||
|
||||
if pbSet != nil {
|
||||
wafMap["set"] = maps.Map{
|
||||
"id": pbSet.Id,
|
||||
"name": pbSet.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wafInfos[setId] = wafMap
|
||||
}
|
||||
this.Data["wafInfos"] = wafInfos
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ func (this *PolicyAction) RunGet(params struct {
|
||||
"blockOptions": firewallPolicy.BlockOptions,
|
||||
"useLocalFirewall": firewallPolicy.UseLocalFirewall,
|
||||
"synFlood": firewallPolicy.SYNFlood,
|
||||
"log": firewallPolicy.Log,
|
||||
}
|
||||
|
||||
// 正在使用此策略的集群
|
||||
|
||||
@@ -58,6 +58,11 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
// log
|
||||
if firewallPolicy.Log == nil {
|
||||
firewallPolicy.Log = firewallconfigs.DefaultHTTPFirewallPolicyLogConfig
|
||||
}
|
||||
|
||||
this.Data["firewallPolicy"] = maps.Map{
|
||||
"id": firewallPolicy.Id,
|
||||
"name": firewallPolicy.Name,
|
||||
@@ -67,10 +72,11 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
"blockOptions": firewallPolicy.BlockOptions,
|
||||
"useLocalFirewall": firewallPolicy.UseLocalFirewall,
|
||||
"synFloodConfig": firewallPolicy.SYNFlood,
|
||||
"log": firewallPolicy.Log,
|
||||
}
|
||||
|
||||
// 预置分组
|
||||
groups := []maps.Map{}
|
||||
var groups = []maps.Map{}
|
||||
templatePolicy := firewallconfigs.HTTPFirewallTemplate()
|
||||
for _, group := range templatePolicy.AllRuleGroups() {
|
||||
if len(group.Code) > 0 {
|
||||
@@ -101,6 +107,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
Mode string
|
||||
UseLocalFirewall bool
|
||||
SynFloodJSON []byte
|
||||
LogJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -128,6 +135,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
Mode: params.Mode,
|
||||
UseLocalFirewall: params.UseLocalFirewall,
|
||||
SynFloodJSON: params.SynFloodJSON,
|
||||
LogJSON: params.LogJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -299,16 +299,19 @@ func (this *CreateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 源站地址
|
||||
reverseProxyRefJSON := []byte{}
|
||||
var reverseProxyRefJSON = []byte{}
|
||||
switch params.ServerType {
|
||||
case serverconfigs.ServerTypeHTTPProxy, serverconfigs.ServerTypeTCPProxy, serverconfigs.ServerTypeUDPProxy:
|
||||
originConfigs := []*serverconfigs.OriginConfig{}
|
||||
var originConfigs = []*serverconfigs.OriginConfig{}
|
||||
err := json.Unmarshal([]byte(params.Origins), &originConfigs)
|
||||
if err != nil {
|
||||
this.Fail("源站地址解析失败:" + err.Error())
|
||||
}
|
||||
if len(originConfigs) == 0 {
|
||||
this.Fail("请添加至少一个源站地址")
|
||||
}
|
||||
|
||||
originRefs := []*serverconfigs.OriginRef{}
|
||||
var originRefs = []*serverconfigs.OriginRef{}
|
||||
for _, originConfig := range originConfigs {
|
||||
if originConfig.Id > 0 {
|
||||
originRefs = append(originRefs, &serverconfigs.OriginRef{
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package servergrouputils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
func filterMenuItems(leftMenuItems []maps.Map, groupId int64, urlPrefix string, menuItem string, configInfoResp *pb.FindEnabledServerGroupConfigInfoResponse) []maps.Map {
|
||||
return leftMenuItems
|
||||
}
|
||||
|
||||
func filterMenuItems2(leftMenuItems []maps.Map, groupId int64, urlPrefix string, menuItem string, configInfoResp *pb.FindEnabledServerGroupConfigInfoResponse) []maps.Map {
|
||||
return leftMenuItems
|
||||
}
|
||||
@@ -4,7 +4,6 @@ package servergrouputils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
@@ -57,82 +56,7 @@ func InitGroup(parent *actionutils.ParentAction, groupId int64, menuItem string)
|
||||
},
|
||||
}
|
||||
|
||||
if teaconst.IsPlus {
|
||||
leftMenuItems = append([]maps.Map{
|
||||
{
|
||||
"name": "Web设置",
|
||||
"url": urlPrefix + "/web?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "web",
|
||||
"isOn": configInfoResp.HasRootConfig,
|
||||
},
|
||||
}, leftMenuItems...)
|
||||
leftMenuItems = append(leftMenuItems, []maps.Map{
|
||||
{
|
||||
"name": "-",
|
||||
"url": "",
|
||||
},
|
||||
{
|
||||
"name": "WAF",
|
||||
"url": urlPrefix + "/waf?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "waf",
|
||||
"isOn": configInfoResp.HasWAFConfig,
|
||||
},
|
||||
{
|
||||
"name": "缓存",
|
||||
"url": urlPrefix + "//cache?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "cache",
|
||||
"isOn": configInfoResp.HasCacheConfig,
|
||||
},
|
||||
{
|
||||
"name": "字符编码",
|
||||
"url": urlPrefix + "/charset?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "charset",
|
||||
"isOn": configInfoResp.HasCharsetConfig,
|
||||
},
|
||||
{
|
||||
"name": "访问日志",
|
||||
"url": urlPrefix + "/accessLog?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "accessLog",
|
||||
"isOn": configInfoResp.HasAccessLogConfig,
|
||||
},
|
||||
{
|
||||
"name": "统计",
|
||||
"url": urlPrefix + "/stat?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "stat",
|
||||
"isOn": configInfoResp.HasStatConfig,
|
||||
},
|
||||
{
|
||||
"name": "内容压缩",
|
||||
"url": urlPrefix + "/compression?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "compression",
|
||||
"isOn": configInfoResp.HasCompressionConfig,
|
||||
},
|
||||
{
|
||||
"name": "特殊页面",
|
||||
"url": urlPrefix + "/pages?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "pages",
|
||||
"isOn": configInfoResp.HasPagesConfig,
|
||||
},
|
||||
{
|
||||
"name": "HTTP Header",
|
||||
"url": urlPrefix + "/headers?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "headers",
|
||||
"isOn": configInfoResp.HasRequestHeadersConfig || configInfoResp.HasResponseHeadersConfig,
|
||||
},
|
||||
{
|
||||
"name": "Websocket",
|
||||
"url": urlPrefix + "/websocket?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "websocket",
|
||||
"isOn": configInfoResp.HasWebsocketConfig,
|
||||
},
|
||||
{
|
||||
"name": "WebP",
|
||||
"url": urlPrefix + "/webp?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "webp",
|
||||
"isOn": configInfoResp.HasWebPConfig,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
leftMenuItems = filterMenuItems(leftMenuItems, groupId, urlPrefix, menuItem, configInfoResp)
|
||||
|
||||
leftMenuItems = append(leftMenuItems, maps.Map{
|
||||
"name": "-",
|
||||
@@ -145,14 +69,8 @@ func InitGroup(parent *actionutils.ParentAction, groupId int64, menuItem string)
|
||||
"isOn": configInfoResp.HasRemoteAddrConfig,
|
||||
})
|
||||
|
||||
if teaconst.IsPlus {
|
||||
leftMenuItems = append(leftMenuItems, maps.Map{
|
||||
"name": "请求限制",
|
||||
"url": urlPrefix + "/requestLimit?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "requestLimit",
|
||||
"isOn": configInfoResp.HasRequestLimitConfig,
|
||||
})
|
||||
}
|
||||
leftMenuItems = filterMenuItems2(leftMenuItems, groupId, urlPrefix, menuItem, configInfoResp)
|
||||
|
||||
parent.Data["leftMenuItems"] = leftMenuItems
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package servers
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
@@ -26,12 +27,15 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Keyword string
|
||||
AuditingFlag int32
|
||||
CheckDNS bool
|
||||
|
||||
TrafficOutOrder string
|
||||
}) {
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
this.Data["groupId"] = params.GroupId
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["auditingFlag"] = params.AuditingFlag
|
||||
this.Data["checkDNS"] = params.CheckDNS
|
||||
this.Data["hasOrder"] = len(params.TrafficOutOrder) > 0
|
||||
|
||||
isSearching := params.AuditingFlag == 1 || params.ClusterId > 0 || params.GroupId > 0 || len(params.Keyword) > 0
|
||||
|
||||
@@ -83,12 +87,14 @@ func (this *IndexAction) RunGet(params struct {
|
||||
|
||||
// 服务列表
|
||||
serversResp, err := this.RPC().ServerRPC().ListEnabledServersMatch(this.AdminContext(), &pb.ListEnabledServersMatchRequest{
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
NodeClusterId: params.ClusterId,
|
||||
ServerGroupId: params.GroupId,
|
||||
Keyword: params.Keyword,
|
||||
AuditingFlag: params.AuditingFlag,
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
NodeClusterId: params.ClusterId,
|
||||
ServerGroupId: params.GroupId,
|
||||
Keyword: params.Keyword,
|
||||
AuditingFlag: params.AuditingFlag,
|
||||
TrafficOutDesc: params.TrafficOutOrder == "desc",
|
||||
TrafficOutAsc: params.TrafficOutOrder == "asc",
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -205,6 +211,15 @@ func (this *IndexAction) RunGet(params struct {
|
||||
auditingTime = timeutil.FormatTime("Y-m-d", server.AuditingAt)
|
||||
}
|
||||
|
||||
// 统计数据
|
||||
var bandwidth = ""
|
||||
if server.LatestServerDailyStat != nil {
|
||||
var bytesPerSecond = server.LatestServerDailyStat.Bytes / 300
|
||||
if bytesPerSecond > 0 {
|
||||
bandwidth = numberutils.FormatBytes(bytesPerSecond)
|
||||
}
|
||||
}
|
||||
|
||||
serverMaps = append(serverMaps, maps.Map{
|
||||
"id": server.Id,
|
||||
"isOn": server.IsOn,
|
||||
@@ -222,6 +237,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"auditingIsOk": auditingIsOk,
|
||||
"user": userMap,
|
||||
"auditingTime": auditingTime,
|
||||
"bandwidth": bandwidth,
|
||||
})
|
||||
}
|
||||
this.Data["servers"] = serverMaps
|
||||
@@ -260,72 +276,17 @@ func (this *IndexAction) RunGet(params struct {
|
||||
// 是否有用户管理权限
|
||||
this.Data["canVisitUser"] = configloaders.AllowModule(this.AdminId(), configloaders.AdminModuleCodeUser)
|
||||
|
||||
// 显示服务相关的日志
|
||||
errorLogsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
|
||||
NodeId: 0,
|
||||
// 显示服务需要修复的日志数量
|
||||
countNeedFixLogsResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Offset: 0,
|
||||
Size: 20,
|
||||
Level: "error,success,warning",
|
||||
FixedState: int32(configutils.BoolStateNo),
|
||||
AllServers: true,
|
||||
FixedState: int32(configutils.BoolStateNo),
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
errorLogMaps := []maps.Map{}
|
||||
for _, errorLog := range errorLogsResp.NodeLogs {
|
||||
serverResp, err := this.RPC().ServerRPC().FindEnabledUserServerBasic(this.AdminContext(), &pb.FindEnabledUserServerBasicRequest{ServerId: errorLog.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 服务
|
||||
var server = serverResp.Server
|
||||
if server == nil {
|
||||
// 设置为已修复
|
||||
_, err = this.RPC().NodeLogRPC().FixNodeLogs(this.AdminContext(), &pb.FixNodeLogsRequest{NodeLogIds: []int64{errorLog.Id}})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// 节点
|
||||
nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: errorLog.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var node = nodeResp.Node
|
||||
if node == nil || node.NodeCluster == nil {
|
||||
// 设置为已修复
|
||||
_, err = this.RPC().NodeLogRPC().FixNodeLogs(this.AdminContext(), &pb.FixNodeLogsRequest{NodeLogIds: []int64{errorLog.Id}})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
errorLogMaps = append(errorLogMaps, maps.Map{
|
||||
"id": errorLog.Id,
|
||||
"description": errorLog.Description,
|
||||
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", errorLog.CreatedAt),
|
||||
"serverId": errorLog.ServerId,
|
||||
"level": errorLog.Level,
|
||||
"serverName": server.Name,
|
||||
"nodeId": node.Id,
|
||||
"nodeName": node.Name,
|
||||
"clusterId": node.NodeCluster.Id,
|
||||
})
|
||||
}
|
||||
this.Data["errorLogs"] = errorLogMaps
|
||||
this.Data["countNeedFixLogs"] = countNeedFixLogsResp.Count
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ func init() {
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/create", new(CreateAction)).
|
||||
GetPost("/update", new(UpdateAction)).
|
||||
Post("/fixLog", new(FixLogAction)).
|
||||
Post("/nearby", new(NearbyAction)).
|
||||
|
||||
//
|
||||
|
||||
@@ -102,34 +102,38 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["publicBlackIPLists"] = publicBlackIPListMaps
|
||||
|
||||
// 访问日志
|
||||
accessLogsResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Day: timeutil.Format("Ymd"),
|
||||
Ip: params.Ip,
|
||||
Size: 20,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var accessLogs = accessLogsResp.HttpAccessLogs
|
||||
if len(accessLogs) == 0 {
|
||||
// 查询昨天
|
||||
accessLogsResp, err = this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Day: timeutil.Format("Ymd", time.Now().AddDate(0, 0, -1)),
|
||||
Ip: params.Ip,
|
||||
Size: 20,
|
||||
})
|
||||
var hasAccessLogs = false
|
||||
Loop:
|
||||
for _, day := range []string{timeutil.Format("Ymd"), timeutil.Format("Ymd", time.Now().AddDate(0, 0, -1))} {
|
||||
partitionsResp, err := this.RPC().HTTPAccessLogRPC().FindHTTPAccessLogPartitions(this.AdminContext(), &pb.FindHTTPAccessLogPartitionsRequest{Day: day})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
accessLogs = accessLogsResp.HttpAccessLogs
|
||||
for _, partition := range partitionsResp.ReversePartitions {
|
||||
accessLogsResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: partition,
|
||||
Day: day,
|
||||
Ip: params.Ip,
|
||||
Size: 20,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(accessLogs) == 0 {
|
||||
accessLogs = []*pb.HTTPAccessLog{}
|
||||
var accessLogs = accessLogsResp.HttpAccessLogs
|
||||
if len(accessLogs) > 0 {
|
||||
this.Data["accessLogs"] = accessLogs
|
||||
hasAccessLogs = true
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["accessLogs"] = accessLogs
|
||||
|
||||
if !hasAccessLogs {
|
||||
this.Data["accessLogs"] = []interface{}{}
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -29,23 +29,42 @@ func (this *AccessLogsPopupAction) RunGet(params struct {
|
||||
this.NotFound("ipItem", params.ItemId)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["ipFrom"] = item.IpFrom
|
||||
this.Data["ipTo"] = item.IpTo
|
||||
|
||||
accessLogsResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Day: timeutil.Format("Ymd"),
|
||||
Keyword: "ip:" + item.IpFrom + "," + item.IpTo,
|
||||
Size: 10,
|
||||
})
|
||||
// 多找几个Partition
|
||||
var day = timeutil.FormatTime("Ymd", item.CreatedAt)
|
||||
partitionsResp, err := this.RPC().HTTPAccessLogRPC().FindHTTPAccessLogPartitions(this.AdminContext(), &pb.FindHTTPAccessLogPartitionsRequest{Day: day})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var accessLogs = accessLogsResp.HttpAccessLogs
|
||||
if len(accessLogs) == 0 {
|
||||
accessLogs = []*pb.HTTPAccessLog{}
|
||||
|
||||
var hasAccessLogs = false
|
||||
|
||||
for _, partition := range partitionsResp.ReversePartitions {
|
||||
accessLogsResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: partition,
|
||||
Day: day,
|
||||
Keyword: "ip:" + item.IpFrom + "," + item.IpTo,
|
||||
Size: 20,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var accessLogs = accessLogsResp.HttpAccessLogs
|
||||
if len(accessLogs) > 0 {
|
||||
this.Data["accessLogs"] = accessLogs
|
||||
hasAccessLogs = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !hasAccessLogs {
|
||||
this.Data["accessLogs"] = []interface{}{}
|
||||
}
|
||||
this.Data["accessLogs"] = accessLogs
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -23,16 +23,22 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Ip string
|
||||
GlobalOnly bool
|
||||
Unread bool
|
||||
EventLevel string
|
||||
ListType string
|
||||
}) {
|
||||
this.Data["type"] = ""
|
||||
this.Data["ip"] = params.Ip
|
||||
this.Data["globalOnly"] = params.GlobalOnly
|
||||
this.Data["unread"] = params.Unread
|
||||
this.Data["eventLevel"] = params.EventLevel
|
||||
this.Data["listType"] = params.ListType
|
||||
|
||||
countUnreadResp, err := this.RPC().IPItemRPC().CountAllEnabledIPItems(this.AdminContext(), &pb.CountAllEnabledIPItemsRequest{
|
||||
Ip: params.Ip,
|
||||
GlobalOnly: params.GlobalOnly,
|
||||
Unread: true,
|
||||
EventLevel: params.EventLevel,
|
||||
ListType: params.ListType,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -44,6 +50,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Ip: params.Ip,
|
||||
GlobalOnly: params.GlobalOnly,
|
||||
Unread: params.Unread,
|
||||
EventLevel: params.EventLevel,
|
||||
ListType: params.ListType,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -57,6 +65,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Ip: params.Ip,
|
||||
GlobalOnly: params.GlobalOnly,
|
||||
Unread: params.Unread,
|
||||
EventLevel: params.EventLevel,
|
||||
ListType: params.ListType,
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
})
|
||||
@@ -143,6 +153,22 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
// 区域 & ISP
|
||||
var region = ""
|
||||
var isp = ""
|
||||
if len(item.IpFrom) > 0 && len(item.IpTo) == 0 {
|
||||
regionResp, err := this.RPC().IPLibraryRPC().LookupIPRegion(this.AdminContext(), &pb.LookupIPRegionRequest{Ip: item.IpFrom})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var ipRegion = regionResp.IpRegion
|
||||
if ipRegion != nil {
|
||||
region = ipRegion.Summary
|
||||
isp = ipRegion.Isp
|
||||
}
|
||||
}
|
||||
|
||||
itemMaps = append(itemMaps, maps.Map{
|
||||
"id": item.Id,
|
||||
"ipFrom": item.IpFrom,
|
||||
@@ -162,9 +188,14 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"sourceNode": sourceNodeMap,
|
||||
"list": listMap,
|
||||
"policy": policyMap,
|
||||
"region": region,
|
||||
"isp": isp,
|
||||
})
|
||||
}
|
||||
this.Data["items"] = itemMaps
|
||||
|
||||
// 所有级别
|
||||
this.Data["eventLevels"] = firewallconfigs.FindAllFirewallEventLevels()
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -20,10 +20,12 @@ func (this *ItemsAction) Init() {
|
||||
}
|
||||
|
||||
func (this *ItemsAction) RunGet(params struct {
|
||||
ListId int64
|
||||
Keyword string
|
||||
ListId int64
|
||||
Keyword string
|
||||
EventLevel string
|
||||
}) {
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["eventLevel"] = params.EventLevel
|
||||
|
||||
err := InitIPList(this.Parent(), params.ListId)
|
||||
if err != nil {
|
||||
@@ -34,8 +36,9 @@ func (this *ItemsAction) RunGet(params struct {
|
||||
// 数量
|
||||
var listId = params.ListId
|
||||
countResp, err := this.RPC().IPItemRPC().CountIPItemsWithListId(this.AdminContext(), &pb.CountIPItemsWithListIdRequest{
|
||||
IpListId: listId,
|
||||
Keyword: params.Keyword,
|
||||
IpListId: listId,
|
||||
Keyword: params.Keyword,
|
||||
EventLevel: params.EventLevel,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -47,10 +50,11 @@ func (this *ItemsAction) RunGet(params struct {
|
||||
|
||||
// 列表
|
||||
itemsResp, err := this.RPC().IPItemRPC().ListIPItemsWithListId(this.AdminContext(), &pb.ListIPItemsWithListIdRequest{
|
||||
IpListId: listId,
|
||||
Keyword: params.Keyword,
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
IpListId: listId,
|
||||
Keyword: params.Keyword,
|
||||
EventLevel: params.EventLevel,
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -100,6 +104,22 @@ func (this *ItemsAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
// 区域 & ISP
|
||||
var region = ""
|
||||
var isp = ""
|
||||
if len(item.IpFrom) > 0 && len(item.IpTo) == 0 {
|
||||
regionResp, err := this.RPC().IPLibraryRPC().LookupIPRegion(this.AdminContext(), &pb.LookupIPRegionRequest{Ip: item.IpFrom})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var ipRegion = regionResp.IpRegion
|
||||
if ipRegion != nil {
|
||||
region = ipRegion.Summary
|
||||
isp = ipRegion.Isp
|
||||
}
|
||||
}
|
||||
|
||||
itemMaps = append(itemMaps, maps.Map{
|
||||
"id": item.Id,
|
||||
"ipFrom": item.IpFrom,
|
||||
@@ -114,9 +134,14 @@ func (this *ItemsAction) RunGet(params struct {
|
||||
"sourceSet": sourceSetMap,
|
||||
"sourceServer": sourceServerMap,
|
||||
"lifeSeconds": item.ExpiredAt - time.Now().Unix(),
|
||||
"region": region,
|
||||
"isp": isp,
|
||||
})
|
||||
}
|
||||
this.Data["items"] = itemMaps
|
||||
|
||||
// 所有级别
|
||||
this.Data["eventLevels"] = firewallconfigs.FindAllFirewallEventLevels()
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
55
internal/web/actions/default/servers/logs/checkLog.go
Normal file
55
internal/web/actions/default/servers/logs/checkLog.go
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// CheckLogAction 检查是否有日志
|
||||
type CheckLogAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *CheckLogAction) RunPost(params struct {
|
||||
Day string
|
||||
Partition int32
|
||||
|
||||
ServerId int64
|
||||
RequestId string
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
HasError bool
|
||||
HasFirewallPolicy bool
|
||||
Keyword string
|
||||
Ip string
|
||||
Domain string
|
||||
|
||||
Hour string
|
||||
}) {
|
||||
resp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeId: params.NodeId,
|
||||
ServerId: params.ServerId,
|
||||
HasError: params.HasError,
|
||||
HasFirewallPolicy: params.HasFirewallPolicy,
|
||||
Day: params.Day,
|
||||
HourFrom: params.Hour,
|
||||
HourTo: params.Hour,
|
||||
Keyword: params.Keyword,
|
||||
Ip: params.Ip,
|
||||
Domain: params.Domain,
|
||||
Size: 1,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["hasLogs"] = len(resp.HttpAccessLogs) > 0
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -31,6 +32,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Domain string
|
||||
HasError int
|
||||
HasWAF int
|
||||
Partition int32 `default:"-1"`
|
||||
|
||||
RequestId string
|
||||
ServerId int64
|
||||
@@ -56,9 +58,11 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["pageSize"] = params.PageSize
|
||||
this.Data["isSlowQuery"] = false
|
||||
this.Data["slowQueryCost"] = ""
|
||||
this.Data["partition"] = params.Partition
|
||||
|
||||
day := params.Day
|
||||
ipList := []string{}
|
||||
var day = params.Day
|
||||
var ipList = []string{}
|
||||
var wafMaps = []maps.Map{}
|
||||
|
||||
if len(day) > 0 && regexp.MustCompile(`\d{4}-\d{2}-\d{2}`).MatchString(day) {
|
||||
day = strings.ReplaceAll(day, "-", "")
|
||||
@@ -71,6 +75,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
|
||||
var before = time.Now()
|
||||
resp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeId: params.NodeId,
|
||||
@@ -101,11 +106,31 @@ func (this *IndexAction) RunGet(params struct {
|
||||
} else {
|
||||
this.Data["accessLogs"] = resp.HttpAccessLogs
|
||||
for _, accessLog := range resp.HttpAccessLogs {
|
||||
// IP信息集合
|
||||
if len(accessLog.RemoteAddr) > 0 {
|
||||
if !lists.ContainsString(ipList, accessLog.RemoteAddr) {
|
||||
ipList = append(ipList, accessLog.RemoteAddr)
|
||||
}
|
||||
}
|
||||
|
||||
// WAF信息集合
|
||||
if accessLog.FirewallPolicyId > 0 && accessLog.FirewallRuleGroupId > 0 && accessLog.FirewallRuleSetId > 0 {
|
||||
// 检查Set是否已经存在
|
||||
var existSet = false
|
||||
for _, wafMap := range wafMaps {
|
||||
if wafMap.GetInt64("setId") == accessLog.FirewallRuleSetId {
|
||||
existSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !existSet {
|
||||
wafMaps = append(wafMaps, maps.Map{
|
||||
"policyId": accessLog.FirewallPolicyId,
|
||||
"groupId": accessLog.FirewallRuleGroupId,
|
||||
"setId": accessLog.FirewallRuleSetId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["hasMore"] = resp.HasMore
|
||||
@@ -117,6 +142,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
if len(params.RequestId) > 0 {
|
||||
this.Data["hasPrev"] = true
|
||||
prevResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeId: params.NodeId,
|
||||
@@ -143,7 +169,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 根据IP查询区域
|
||||
regionMap := map[string]string{} // ip => region
|
||||
var regionMap = map[string]string{} // ip => region
|
||||
if len(ipList) > 0 {
|
||||
resp, err := this.RPC().IPLibraryRPC().LookupIPRegions(this.AdminContext(), &pb.LookupIPRegionsRequest{IpList: ipList})
|
||||
if err != nil {
|
||||
@@ -158,5 +184,79 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["regions"] = regionMap
|
||||
|
||||
// WAF相关
|
||||
var wafInfos = map[int64]maps.Map{} // set id => WAF Map
|
||||
var wafPolicyCacheMap = map[int64]*pb.HTTPFirewallPolicy{} // id => *pb.HTTPFirewallPolicy
|
||||
var wafGroupCacheMap = map[int64]*pb.HTTPFirewallRuleGroup{} // id => *pb.HTTPFirewallRuleGroup
|
||||
var wafSetCacheMap = map[int64]*pb.HTTPFirewallRuleSet{} // id => *pb.HTTPFirewallRuleSet
|
||||
for _, wafMap := range wafMaps {
|
||||
var policyId = wafMap.GetInt64("policyId")
|
||||
var groupId = wafMap.GetInt64("groupId")
|
||||
var setId = wafMap.GetInt64("setId")
|
||||
if policyId > 0 {
|
||||
pbPolicy, ok := wafPolicyCacheMap[policyId]
|
||||
if !ok {
|
||||
policyResp, err := this.RPC().HTTPFirewallPolicyRPC().FindEnabledHTTPFirewallPolicy(this.AdminContext(), &pb.FindEnabledHTTPFirewallPolicyRequest{HttpFirewallPolicyId: policyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbPolicy = policyResp.HttpFirewallPolicy
|
||||
wafPolicyCacheMap[policyId] = pbPolicy
|
||||
}
|
||||
if pbPolicy != nil {
|
||||
wafMap = maps.Map{
|
||||
"policy": maps.Map{
|
||||
"id": pbPolicy.Id,
|
||||
"name": pbPolicy.Name,
|
||||
"serverId": pbPolicy.ServerId,
|
||||
},
|
||||
}
|
||||
if groupId > 0 {
|
||||
pbGroup, ok := wafGroupCacheMap[groupId]
|
||||
if !ok {
|
||||
groupResp, err := this.RPC().HTTPFirewallRuleGroupRPC().FindEnabledHTTPFirewallRuleGroup(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleGroupRequest{FirewallRuleGroupId: groupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbGroup = groupResp.FirewallRuleGroup
|
||||
wafGroupCacheMap[groupId] = pbGroup
|
||||
}
|
||||
|
||||
if pbGroup != nil {
|
||||
wafMap["group"] = maps.Map{
|
||||
"id": pbGroup.Id,
|
||||
"name": pbGroup.Name,
|
||||
}
|
||||
|
||||
if setId > 0 {
|
||||
pbSet, ok := wafSetCacheMap[setId]
|
||||
if !ok {
|
||||
setResp, err := this.RPC().HTTPFirewallRuleSetRPC().FindEnabledHTTPFirewallRuleSet(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleSetRequest{FirewallRuleSetId: setId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbSet = setResp.FirewallRuleSet
|
||||
wafSetCacheMap[setId] = pbSet
|
||||
}
|
||||
|
||||
if pbSet != nil {
|
||||
wafMap["set"] = maps.Map{
|
||||
"id": pbSet.Id,
|
||||
"name": pbSet.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wafInfos[setId] = wafMap
|
||||
}
|
||||
this.Data["wafInfos"] = wafInfos
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ func init() {
|
||||
Prefix("/servers/logs").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/settings", new(SettingsAction)).
|
||||
Post("/partitionData", new(PartitionDataAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
37
internal/web/actions/default/servers/logs/partitionData.go
Normal file
37
internal/web/actions/default/servers/logs/partitionData.go
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PartitionDataAction 读取分区表
|
||||
type PartitionDataAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *PartitionDataAction) RunPost(params struct {
|
||||
Day string
|
||||
}) {
|
||||
var day = params.Day
|
||||
day = strings.ReplaceAll(day, "-", "")
|
||||
|
||||
resp, err := this.RPC().HTTPAccessLogRPC().FindHTTPAccessLogPartitions(this.AdminContext(), &pb.FindHTTPAccessLogPartitionsRequest{
|
||||
Day: day,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(resp.Partitions) > 0 {
|
||||
this.Data["partitions"] = resp.Partitions
|
||||
} else {
|
||||
this.Data["partitions"] = []int32{}
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -29,12 +29,13 @@ func (this *CreatePopupAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) RunPost(params struct {
|
||||
Name string
|
||||
Category string
|
||||
KeysJSON []byte
|
||||
PeriodJSON []byte
|
||||
Value string
|
||||
IsPublic bool
|
||||
Name string
|
||||
Category string
|
||||
KeysJSON []byte
|
||||
PeriodJSON []byte
|
||||
Value string
|
||||
IsPublic bool
|
||||
ExpiresPeriod int32
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -68,15 +69,20 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
var period = periodMap.GetInt32("period")
|
||||
var periodUnit = periodMap.GetString("unit")
|
||||
|
||||
if params.ExpiresPeriod < 0 {
|
||||
params.ExpiresPeriod = 0
|
||||
}
|
||||
|
||||
createResp, err := this.RPC().MetricItemRPC().CreateMetricItem(this.AdminContext(), &pb.CreateMetricItemRequest{
|
||||
Code: "", // TODO 未来实现
|
||||
Category: params.Category,
|
||||
Name: params.Name,
|
||||
Keys: keys,
|
||||
Period: period,
|
||||
PeriodUnit: periodUnit,
|
||||
Value: params.Value,
|
||||
IsPublic: params.IsPublic,
|
||||
Code: "", // TODO 未来实现
|
||||
Category: params.Category,
|
||||
Name: params.Name,
|
||||
Keys: keys,
|
||||
Period: period,
|
||||
PeriodUnit: periodUnit,
|
||||
ExpiresPeriod: params.ExpiresPeriod,
|
||||
Value: params.Value,
|
||||
IsPublic: params.IsPublic,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -53,6 +53,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"period": item.Period,
|
||||
"periodUnit": item.PeriodUnit,
|
||||
"periodUnitName": serverconfigs.FindMetricPeriodUnitName(item.PeriodUnit),
|
||||
"expiresPeriod": item.ExpiresPeriod,
|
||||
"keys": item.Keys,
|
||||
"value": item.Value,
|
||||
"valueName": serverconfigs.FindMetricValueName(item.Category, item.Value),
|
||||
|
||||
@@ -46,6 +46,7 @@ func InitItem(parent *actionutils.ParentAction, itemId int64) (*pb.MetricItem, e
|
||||
"category": item.Category,
|
||||
"isPublic": item.IsPublic,
|
||||
"countCharts": countCharts,
|
||||
"expiresPeriod": item.ExpiresPeriod,
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
|
||||
@@ -35,13 +35,14 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
func (this *UpdateAction) RunPost(params struct {
|
||||
ItemId int64
|
||||
Name string
|
||||
KeysJSON []byte
|
||||
PeriodJSON []byte
|
||||
Value string
|
||||
IsOn bool
|
||||
IsPublic bool
|
||||
ItemId int64
|
||||
Name string
|
||||
KeysJSON []byte
|
||||
PeriodJSON []byte
|
||||
ExpiresPeriod int32
|
||||
Value string
|
||||
IsOn bool
|
||||
IsPublic bool
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -71,15 +72,20 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
var period = periodMap.GetInt32("period")
|
||||
var periodUnit = periodMap.GetString("unit")
|
||||
|
||||
if params.ExpiresPeriod < 0 {
|
||||
params.ExpiresPeriod = 0
|
||||
}
|
||||
|
||||
_, err = this.RPC().MetricItemRPC().UpdateMetricItem(this.AdminContext(), &pb.UpdateMetricItemRequest{
|
||||
MetricItemId: params.ItemId,
|
||||
Name: params.Name,
|
||||
Keys: keys,
|
||||
Period: period,
|
||||
PeriodUnit: periodUnit,
|
||||
Value: params.Value,
|
||||
IsOn: params.IsOn,
|
||||
IsPublic: params.IsPublic,
|
||||
MetricItemId: params.ItemId,
|
||||
Name: params.Name,
|
||||
Keys: keys,
|
||||
Period: period,
|
||||
PeriodUnit: periodUnit,
|
||||
Value: params.Value,
|
||||
IsOn: params.IsOn,
|
||||
IsPublic: params.IsPublic,
|
||||
ExpiresPeriod: params.ExpiresPeriod,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
package boards
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "board", "")
|
||||
this.SecondMenu("index")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
ServerId int64
|
||||
}) {
|
||||
if !teaconst.IsPlus {
|
||||
this.RedirectURL("/servers/server/stat?serverId=" + strconv.FormatInt(params.ServerId, 10))
|
||||
return
|
||||
}
|
||||
|
||||
serverResp, err := this.RPC().ServerRPC().FindEnabledServer(this.AdminContext(), &pb.FindEnabledServerRequest{ServerId: params.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var server = serverResp.Server
|
||||
if server == nil {
|
||||
this.NotFound("server", params.ServerId)
|
||||
return
|
||||
}
|
||||
this.Data["server"] = maps.Map{
|
||||
"id": server.Id,
|
||||
"name": server.Name,
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
ServerId int64
|
||||
}) {
|
||||
resp, err := this.RPC().ServerStatBoardRPC().ComposeServerStatBoard(this.AdminContext(), &pb.ComposeServerStatBoardRequest{ServerId: params.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 24小时流量趋势
|
||||
{
|
||||
var statMaps = []maps.Map{}
|
||||
for _, stat := range resp.HourlyTrafficStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"bytes": stat.Bytes,
|
||||
"cachedBytes": stat.CachedBytes,
|
||||
"countRequests": stat.CountRequests,
|
||||
"countCachedRequests": stat.CountCachedRequests,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"attackBytes": stat.AttackBytes,
|
||||
"day": stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
|
||||
"hour": stat.Hour[8:],
|
||||
})
|
||||
}
|
||||
this.Data["hourlyStats"] = statMaps
|
||||
}
|
||||
|
||||
// 15天流量趋势
|
||||
{
|
||||
var statMaps = []maps.Map{}
|
||||
for _, stat := range resp.DailyTrafficStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"bytes": stat.Bytes,
|
||||
"cachedBytes": stat.CachedBytes,
|
||||
"countRequests": stat.CountRequests,
|
||||
"countCachedRequests": stat.CountCachedRequests,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"attackBytes": stat.AttackBytes,
|
||||
"day": stat.Day[4:6] + "月" + stat.Day[6:] + "日",
|
||||
})
|
||||
}
|
||||
this.Data["dailyStats"] = statMaps
|
||||
}
|
||||
|
||||
// 节点排行
|
||||
{
|
||||
var statMaps = []maps.Map{}
|
||||
for _, stat := range resp.TopNodeStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"nodeId": stat.NodeId,
|
||||
"nodeName": stat.NodeName,
|
||||
"countRequests": stat.CountRequests,
|
||||
"bytes": stat.Bytes,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"attackBytes": stat.AttackBytes,
|
||||
})
|
||||
}
|
||||
this.Data["topNodeStats"] = statMaps
|
||||
}
|
||||
|
||||
// 域名排行
|
||||
{
|
||||
var statMaps = []maps.Map{}
|
||||
for _, stat := range resp.TopDomainStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"serverId": stat.ServerId,
|
||||
"domain": stat.Domain,
|
||||
"countRequests": stat.CountRequests,
|
||||
"bytes": stat.Bytes,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"attackBytes": stat.AttackBytes,
|
||||
})
|
||||
}
|
||||
this.Data["topDomainStats"] = statMaps
|
||||
}
|
||||
|
||||
// 地区排行
|
||||
{
|
||||
var countryMaps = []maps.Map{}
|
||||
for _, stat := range resp.TopCountryStats {
|
||||
countryMaps = append(countryMaps, maps.Map{
|
||||
"name": stat.CountryName,
|
||||
"bytes": stat.Bytes,
|
||||
"formattedBytes": numberutils.FormatBytes(stat.Bytes),
|
||||
"countRequests": stat.CountRequests,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"percent": fmt.Sprintf("%.2f", stat.Percent),
|
||||
})
|
||||
}
|
||||
this.Data["topCountryStats"] = countryMaps
|
||||
}
|
||||
|
||||
// 指标
|
||||
{
|
||||
var chartMaps = []maps.Map{}
|
||||
for _, chart := range resp.MetricDataCharts {
|
||||
var statMaps = []maps.Map{}
|
||||
for _, stat := range chart.MetricStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"keys": stat.Keys,
|
||||
"time": stat.Time,
|
||||
"value": stat.Value,
|
||||
"count": stat.SumCount,
|
||||
"total": stat.SumTotal,
|
||||
})
|
||||
}
|
||||
chartMaps = append(chartMaps, maps.Map{
|
||||
"chart": maps.Map{
|
||||
"id": chart.MetricChart.Id,
|
||||
"name": chart.MetricChart.Name,
|
||||
"widthDiv": chart.MetricChart.WidthDiv,
|
||||
"isOn": chart.MetricChart.IsOn,
|
||||
"maxItems": chart.MetricChart.MaxItems,
|
||||
"type": chart.MetricChart.Type,
|
||||
},
|
||||
"item": maps.Map{
|
||||
"id": chart.MetricChart.MetricItem.Id,
|
||||
"name": chart.MetricChart.MetricItem.Name,
|
||||
"period": chart.MetricChart.MetricItem.Period,
|
||||
"periodUnit": chart.MetricChart.MetricItem.PeriodUnit,
|
||||
"valueType": serverconfigs.FindMetricValueType(chart.MetricChart.MetricItem.Category, chart.MetricChart.MetricItem.Value),
|
||||
"valueTypeName": serverconfigs.FindMetricValueName(chart.MetricChart.MetricItem.Category, chart.MetricChart.MetricItem.Value),
|
||||
"keys": chart.MetricChart.MetricItem.Keys,
|
||||
},
|
||||
"stats": statMaps,
|
||||
})
|
||||
}
|
||||
this.Data["metricCharts"] = chartMaps
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package boards
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Helper(serverutils.NewServerHelper()).
|
||||
Prefix("/servers/server/boards").
|
||||
GetPost("", new(IndexAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -33,6 +34,8 @@ func (this *HistoryAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
|
||||
Partition int32 `default:"-1"`
|
||||
|
||||
PageSize int
|
||||
}) {
|
||||
if len(params.Day) == 0 {
|
||||
@@ -51,9 +54,11 @@ func (this *HistoryAction) RunGet(params struct {
|
||||
this.Data["pageSize"] = params.PageSize
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
this.Data["partition"] = params.Partition
|
||||
|
||||
day := params.Day
|
||||
ipList := []string{}
|
||||
var day = params.Day
|
||||
var ipList = []string{}
|
||||
var wafMaps = []maps.Map{}
|
||||
|
||||
if len(day) > 0 && regexp.MustCompile(`\d{4}-\d{2}-\d{2}`).MatchString(day) {
|
||||
day = strings.ReplaceAll(day, "-", "")
|
||||
@@ -65,6 +70,7 @@ func (this *HistoryAction) RunGet(params struct {
|
||||
this.Data["hasError"] = params.HasError
|
||||
|
||||
resp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
ServerId: params.ServerId,
|
||||
HasError: params.HasError > 0,
|
||||
@@ -89,11 +95,31 @@ func (this *HistoryAction) RunGet(params struct {
|
||||
} else {
|
||||
this.Data["accessLogs"] = resp.HttpAccessLogs
|
||||
for _, accessLog := range resp.HttpAccessLogs {
|
||||
// IP
|
||||
if len(accessLog.RemoteAddr) > 0 {
|
||||
if !lists.ContainsString(ipList, accessLog.RemoteAddr) {
|
||||
ipList = append(ipList, accessLog.RemoteAddr)
|
||||
}
|
||||
}
|
||||
|
||||
// WAF信息集合
|
||||
if accessLog.FirewallPolicyId > 0 && accessLog.FirewallRuleGroupId > 0 && accessLog.FirewallRuleSetId > 0 {
|
||||
// 检查Set是否已经存在
|
||||
var existSet = false
|
||||
for _, wafMap := range wafMaps {
|
||||
if wafMap.GetInt64("setId") == accessLog.FirewallRuleSetId {
|
||||
existSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !existSet {
|
||||
wafMaps = append(wafMaps, maps.Map{
|
||||
"policyId": accessLog.FirewallPolicyId,
|
||||
"groupId": accessLog.FirewallRuleGroupId,
|
||||
"setId": accessLog.FirewallRuleSetId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["hasMore"] = resp.HasMore
|
||||
@@ -105,6 +131,7 @@ func (this *HistoryAction) RunGet(params struct {
|
||||
if len(params.RequestId) > 0 {
|
||||
this.Data["hasPrev"] = true
|
||||
prevResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
ServerId: params.ServerId,
|
||||
HasError: params.HasError > 0,
|
||||
@@ -129,7 +156,7 @@ func (this *HistoryAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 根据IP查询区域
|
||||
regionMap := map[string]string{} // ip => region
|
||||
var regionMap = map[string]string{} // ip => region
|
||||
if len(ipList) > 0 {
|
||||
resp, err := this.RPC().IPLibraryRPC().LookupIPRegions(this.AdminContext(), &pb.LookupIPRegionsRequest{IpList: ipList})
|
||||
if err != nil {
|
||||
@@ -144,5 +171,79 @@ func (this *HistoryAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["regions"] = regionMap
|
||||
|
||||
// WAF相关
|
||||
var wafInfos = map[int64]maps.Map{} // set id => WAF Map
|
||||
var wafPolicyCacheMap = map[int64]*pb.HTTPFirewallPolicy{} // id => *pb.HTTPFirewallPolicy
|
||||
var wafGroupCacheMap = map[int64]*pb.HTTPFirewallRuleGroup{} // id => *pb.HTTPFirewallRuleGroup
|
||||
var wafSetCacheMap = map[int64]*pb.HTTPFirewallRuleSet{} // id => *pb.HTTPFirewallRuleSet
|
||||
for _, wafMap := range wafMaps {
|
||||
var policyId = wafMap.GetInt64("policyId")
|
||||
var groupId = wafMap.GetInt64("groupId")
|
||||
var setId = wafMap.GetInt64("setId")
|
||||
if policyId > 0 {
|
||||
pbPolicy, ok := wafPolicyCacheMap[policyId]
|
||||
if !ok {
|
||||
policyResp, err := this.RPC().HTTPFirewallPolicyRPC().FindEnabledHTTPFirewallPolicy(this.AdminContext(), &pb.FindEnabledHTTPFirewallPolicyRequest{HttpFirewallPolicyId: policyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbPolicy = policyResp.HttpFirewallPolicy
|
||||
wafPolicyCacheMap[policyId] = pbPolicy
|
||||
}
|
||||
if pbPolicy != nil {
|
||||
wafMap = maps.Map{
|
||||
"policy": maps.Map{
|
||||
"id": pbPolicy.Id,
|
||||
"name": pbPolicy.Name,
|
||||
"serverId": pbPolicy.ServerId,
|
||||
},
|
||||
}
|
||||
if groupId > 0 {
|
||||
pbGroup, ok := wafGroupCacheMap[groupId]
|
||||
if !ok {
|
||||
groupResp, err := this.RPC().HTTPFirewallRuleGroupRPC().FindEnabledHTTPFirewallRuleGroup(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleGroupRequest{FirewallRuleGroupId: groupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbGroup = groupResp.FirewallRuleGroup
|
||||
wafGroupCacheMap[groupId] = pbGroup
|
||||
}
|
||||
|
||||
if pbGroup != nil {
|
||||
wafMap["group"] = maps.Map{
|
||||
"id": pbGroup.Id,
|
||||
"name": pbGroup.Name,
|
||||
}
|
||||
|
||||
if setId > 0 {
|
||||
pbSet, ok := wafSetCacheMap[setId]
|
||||
if !ok {
|
||||
setResp, err := this.RPC().HTTPFirewallRuleSetRPC().FindEnabledHTTPFirewallRuleSet(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleSetRequest{FirewallRuleSetId: setId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbSet = setResp.FirewallRuleSet
|
||||
wafSetCacheMap[setId] = pbSet
|
||||
}
|
||||
|
||||
if pbSet != nil {
|
||||
wafMap["set"] = maps.Map{
|
||||
"id": pbSet.Id,
|
||||
"name": pbSet.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wafInfos[setId] = wafMap
|
||||
}
|
||||
this.Data["wafInfos"] = wafInfos
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
)
|
||||
|
||||
@@ -57,10 +58,13 @@ func (this *IndexAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
|
||||
Partition int32 `default:"-1"`
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
isReverse := len(params.RequestId) > 0
|
||||
var isReverse = len(params.RequestId) > 0
|
||||
accessLogsResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
ServerId: params.ServerId,
|
||||
RequestId: params.RequestId,
|
||||
Size: 20,
|
||||
@@ -77,17 +81,39 @@ func (this *IndexAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
ipList := []string{}
|
||||
accessLogs := accessLogsResp.HttpAccessLogs
|
||||
var ipList = []string{}
|
||||
var wafMaps = []maps.Map{}
|
||||
|
||||
var accessLogs = accessLogsResp.HttpAccessLogs
|
||||
if len(accessLogs) == 0 {
|
||||
accessLogs = []*pb.HTTPAccessLog{}
|
||||
} else {
|
||||
for _, accessLog := range accessLogs {
|
||||
// IP
|
||||
if len(accessLog.RemoteAddr) > 0 {
|
||||
if !lists.ContainsString(ipList, accessLog.RemoteAddr) {
|
||||
ipList = append(ipList, accessLog.RemoteAddr)
|
||||
}
|
||||
}
|
||||
|
||||
// WAF信息集合
|
||||
if accessLog.FirewallPolicyId > 0 && accessLog.FirewallRuleGroupId > 0 && accessLog.FirewallRuleSetId > 0 {
|
||||
// 检查Set是否已经存在
|
||||
var existSet = false
|
||||
for _, wafMap := range wafMaps {
|
||||
if wafMap.GetInt64("setId") == accessLog.FirewallRuleSetId {
|
||||
existSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !existSet {
|
||||
wafMaps = append(wafMaps, maps.Map{
|
||||
"policyId": accessLog.FirewallPolicyId,
|
||||
"groupId": accessLog.FirewallRuleGroupId,
|
||||
"setId": accessLog.FirewallRuleSetId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["accessLogs"] = accessLogs
|
||||
@@ -99,7 +125,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
this.Data["hasMore"] = accessLogsResp.HasMore
|
||||
|
||||
// 根据IP查询区域
|
||||
regionMap := map[string]string{} // ip => region
|
||||
var regionMap = map[string]string{} // ip => region
|
||||
if len(ipList) > 0 {
|
||||
resp, err := this.RPC().IPLibraryRPC().LookupIPRegions(this.AdminContext(), &pb.LookupIPRegionsRequest{IpList: ipList})
|
||||
if err != nil {
|
||||
@@ -114,5 +140,79 @@ func (this *IndexAction) RunPost(params struct {
|
||||
}
|
||||
this.Data["regions"] = regionMap
|
||||
|
||||
// WAF相关
|
||||
var wafInfos = map[int64]maps.Map{} // set id => WAF Map
|
||||
var wafPolicyCacheMap = map[int64]*pb.HTTPFirewallPolicy{} // id => *pb.HTTPFirewallPolicy
|
||||
var wafGroupCacheMap = map[int64]*pb.HTTPFirewallRuleGroup{} // id => *pb.HTTPFirewallRuleGroup
|
||||
var wafSetCacheMap = map[int64]*pb.HTTPFirewallRuleSet{} // id => *pb.HTTPFirewallRuleSet
|
||||
for _, wafMap := range wafMaps {
|
||||
var policyId = wafMap.GetInt64("policyId")
|
||||
var groupId = wafMap.GetInt64("groupId")
|
||||
var setId = wafMap.GetInt64("setId")
|
||||
if policyId > 0 {
|
||||
pbPolicy, ok := wafPolicyCacheMap[policyId]
|
||||
if !ok {
|
||||
policyResp, err := this.RPC().HTTPFirewallPolicyRPC().FindEnabledHTTPFirewallPolicy(this.AdminContext(), &pb.FindEnabledHTTPFirewallPolicyRequest{HttpFirewallPolicyId: policyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbPolicy = policyResp.HttpFirewallPolicy
|
||||
wafPolicyCacheMap[policyId] = pbPolicy
|
||||
}
|
||||
if pbPolicy != nil {
|
||||
wafMap = maps.Map{
|
||||
"policy": maps.Map{
|
||||
"id": pbPolicy.Id,
|
||||
"name": pbPolicy.Name,
|
||||
"serverId": pbPolicy.ServerId,
|
||||
},
|
||||
}
|
||||
if groupId > 0 {
|
||||
pbGroup, ok := wafGroupCacheMap[groupId]
|
||||
if !ok {
|
||||
groupResp, err := this.RPC().HTTPFirewallRuleGroupRPC().FindEnabledHTTPFirewallRuleGroup(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleGroupRequest{FirewallRuleGroupId: groupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbGroup = groupResp.FirewallRuleGroup
|
||||
wafGroupCacheMap[groupId] = pbGroup
|
||||
}
|
||||
|
||||
if pbGroup != nil {
|
||||
wafMap["group"] = maps.Map{
|
||||
"id": pbGroup.Id,
|
||||
"name": pbGroup.Name,
|
||||
}
|
||||
|
||||
if setId > 0 {
|
||||
pbSet, ok := wafSetCacheMap[setId]
|
||||
if !ok {
|
||||
setResp, err := this.RPC().HTTPFirewallRuleSetRPC().FindEnabledHTTPFirewallRuleSet(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleSetRequest{FirewallRuleSetId: setId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbSet = setResp.FirewallRuleSet
|
||||
wafSetCacheMap[setId] = pbSet
|
||||
}
|
||||
|
||||
if pbSet != nil {
|
||||
wafMap["set"] = maps.Map{
|
||||
"id": pbSet.Id,
|
||||
"name": pbSet.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wafInfos[setId] = wafMap
|
||||
}
|
||||
this.Data["wafInfos"] = wafInfos
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
)
|
||||
|
||||
@@ -27,11 +28,13 @@ func (this *TodayAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
|
||||
Partition int32 `default:"-1"`
|
||||
|
||||
PageSize int
|
||||
}) {
|
||||
this.Data["pageSize"] = params.PageSize
|
||||
|
||||
size := int64(params.PageSize)
|
||||
var size = int64(params.PageSize)
|
||||
if size < 1 {
|
||||
size = 20
|
||||
}
|
||||
@@ -44,8 +47,11 @@ func (this *TodayAction) RunGet(params struct {
|
||||
this.Data["hasWAF"] = params.HasWAF
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
this.Data["partition"] = params.Partition
|
||||
this.Data["day"] = timeutil.Format("Ymd")
|
||||
|
||||
resp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
ServerId: params.ServerId,
|
||||
HasError: params.HasError > 0,
|
||||
@@ -63,17 +69,39 @@ func (this *TodayAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
ipList := []string{}
|
||||
var ipList = []string{}
|
||||
var wafMaps = []maps.Map{}
|
||||
|
||||
if len(resp.HttpAccessLogs) == 0 {
|
||||
this.Data["accessLogs"] = []interface{}{}
|
||||
} else {
|
||||
this.Data["accessLogs"] = resp.HttpAccessLogs
|
||||
for _, accessLog := range resp.HttpAccessLogs {
|
||||
// IP
|
||||
if len(accessLog.RemoteAddr) > 0 {
|
||||
if !lists.ContainsString(ipList, accessLog.RemoteAddr) {
|
||||
ipList = append(ipList, accessLog.RemoteAddr)
|
||||
}
|
||||
}
|
||||
|
||||
// WAF信息集合
|
||||
if accessLog.FirewallPolicyId > 0 && accessLog.FirewallRuleGroupId > 0 && accessLog.FirewallRuleSetId > 0 {
|
||||
// 检查Set是否已经存在
|
||||
var existSet = false
|
||||
for _, wafMap := range wafMaps {
|
||||
if wafMap.GetInt64("setId") == accessLog.FirewallRuleSetId {
|
||||
existSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !existSet {
|
||||
wafMaps = append(wafMaps, maps.Map{
|
||||
"policyId": accessLog.FirewallPolicyId,
|
||||
"groupId": accessLog.FirewallRuleGroupId,
|
||||
"setId": accessLog.FirewallRuleSetId,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["hasMore"] = resp.HasMore
|
||||
@@ -85,6 +113,7 @@ func (this *TodayAction) RunGet(params struct {
|
||||
if len(params.RequestId) > 0 {
|
||||
this.Data["hasPrev"] = true
|
||||
prevResp, err := this.RPC().HTTPAccessLogRPC().ListHTTPAccessLogs(this.AdminContext(), &pb.ListHTTPAccessLogsRequest{
|
||||
Partition: params.Partition,
|
||||
RequestId: params.RequestId,
|
||||
ServerId: params.ServerId,
|
||||
HasError: params.HasError > 0,
|
||||
@@ -108,7 +137,7 @@ func (this *TodayAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 根据IP查询区域
|
||||
regionMap := map[string]string{} // ip => region
|
||||
var regionMap = map[string]string{} // ip => region
|
||||
if len(ipList) > 0 {
|
||||
resp, err := this.RPC().IPLibraryRPC().LookupIPRegions(this.AdminContext(), &pb.LookupIPRegionsRequest{IpList: ipList})
|
||||
if err != nil {
|
||||
@@ -123,5 +152,79 @@ func (this *TodayAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["regions"] = regionMap
|
||||
|
||||
// WAF相关
|
||||
var wafInfos = map[int64]maps.Map{} // set id => WAF Map
|
||||
var wafPolicyCacheMap = map[int64]*pb.HTTPFirewallPolicy{} // id => *pb.HTTPFirewallPolicy
|
||||
var wafGroupCacheMap = map[int64]*pb.HTTPFirewallRuleGroup{} // id => *pb.HTTPFirewallRuleGroup
|
||||
var wafSetCacheMap = map[int64]*pb.HTTPFirewallRuleSet{} // id => *pb.HTTPFirewallRuleSet
|
||||
for _, wafMap := range wafMaps {
|
||||
var policyId = wafMap.GetInt64("policyId")
|
||||
var groupId = wafMap.GetInt64("groupId")
|
||||
var setId = wafMap.GetInt64("setId")
|
||||
if policyId > 0 {
|
||||
pbPolicy, ok := wafPolicyCacheMap[policyId]
|
||||
if !ok {
|
||||
policyResp, err := this.RPC().HTTPFirewallPolicyRPC().FindEnabledHTTPFirewallPolicy(this.AdminContext(), &pb.FindEnabledHTTPFirewallPolicyRequest{HttpFirewallPolicyId: policyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbPolicy = policyResp.HttpFirewallPolicy
|
||||
wafPolicyCacheMap[policyId] = pbPolicy
|
||||
}
|
||||
if pbPolicy != nil {
|
||||
wafMap = maps.Map{
|
||||
"policy": maps.Map{
|
||||
"id": pbPolicy.Id,
|
||||
"name": pbPolicy.Name,
|
||||
"serverId": pbPolicy.ServerId,
|
||||
},
|
||||
}
|
||||
if groupId > 0 {
|
||||
pbGroup, ok := wafGroupCacheMap[groupId]
|
||||
if !ok {
|
||||
groupResp, err := this.RPC().HTTPFirewallRuleGroupRPC().FindEnabledHTTPFirewallRuleGroup(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleGroupRequest{FirewallRuleGroupId: groupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbGroup = groupResp.FirewallRuleGroup
|
||||
wafGroupCacheMap[groupId] = pbGroup
|
||||
}
|
||||
|
||||
if pbGroup != nil {
|
||||
wafMap["group"] = maps.Map{
|
||||
"id": pbGroup.Id,
|
||||
"name": pbGroup.Name,
|
||||
}
|
||||
|
||||
if setId > 0 {
|
||||
pbSet, ok := wafSetCacheMap[setId]
|
||||
if !ok {
|
||||
setResp, err := this.RPC().HTTPFirewallRuleSetRPC().FindEnabledHTTPFirewallRuleSet(this.AdminContext(), &pb.FindEnabledHTTPFirewallRuleSetRequest{FirewallRuleSetId: setId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbSet = setResp.FirewallRuleSet
|
||||
wafSetCacheMap[setId] = pbSet
|
||||
}
|
||||
|
||||
if pbSet != nil {
|
||||
wafMap["set"] = maps.Map{
|
||||
"id": pbSet.Id,
|
||||
"name": pbSet.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wafInfos[setId] = wafMap
|
||||
}
|
||||
this.Data["wafInfos"] = wafInfos
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ func init() {
|
||||
GetPost("/createPopup", new(CreatePopupAction)).
|
||||
GetPost("/purge", new(PurgeAction)).
|
||||
GetPost("/preheat", new(PreheatAction)).
|
||||
Post("/updateRefs", new(UpdateRefsAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
83
internal/web/actions/default/servers/server/settings/cache/updateRefs.go
vendored
Normal file
83
internal/web/actions/default/servers/server/settings/cache/updateRefs.go
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
)
|
||||
|
||||
type UpdateRefsAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *UpdateRefsAction) RunPost(params struct {
|
||||
WebId int64
|
||||
RefsJSON []byte
|
||||
}) {
|
||||
// 日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改Web %d 的缓存设置", params.WebId)
|
||||
|
||||
this.Data["isUpdated"] = false
|
||||
|
||||
webConfigResp, err := this.RPC().HTTPWebRPC().FindEnabledHTTPWebConfig(this.AdminContext(), &pb.FindEnabledHTTPWebConfigRequest{HttpWebId: params.WebId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var webConfig = &serverconfigs.HTTPWebConfig{}
|
||||
err = json.Unmarshal(webConfigResp.HttpWebJSON, webConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["webId"] = webConfig.Id
|
||||
this.Data["cacheConfig"] = webConfig.Cache
|
||||
|
||||
// 校验配置
|
||||
var cacheConfig = webConfig.Cache
|
||||
if webConfig == nil {
|
||||
this.Success()
|
||||
}
|
||||
|
||||
var refs = []*serverconfigs.HTTPCacheRef{}
|
||||
err = json.Unmarshal(params.RefsJSON, &refs)
|
||||
if err != nil {
|
||||
this.ErrorPage(errors.New("decode refs json failed: " + err.Error()))
|
||||
return
|
||||
}
|
||||
cacheConfig.CacheRefs = refs
|
||||
|
||||
err = cacheConfig.Init()
|
||||
if err != nil {
|
||||
this.Fail("检查配置失败:" + err.Error())
|
||||
}
|
||||
|
||||
// 去除不必要的部分
|
||||
for _, cacheRef := range cacheConfig.CacheRefs {
|
||||
cacheRef.CachePolicy = nil
|
||||
}
|
||||
|
||||
cacheJSON, err := json.Marshal(cacheConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebCache(this.AdminContext(), &pb.UpdateHTTPWebCacheRequest{
|
||||
HttpWebId: params.WebId,
|
||||
CacheJSON: cacheJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["isUpdated"] = true
|
||||
this.Success()
|
||||
}
|
||||
@@ -147,13 +147,14 @@ func (this *IndexAction) RunGet(params struct {
|
||||
|
||||
// RunPost 保存
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
ServerId int64
|
||||
Name string
|
||||
Description string
|
||||
ClusterId int64
|
||||
GroupIds []int64
|
||||
IsOn bool
|
||||
UserPlanId int64
|
||||
ServerId int64
|
||||
Name string
|
||||
Description string
|
||||
ClusterId int64
|
||||
KeepOldConfigs bool
|
||||
GroupIds []int64
|
||||
IsOn bool
|
||||
UserPlanId int64
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -174,6 +175,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
Name: params.Name,
|
||||
Description: params.Description,
|
||||
NodeClusterId: params.ClusterId,
|
||||
KeepOldConfigs: params.KeepOldConfigs,
|
||||
IsOn: params.IsOn,
|
||||
ServerGroupIds: params.GroupIds,
|
||||
})
|
||||
|
||||
@@ -66,13 +66,7 @@ func (this *LocationHelper) createMenus(serverIdString string, locationIdString
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && locationConfig.Web.RedirectToHttps != nil && locationConfig.Web.RedirectToHttps.IsPrior,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "Web设置",
|
||||
"url": "/servers/server/settings/locations/web?serverId=" + serverIdString + "&locationId=" + locationIdString,
|
||||
"isActive": secondMenuItem == "web",
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && locationConfig.Web.Root != nil && locationConfig.Web.Root.IsPrior,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "反向代理",
|
||||
"name": "源站",
|
||||
"url": "/servers/server/settings/locations/reverseProxy?serverId=" + serverIdString + "&locationId=" + locationIdString,
|
||||
"isActive": secondMenuItem == "reverseProxy",
|
||||
"isOn": locationConfig != nil && locationConfig.ReverseProxyRef != nil && locationConfig.ReverseProxyRef.IsPrior,
|
||||
@@ -131,7 +125,7 @@ func (this *LocationHelper) createMenus(serverIdString string, locationIdString
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && locationConfig.Web.Compression != nil && locationConfig.Web.Compression.IsPrior,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "特殊页面",
|
||||
"name": "自定义页面",
|
||||
"url": "/servers/server/settings/locations/pages?serverId=" + serverIdString + "&locationId=" + locationIdString,
|
||||
"isActive": secondMenuItem == "pages",
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && (len(locationConfig.Web.Pages) > 0 || (locationConfig.Web.Shutdown != nil && locationConfig.Web.Shutdown.IsPrior)),
|
||||
@@ -154,6 +148,12 @@ func (this *LocationHelper) createMenus(serverIdString string, locationIdString
|
||||
"isActive": secondMenuItem == "webp",
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && locationConfig.Web.WebP != nil && locationConfig.Web.WebP.IsPrior,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "静态分发",
|
||||
"url": "/servers/server/settings/locations/web?serverId=" + serverIdString + "&locationId=" + locationIdString,
|
||||
"isActive": secondMenuItem == "web",
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && locationConfig.Web.Root != nil && locationConfig.Web.Root.IsPrior,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "Fastcgi",
|
||||
"url": "/servers/server/settings/locations/fastcgi?serverId=" + serverIdString + "&locationId=" + locationIdString,
|
||||
@@ -161,6 +161,8 @@ func (this *LocationHelper) createMenus(serverIdString string, locationIdString
|
||||
"isOn": locationConfig != nil && locationConfig.Web != nil && locationConfig.Web.FastcgiRef != nil && locationConfig.Web.FastcgiRef.IsPrior,
|
||||
})
|
||||
|
||||
menuItems = filterMenuItems(locationConfig, menuItems, serverIdString, locationIdString, secondMenuItem)
|
||||
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "-",
|
||||
"url": "",
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package locationutils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
func filterMenuItems(locationConfig *serverconfigs.HTTPLocationConfig, menuItems []maps.Map, serverIdString string, locationIdString string, secondMenuItem string) []maps.Map {
|
||||
return menuItems
|
||||
}
|
||||
@@ -36,7 +36,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
ShutdownJSON string
|
||||
Must *actions.Must
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改Web %d 的特殊页面设置", params.WebId)
|
||||
defer this.CreateLogInfo("修改Web %d 的自定义页面设置", params.WebId)
|
||||
|
||||
// TODO 检查配置
|
||||
|
||||
|
||||
@@ -63,9 +63,9 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pageId := createResp.PageId
|
||||
pageId := createResp.HttpPageId
|
||||
|
||||
configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{PageId: pageId})
|
||||
configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{HttpPageId: pageId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
@@ -80,7 +80,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
this.Data["page"] = pageConfig
|
||||
|
||||
// 日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "创建特殊页面 %d", pageId)
|
||||
defer this.CreateLog(oplogs.LevelInfo, "创建自定义页面 %d", pageId)
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
||||
}) {
|
||||
this.Data["bodyTypes"] = shared.FindAllBodyTypes()
|
||||
|
||||
configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{PageId: params.PageId})
|
||||
configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{HttpPageId: params.PageId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
@@ -55,7 +55,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Must *actions.Must
|
||||
}) {
|
||||
// 日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改特殊页面 %d", params.PageId)
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改自定义页面 %d", params.PageId)
|
||||
|
||||
params.Must.
|
||||
Field("status", params.Status).
|
||||
@@ -73,7 +73,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
_, err := this.RPC().HTTPPageRPC().UpdateHTTPPage(this.AdminContext(), &pb.UpdateHTTPPageRequest{
|
||||
PageId: params.PageId,
|
||||
HttpPageId: params.PageId,
|
||||
StatusList: []string{params.Status},
|
||||
BodyType: params.BodyType,
|
||||
Url: params.URL,
|
||||
@@ -86,7 +86,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 返回修改后的配置
|
||||
configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{PageId: params.PageId})
|
||||
configResp, err := this.RPC().HTTPPageRPC().FindEnabledHTTPPageConfig(this.AdminContext(), &pb.FindEnabledHTTPPageConfigRequest{HttpPageId: params.PageId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -5,6 +5,7 @@ package webp
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
@@ -44,6 +45,25 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["webId"] = webConfig.Id
|
||||
this.Data["webpConfig"] = webConfig.WebP
|
||||
|
||||
// WebP策略配置
|
||||
var serverMap = this.Data.GetMap("server")
|
||||
var clusterId = serverMap.GetInt64("clusterId")
|
||||
webpPolicyResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterWebPPolicy(this.AdminContext(), &pb.FindEnabledNodeClusterWebPPolicyRequest{NodeClusterId: clusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["requireCache"] = true
|
||||
if len(webpPolicyResp.WebpPolicyJSON) > 0 {
|
||||
var webpPolicy = &nodeconfigs.WebPImagePolicy{}
|
||||
err = json.Unmarshal(webpPolicyResp.WebpPolicyJSON, webpPolicy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["requireCache"] = webpPolicy.RequireCache
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
|
||||
14
internal/web/actions/default/servers/serverutils/menu.go
Normal file
14
internal/web/actions/default/servers/serverutils/menu.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package serverutils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
func filterMenuItems(serverConfig *serverconfigs.ServerConfig, menuItems []maps.Map, serverIdString string, secondMenuItem string) []maps.Map {
|
||||
return menuItems
|
||||
}
|
||||
@@ -62,7 +62,7 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
server := serverResp.Server
|
||||
var server = serverResp.Server
|
||||
if server == nil {
|
||||
logs.Error(errors.New("can not find the server"))
|
||||
return
|
||||
@@ -70,11 +70,18 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
|
||||
|
||||
// 初始化数据
|
||||
if !action.Data.Has("server") {
|
||||
action.Data["server"] = maps.Map{"id": server.Id, "name": server.Name}
|
||||
if server.NodeCluster == nil {
|
||||
server.NodeCluster = &pb.NodeCluster{Id: 0}
|
||||
}
|
||||
action.Data["server"] = maps.Map{
|
||||
"id": server.Id,
|
||||
"name": server.Name,
|
||||
"clusterId": server.NodeCluster.Id,
|
||||
}
|
||||
}
|
||||
|
||||
// 服务管理
|
||||
serverConfig := &serverconfigs.ServerConfig{}
|
||||
var serverConfig = &serverconfigs.ServerConfig{}
|
||||
err = json.Unmarshal(server.Config, serverConfig)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
@@ -109,10 +116,6 @@ func (this *ServerHelper) createLeftMenu(action *actions.ActionObject) {
|
||||
}
|
||||
tabbar.Add("设置", "", "/servers/server/settings?serverId="+serverIdString, "setting", selectedTabbar == "setting")
|
||||
tabbar.Add("删除", "", "/servers/server/delete?serverId="+serverIdString, "trash", selectedTabbar == "delete")
|
||||
{
|
||||
m := tabbar.Add("当前服务:"+server.Name, "", "/servers/server?serverId="+serverIdString, "", false)
|
||||
m["right"] = true
|
||||
}
|
||||
|
||||
actionutils.SetTabbar(action, tabbar)
|
||||
|
||||
@@ -243,17 +246,28 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
|
||||
"isOff": serverConfig.HTTPS != nil && !serverConfig.HTTPS.IsOn,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "Web设置",
|
||||
"url": "/servers/server/settings/web?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "web",
|
||||
"isOn": serverConfig.Web != nil && serverConfig.Web.Root != nil && serverConfig.Web.Root.IsOn,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "反向代理",
|
||||
"name": "源站",
|
||||
"url": "/servers/server/settings/reverseProxy?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "reverseProxy",
|
||||
"isOn": serverConfig.ReverseProxyRef != nil && serverConfig.ReverseProxyRef.IsOn,
|
||||
})
|
||||
|
||||
if teaconst.IsPlus {
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "-",
|
||||
"url": "",
|
||||
"isActive": false,
|
||||
})
|
||||
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "5秒盾",
|
||||
"url": "/servers/server/settings/uam?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "uam",
|
||||
"isOn": serverConfig.UAM != nil && serverConfig.UAM.IsOn,
|
||||
"isImportant": serverConfig.UAM != nil && serverConfig.UAM.IsOn,
|
||||
})
|
||||
}
|
||||
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "-",
|
||||
"url": "",
|
||||
@@ -320,7 +334,7 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
|
||||
"isOn": serverConfig.Web != nil && serverConfig.Web.Compression != nil && serverConfig.Web.Compression.IsOn,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "特殊页面",
|
||||
"name": "自定义页面",
|
||||
"url": "/servers/server/settings/pages?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "pages",
|
||||
"isOn": serverConfig.Web != nil && (len(serverConfig.Web.Pages) > 0 || (serverConfig.Web.Shutdown != nil && serverConfig.Web.Shutdown.IsOn)),
|
||||
@@ -344,6 +358,12 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
|
||||
"isOn": serverConfig.Web != nil && serverConfig.Web.WebP != nil && serverConfig.Web.WebP.IsOn,
|
||||
})
|
||||
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "静态分发",
|
||||
"url": "/servers/server/settings/web?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "web",
|
||||
"isOn": serverConfig.Web != nil && serverConfig.Web.Root != nil && serverConfig.Web.Root.IsOn,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "Fastcgi",
|
||||
"url": "/servers/server/settings/fastcgi?serverId=" + serverIdString,
|
||||
@@ -371,24 +391,7 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
|
||||
"isOn": serverConfig.Web != nil && serverConfig.Web.RequestLimit != nil && serverConfig.Web.RequestLimit.IsOn,
|
||||
})
|
||||
|
||||
if teaconst.IsPlus {
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "流量限制",
|
||||
"url": "/servers/server/settings/traffic?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "traffic",
|
||||
"isOn": serverConfig.TrafficLimit != nil && serverConfig.TrafficLimit.IsOn,
|
||||
})
|
||||
|
||||
if serverConfig.Web != nil && serverConfig.Web.RequestScripts != nil {
|
||||
_ = serverConfig.Web.RequestScripts.Init()
|
||||
}
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "边缘脚本",
|
||||
"url": "/servers/server/settings/requestScripts?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "requestScripts",
|
||||
"isOn": serverConfig.Web != nil && serverConfig.Web.RequestScripts != nil && !serverConfig.Web.RequestScripts.IsEmpty(),
|
||||
})
|
||||
}
|
||||
menuItems = filterMenuItems(serverConfig, menuItems, serverIdString, secondMenuItem)
|
||||
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "-",
|
||||
@@ -416,7 +419,7 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
|
||||
"isOn": serverConfig.TLS != nil && serverConfig.TLS.IsOn && len(serverConfig.TLS.Listen) > 0,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "反向代理",
|
||||
"name": "源站",
|
||||
"url": "/servers/server/settings/reverseProxy?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "reverseProxy",
|
||||
"isOn": serverConfig.ReverseProxyRef != nil && serverConfig.ReverseProxyRef.IsOn,
|
||||
@@ -436,7 +439,7 @@ func (this *ServerHelper) createSettingsMenu(secondMenuItem string, serverIdStri
|
||||
"isOn": serverConfig.UDP != nil && serverConfig.UDP.IsOn && len(serverConfig.UDP.Listen) > 0,
|
||||
})
|
||||
menuItems = append(menuItems, maps.Map{
|
||||
"name": "反向代理",
|
||||
"name": "源站",
|
||||
"url": "/servers/server/settings/reverseProxy?serverId=" + serverIdString,
|
||||
"isActive": secondMenuItem == "reverseProxy",
|
||||
"isOn": serverConfig.ReverseProxyRef != nil && serverConfig.ReverseProxyRef.IsOn,
|
||||
|
||||
@@ -3,6 +3,7 @@ package ui
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"io"
|
||||
@@ -27,6 +28,15 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
this.Data["config"] = config
|
||||
|
||||
// 时区
|
||||
this.Data["timeZoneGroups"] = nodeconfigs.FindAllTimeZoneGroups()
|
||||
this.Data["timeZoneLocations"] = nodeconfigs.FindAllTimeZoneLocations()
|
||||
|
||||
if len(config.TimeZone) == 0 {
|
||||
config.TimeZone = nodeconfigs.DefaultTimeZoneLocation
|
||||
}
|
||||
this.Data["timeZoneLocation"] = nodeconfigs.FindTimeZoneLocation(config.TimeZone)
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -40,6 +50,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
FaviconFile *actions.File
|
||||
LogoFile *actions.File
|
||||
DefaultPageSize int
|
||||
TimeZone string
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -66,6 +77,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
config.ShowFinance = params.ShowFinance
|
||||
config.ShowVersion = params.ShowVersion
|
||||
config.Version = params.Version
|
||||
config.TimeZone = params.TimeZone
|
||||
|
||||
if params.DefaultPageSize > 0 {
|
||||
config.DefaultPageSize = params.DefaultPageSize
|
||||
|
||||
@@ -3,6 +3,7 @@ package userui
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"io"
|
||||
@@ -24,6 +25,15 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
this.Data["config"] = config
|
||||
|
||||
// 时区
|
||||
this.Data["timeZoneGroups"] = nodeconfigs.FindAllTimeZoneGroups()
|
||||
this.Data["timeZoneLocations"] = nodeconfigs.FindAllTimeZoneLocations()
|
||||
|
||||
if len(config.TimeZone) == 0 {
|
||||
config.TimeZone = nodeconfigs.DefaultTimeZoneLocation
|
||||
}
|
||||
this.Data["timeZoneLocation"] = nodeconfigs.FindTimeZoneLocation(config.TimeZone)
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -36,6 +46,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
ShowFinance bool
|
||||
FaviconFile *actions.File
|
||||
LogoFile *actions.File
|
||||
TimeZone string
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -57,6 +68,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
config.ShowVersion = params.ShowVersion
|
||||
config.Version = params.Version
|
||||
config.ShowFinance = params.ShowFinance
|
||||
config.TimeZone = params.TimeZone
|
||||
|
||||
// 上传Favicon文件
|
||||
if params.FaviconFile != nil {
|
||||
|
||||
@@ -44,6 +44,7 @@ import (
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/httpReverseProxy"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/index"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/remoteAddr"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/tcpReverseProxy"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/udpReverseProxy"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/logs"
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 107 KiB |
10152
web/public/js/components.js
Executable file → Normal file
10152
web/public/js/components.js
Executable file → Normal file
File diff suppressed because one or more lines are too long
14332
web/public/js/components.src.js
Executable file
14332
web/public/js/components.src.js
Executable file
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@ Vue.component("node-cluster-combo-box", {
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `<div v-if="clusters.length > 0">
|
||||
template: `<div v-if="clusters.length > 0" style="min-width: 10.4em">
|
||||
<combo-box title="集群" placeholder="集群名称" :v-items="clusters" name="clusterId" :v-value="vClusterId" @change="change"></combo-box>
|
||||
</div>`
|
||||
})
|
||||
@@ -144,7 +144,7 @@ Vue.component("combo-box", {
|
||||
<!-- 当前选中 -->
|
||||
<div v-if="selectedItem != null">
|
||||
<input type="hidden" :name="name" :value="selectedItem.value"/>
|
||||
<a href="" class="ui label basic" ref="selectedLabel" @click.prevent="submitForm"><span>{{title}}:{{selectedItem.name}}</span>
|
||||
<a href="" class="ui label basic" style="line-height: 1.4; font-weight: normal; font-size: 1em" ref="selectedLabel" @click.prevent="submitForm"><span>{{title}}:{{selectedItem.name}}</span>
|
||||
<span title="清除" @click.prevent="reset"><i class="icon remove small"></i></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,7 @@ Vue.component("health-check-config-box", {
|
||||
countUp: 1,
|
||||
countDown: 3,
|
||||
userAgent: "",
|
||||
onlyBasicRequest: false
|
||||
onlyBasicRequest: true
|
||||
}
|
||||
let that = this
|
||||
setTimeout(function () {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user