Compare commits

..

126 Commits

Author SHA1 Message Date
刘祥超
e3674fa2c1 优化文字 2021-12-20 09:35:36 +08:00
刘祥超
a14cbe1319 访问日志限制字段 2021-12-20 09:35:25 +08:00
刘祥超
c03c35de88 访问日志限制字段 2021-12-19 20:39:18 +08:00
刘祥超
dc6c649af8 优化文字提示等 2021-12-19 18:56:09 +08:00
刘祥超
b0d2bdb0ba 修复HSTS无法设置有效期的Bug 2021-12-18 17:23:55 +08:00
刘祥超
9239dd9a8b 调整单次通知更新任务的数量为500(原来200) 2021-12-17 14:25:40 +08:00
刘祥超
07a368a0bd 修改相关域名、文字等 2021-12-17 14:17:48 +08:00
刘祥超
b8d6d1c249 访问日志中缓存状态增加STALE 2021-12-17 11:55:12 +08:00
刘祥超
0f1d6a1ad2 实现stale cache配置 2021-12-16 17:27:09 +08:00
刘祥超
37c6928ffc 节点IP显示原始IP(如果已经切换到备用IP的话) 2021-12-16 15:18:21 +08:00
刘祥超
7478b6dbe0 优化代码 2021-12-15 20:46:42 +08:00
刘祥超
e3cd6e1441 增加在线检查最新版本功能 2021-12-15 20:13:10 +08:00
刘祥超
8081d968b6 Update components.js 2021-12-15 09:56:18 +08:00
刘祥超
a226eee6ef HTTP Header:实现请求方法、域名、状态码等限制,实现内容替换功能 2021-12-14 21:26:32 +08:00
刘祥超
8b5a21e593 访问日志查询过慢的时候,提示建议增加新的日志节点 2021-12-14 15:50:21 +08:00
刘祥超
2c71f6c6be 实现访问日志队列 2021-12-14 12:45:09 +08:00
刘祥超
1a50b01edf 优化代码 2021-12-13 10:53:49 +08:00
刘祥超
05f08eeb4c 优化坐标轴单位 2021-12-12 21:13:55 +08:00
刘祥超
fdc3ebb5c5 WAF添加规则:调整界面/增加正则表达式测试功能 2021-12-12 20:56:25 +08:00
刘祥超
8f06bccd48 WAF策略:可以修改分组代号/导入时可以根据名称合并/导出时可以导出停用的分组 2021-12-12 20:24:15 +08:00
刘祥超
16b4eb67d4 Update components.js 2021-12-12 17:14:46 +08:00
刘祥超
ffa545cb41 服务分组可以设置请求限制 2021-12-12 17:07:16 +08:00
刘祥超
f67454d51c 路由规则增加专属域名设置 2021-12-12 16:38:52 +08:00
刘祥超
8ae54c56db 增加排除扩展名条件 2021-12-12 16:14:56 +08:00
刘祥超
9a17adcc6f 请求条件增加不区分大小写选项 2021-12-12 16:11:25 +08:00
刘祥超
4dd6903025 优化界面 2021-12-12 11:58:16 +08:00
刘祥超
085770d0ad 实现请求连接数等限制/容量组件增加EB支持 2021-12-12 11:46:09 +08:00
刘祥超
fbaba7c37d 修复公共黑名单/白名单无法搜索的Bug 2021-12-10 11:12:49 +08:00
刘祥超
d5cea208d2 支持设置单节点最大线程数、单节点TCP最大连接数 2021-12-09 18:49:35 +08:00
刘祥超
36397adca4 修复服务统计图表颜色显示问题/Expires设置增加提示文字 2021-12-08 21:40:01 +08:00
刘祥超
4971e25d44 WAF看板最新拦截记录增加区域信息 2021-12-08 20:28:26 +08:00
刘祥超
150357441d 修复域名为空时点击审核页面为空的Bug 2021-12-08 20:20:10 +08:00
刘祥超
c4ee663285 重新生成components.js 2021-12-08 19:13:54 +08:00
刘祥超
8c95b4a9b9 多处访问日志增加单页显示条数选择 2021-12-08 19:13:34 +08:00
刘祥超
32ba919851 增加部分访问日志条数10->20 2021-12-08 17:49:30 +08:00
刘祥超
eb37345e85 可以在缓存条件里设置Expires Header 2021-12-08 17:41:12 +08:00
刘祥超
681e454917 修复编译时components.js可能没有更新的Bug 2021-12-08 10:03:27 +08:00
刘祥超
7c7b82dee4 优化地图标签 2021-12-08 09:37:46 +08:00
刘祥超
2ae47af8f0 增加批量增加节点IP接口 2021-12-07 18:22:46 +08:00
刘祥超
b72d91d0d4 访问日志实现记录和显示requestBody 2021-12-07 15:03:48 +08:00
刘祥超
56010e7203 缓存默认支持所有请求方法 2021-12-07 10:47:46 +08:00
刘祥超
f658698f7b 缓存支持请求方法设置 2021-12-07 10:45:49 +08:00
刘祥超
b708b9c6df 将缓存默认key改为${scheme}://${host}${requestPath}${isArgs}${args} 2021-12-07 10:04:50 +08:00
刘祥超
c2908e17fa SSH认证支持sudo 2021-12-06 19:24:30 +08:00
刘祥超
302daab824 服务看板增加区域地图 2021-12-06 09:16:23 +08:00
刘祥超
ec49f238d6 优化界面 2021-12-06 08:55:47 +08:00
刘祥超
3e43a5d866 上传components.js/优化地图样式 2021-12-05 20:59:07 +08:00
刘祥超
a99d5e68e9 商业版WAF看板增加地图 2021-12-05 19:38:14 +08:00
刘祥超
28514276ec 商业版首页增加地图/调低各个图表的高度,以便同时可以显示更多的图表 2021-12-05 18:59:20 +08:00
刘祥超
b611427c17 创建新服务时默认开启配置可以选择统计 2021-12-03 14:55:14 +08:00
刘祥超
ce7a4ead04 首页看板显示未审核的服务数、本周流量、昨日流量 2021-12-03 14:54:15 +08:00
刘祥超
5fe15a85fd 优化IPBox交互/优化TOA文字提示 2021-12-03 11:00:20 +08:00
刘祥超
ae412909f6 优化服务设置界面顶部菜单 2021-12-02 17:41:51 +08:00
刘祥超
c6ed579797 IPBox把IP加入黑名单可以选择过期时间/可以从已经添加的名单中删除/已经添加的名单中显示过期时间 2021-12-02 17:11:44 +08:00
刘祥超
b2a525268e WAF规则集中增加是否忽略局域网IP选项 2021-12-02 16:09:15 +08:00
刘祥超
eb78b4881c 多个提示页面增加请求ID 2021-12-02 14:45:51 +08:00
刘祥超
4ce6e5a9f6 访问日志弹窗中加入请求ID/优化Header添加/修改文字提示 2021-12-02 11:49:36 +08:00
刘祥超
15d7e75555 优化URL跳转文字提示 2021-12-02 10:39:22 +08:00
刘祥超
6453cc6ccc 缓存配置增加是否支持Cache-Control: max-age=... 2021-12-02 10:18:22 +08:00
刘祥超
d882a2eb63 缓存配置增加Age Header配置 2021-12-02 09:54:31 +08:00
刘祥超
065ac4aa25 增加generate.sh脚本用来生成文件 2021-12-02 09:46:46 +08:00
刘祥超
dea54fc55e 增加是否记录499选项 2021-12-01 21:13:15 +08:00
刘祥超
8f425bd9c7 当用户提交待审核域名时,给管理员发送消息 2021-12-01 17:19:50 +08:00
刘祥超
9d909d73b8 审核中服务增加提交审核时间/已通过域名标绿 2021-12-01 17:06:05 +08:00
刘祥超
b417d50a28 优化节点日志:可以批量设置服务错误日志为已修复等 2021-11-30 16:43:44 +08:00
刘祥超
aa93a2f702 优化编译脚本 2021-11-30 11:05:58 +08:00
刘祥超
ba7125e773 优化文字 2021-11-30 11:05:24 +08:00
刘祥超
46a7eaa4bb 商业版认证增加申请页面 2021-11-30 10:02:31 +08:00
刘祥超
887439a6fe 优化代码 2021-11-29 20:35:47 +08:00
刘祥超
0e2b07d06d 优化提示文字 2021-11-29 16:41:32 +08:00
刘祥超
b7d4bde11b 修改部分菜单名 2021-11-29 12:00:23 +08:00
刘祥超
9707360948 完善套餐 2021-11-28 20:11:48 +08:00
刘祥超
103a8eb092 修改版本号为0.3.7 2021-11-28 14:28:53 +08:00
刘祥超
dcba4f9376 节点同步不在图标上提示IP名单相关更新 2021-11-27 17:06:36 +08:00
刘祥超
12aaa6fcb1 更新生成的components.js 2021-11-27 17:06:03 +08:00
刘祥超
d8393481a4 修改域名变更时是否需要审核的初始状态 2021-11-25 12:10:23 +08:00
刘祥超
70d3202a2c 服务增加是否合并URL中的多余分隔符选项 2021-11-24 14:49:42 +08:00
刘祥超
c7f1bbc03d 版本号改为0.3.6 2021-11-24 14:03:56 +08:00
刘祥超
61a55cb3f4 优化命名 2021-11-24 11:58:01 +08:00
刘祥超
6a484af775 将版本修改为0.3.5.2 2021-11-24 10:29:59 +08:00
刘祥超
3074d41cf2 改进源站专属域名的文字提示和交互 2021-11-22 18:46:08 +08:00
刘祥超
54199058e3 修复服务无法创建的Bug 2021-11-22 14:34:32 +08:00
刘祥超
87a533791b 版本改为0.3.5.1 2021-11-22 14:34:20 +08:00
刘祥超
c3109bb2c6 编译时生成components.js 2021-11-22 12:08:53 +08:00
刘祥超
031cb836d2 安装时等API节点启动完毕后才进行下一步,避免因为未启动完整而导致的错误 2021-11-21 19:26:05 +08:00
刘祥超
aa0a9134cb 迁移后确认API节点界面可以跳转到安装界面 2021-11-21 19:25:42 +08:00
刘祥超
749eac74fe 当迁移了管理平台后,自动跳转到确认API配置页 2021-11-21 15:57:13 +08:00
刘祥超
ac39908737 优化删除IP时成功消息提示时间 2021-11-21 09:45:11 +08:00
刘祥超
bb8f4bf488 增加批量删除IP名单中的IP的功能 2021-11-21 09:43:14 +08:00
刘祥超
db0d157a74 修复时间输入组件时间戳总是多一秒的Bug 2021-11-21 08:44:03 +08:00
刘祥超
bd8e1bbe71 优化RPC客户端锁 2021-11-20 19:17:52 +08:00
刘祥超
7aba898cf5 优化文字 2021-11-20 19:17:16 +08:00
刘祥超
baf039755f 实现迁移辅助功能(系统设置 -- 高级设置 -- 迁移) 2021-11-20 18:58:58 +08:00
刘祥超
70977f7d80 IP地址“健康检查失败”阈值改为“健康检查结果” 2021-11-18 14:47:48 +08:00
刘祥超
884342d6af 节点IP阈值增加节点健康检查失败 2021-11-18 14:30:46 +08:00
刘祥超
411b0fb4c2 修复看板--事件中无法单条已读操作的Bug 2021-11-18 08:52:29 +08:00
刘祥超
8053fb2399 IP名单中显示已过期标签 2021-11-17 21:18:33 +08:00
刘祥超
ed42dcab9c IP名单增加是否只显示自动拦截名单选项 2021-11-17 20:25:31 +08:00
刘祥超
866b5b0f2f IP名单中增加搜索按钮 2021-11-17 20:15:37 +08:00
刘祥超
5834a1a0fa 增加全局查看、检索IP功能 2021-11-17 19:50:52 +08:00
刘祥超
8c6d845603 将公用IP名单默认改成全局名单,自动应用于所有服务 2021-11-17 16:14:37 +08:00
刘祥超
667f363f3c WAF block动作默认封锁范围为global 2021-11-16 19:17:08 +08:00
刘祥超
e209ff38d9 IP名单中显示IP创建时相关的服务、WAF策略等信息 2021-11-16 16:11:29 +08:00
刘祥超
ea915993b6 节点运行日志中显示相关服务链接 2021-11-15 16:51:39 +08:00
刘祥超
72d0468c6a IP名单中的IP增加添加日期显示 2021-11-15 11:31:54 +08:00
刘祥超
35ae13b1c3 优化缓存配置界面 2021-11-14 16:21:04 +08:00
刘祥超
1d9460f565 优化RPC连接 2021-11-10 22:22:27 +08:00
刘祥超
e9a3ed71b4 将带宽限制改为流量限制 2021-11-09 17:36:38 +08:00
刘祥超
e344e5b7e6 支持套餐相关操作 2021-11-09 15:36:18 +08:00
刘祥超
e814064403 编译时删除.js.map文件 2021-11-09 14:19:42 +08:00
刘祥超
f5aeb5cbcd 支持购买套餐/续费套餐/用户账户操作等 2021-11-08 20:52:02 +08:00
刘祥超
f41164b892 删除不需要的文件 2021-11-07 09:11:30 +08:00
刘祥超
03073c8364 删除不需要的文件 2021-11-07 08:42:11 +08:00
刘祥超
a359bff531 安装时自动检查服务器上安装的MySQL 2021-11-06 18:35:22 +08:00
刘祥超
3789ac6433 域名解析中可以删除和恢复某个域名 2021-11-06 16:23:38 +08:00
刘祥超
9f53f59f18 SSH登录支持Passphrase 2021-11-06 15:31:07 +08:00
刘祥超
521bd746e3 当证书被API节点或者用户节点使用时不允许删除/规范命名 2021-11-05 17:56:17 +08:00
刘祥超
3d8e43a42b 修改文字 2021-11-05 17:13:43 +08:00
刘祥超
9452e1852d 规范API命名 2021-11-05 15:34:48 +08:00
刘祥超
3920d24af6 只有一个可用的API节点时不允许删除 2021-11-05 15:29:37 +08:00
刘祥超
3af11e6ba8 修改版本号为0.3.5 2021-11-05 14:59:10 +08:00
刘祥超
7bcde46d49 修复缓存条件可能无法保存的Bug 2021-11-04 11:23:29 +08:00
刘祥超
0b73041718 支持info指令查询PID、版本号等信息 2021-11-04 11:13:54 +08:00
刘祥超
dcdc0cb8c1 修复无法设置缓存条件的Bug 2021-11-04 11:12:59 +08:00
刘祥超
ad6ac1aad6 优化安装程序 2021-11-01 21:09:52 +08:00
刘祥超
249dc6accd 修改版本为0.3.4 2021-11-01 10:45:41 +08:00
469 changed files with 20992 additions and 3431 deletions

View File

@@ -20,6 +20,18 @@ function build() {
TAG="community"
fi
# checking environment
echo "checking required commands ..."
commands=("zip" "unzip" "go" "find" "sed")
for cmd in "${commands[@]}"; do
if [ `which ${cmd}` ]; then
echo "checking ${cmd}: ok"
else
echo "checking ${cmd}: not found"
return
fi
done
VERSION=$(lookup-version $ROOT/../internal/const/const.go)
ZIP="${NAME}-${OS}-${ARCH}-${TAG}-v${VERSION}.zip"
@@ -38,6 +50,10 @@ function build() {
echo "=============================="
cd -
# generate files
echo "generating files ..."
go run -tags $TAG $ROOT/../cmd/edge-admin/main.go generate
# create dir & copy files
echo "copying ..."
if [ ! -d $DIST ]; then
@@ -51,6 +67,19 @@ function build() {
rm -f $DIST/web/tmp/*
cp $ROOT/configs/server.template.yaml $DIST/configs/
# change _plus.[ext] to .[ext]
if [ "${TAG}" = "plus" ]; then
echo "converting filenames ..."
exts=("html" "js" "css")
for ext in "${exts[@]}"; do
pattern="*_plus."${ext}
find $DIST/web/views -type f -name $pattern | \
while read filename; do
mv ${filename} "${filename/_plus."${ext}"/."${ext}"}"
done
done
fi
EDGE_API_ZIP_FILE=$ROOT"/../../EdgeAPI/dist/edge-api-${OS}-${ARCH}-${TAG}-v${APINodeVersion}.zip"
cp $EDGE_API_ZIP_FILE $DIST/
cd $DIST/
@@ -67,6 +96,7 @@ function build() {
find $DIST -name ".gitignore" -delete
find $DIST -name "*.less" -delete
find $DIST -name "*.css.map" -delete
find $DIST -name "*.js.map" -delete
# zip
echo "zip files ..."

3
build/generate.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env bash
go run -tags=community ../cmd/edge-admin/main.go generate

View File

@@ -5,6 +5,7 @@ import (
"github.com/TeaOSLab/EdgeAdmin/internal/apps"
"github.com/TeaOSLab/EdgeAdmin/internal/configs"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/TeaOSLab/EdgeAdmin/internal/gen"
"github.com/TeaOSLab/EdgeAdmin/internal/nodes"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web"
_ "github.com/iwind/TeaGo/bootstrap"
@@ -70,6 +71,13 @@ func main() {
}
fmt.Println("change demo mode successfully")
})
app.On("generate", func() {
err := gen.Generate()
if err != nil {
fmt.Println("generate failed: " + err.Error())
return
}
})
app.Run(func() {
adminNode := nodes.NewAdminNode()
adminNode.Run()

2
go.mod
View File

@@ -11,7 +11,7 @@ require (
github.com/go-yaml/yaml v2.1.0+incompatible
github.com/google/go-cmp v0.5.6 // indirect
github.com/iwind/TeaGo v0.0.0-20211026123858-7de7a21cad24
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3
github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4
github.com/json-iterator/go v1.1.12 // indirect
github.com/miekg/dns v1.1.35
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect

2
go.sum
View File

@@ -68,6 +68,8 @@ github.com/iwind/TeaGo v0.0.0-20211026123858-7de7a21cad24 h1:1cGulkD2SNJJRok5OKw
github.com/iwind/TeaGo v0.0.0-20211026123858-7de7a21cad24/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3 h1:aBSonas7vFcgTj9u96/bWGILGv1ZbUSTLiOzcI1ZT6c=
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4 h1:VWGsCqTzObdlbf7UUE3oceIpcEKi4C/YBUszQXk118A=
github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=

View File

@@ -11,7 +11,9 @@ import (
var plusConfigFile = "plus.cache.json"
type PlusConfig struct {
IsPlus bool `json:"isPlus"`
IsPlus bool `json:"isPlus"`
Components []string `json:"components"`
DayTo string `json:"dayTo"`
}
func ReadPlusConfig() *PlusConfig {

View File

@@ -1,9 +1,9 @@
package teaconst
const (
Version = "0.3.3"
Version = "0.3.7"
APINodeVersion = "0.3.3"
APINodeVersion = "0.3.7"
ProductName = "Edge Admin"
ProcessName = "edge-admin"
@@ -18,4 +18,5 @@ const (
CookieSID = "edgesid"
SystemdServiceName = "edge-admin"
UpdatesURL = "https://goedge.cn/api/boot/versions?os=${os}&arch=${arch}"
)

View File

@@ -1,6 +1,7 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build community
// +build community
package teaconst
// IsPlus 是否为企业版
var IsPlus = false

129
internal/gen/generate.go Normal file
View File

@@ -0,0 +1,129 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package gen
import (
"bytes"
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/conds/condutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/files"
"github.com/iwind/TeaGo/logs"
"io"
"os"
"path/filepath"
)
func Generate() error {
err := generateComponentsJSFile()
if err != nil {
return errors.New("generate 'components.js' failed: " + err.Error())
}
return nil
}
// 生成Javascript文件
func generateComponentsJSFile() error {
var buffer = bytes.NewBuffer([]byte{})
var webRoot string
if Tea.IsTesting() {
webRoot = Tea.Root + "/../web/public/js/components/"
} else {
webRoot = Tea.Root + "/web/public/js/components/"
}
f := files.NewFile(webRoot)
f.Range(func(file *files.File) {
if !file.IsFile() {
return
}
if file.Ext() != ".js" {
return
}
data, err := file.ReadAll()
if err != nil {
logs.Error(err)
return
}
buffer.Write(data)
buffer.Write([]byte{'\n', '\n'})
})
// 条件组件
typesJSON, err := json.Marshal(condutils.ReadAllAvailableCondTypes())
if err != nil {
logs.Println("ComponentsAction marshal request cond types failed: " + err.Error())
} else {
buffer.WriteString("window.REQUEST_COND_COMPONENTS = ")
buffer.Write(typesJSON)
buffer.Write([]byte{'\n', '\n'})
}
// 条件操作符
requestOperatorsJSON, err := json.Marshal(shared.AllRequestOperators())
if err != nil {
logs.Println("ComponentsAction marshal request operators failed: " + err.Error())
} else {
buffer.WriteString("window.REQUEST_COND_OPERATORS = ")
buffer.Write(requestOperatorsJSON)
buffer.Write([]byte{'\n', '\n'})
}
// 请求变量
requestVariablesJSON, err := json.Marshal(shared.DefaultRequestVariables())
if err != nil {
logs.Println("ComponentsAction marshal request variables failed: " + err.Error())
} else {
buffer.WriteString("window.REQUEST_VARIABLES = ")
buffer.Write(requestVariablesJSON)
buffer.Write([]byte{'\n', '\n'})
}
// 指标
metricHTTPKeysJSON, err := json.Marshal(serverconfigs.FindAllMetricKeyDefinitions(serverconfigs.MetricItemCategoryHTTP))
if err != nil {
logs.Println("ComponentsAction marshal metric http keys failed: " + err.Error())
} else {
buffer.WriteString("window.METRIC_HTTP_KEYS = ")
buffer.Write(metricHTTPKeysJSON)
buffer.Write([]byte{'\n', '\n'})
}
// IP地址阈值项目
ipAddrThresholdItemsJSON, err := json.Marshal(nodeconfigs.FindAllIPAddressThresholdItems())
if err != nil {
logs.Println("ComponentsAction marshal ip addr threshold items failed: " + err.Error())
} else {
buffer.WriteString("window.IP_ADDR_THRESHOLD_ITEMS = ")
buffer.Write(ipAddrThresholdItemsJSON)
buffer.Write([]byte{'\n', '\n'})
}
// IP地址阈值动作
ipAddrThresholdActionsJSON, err := json.Marshal(nodeconfigs.FindAllIPAddressThresholdActions())
if err != nil {
logs.Println("ComponentsAction marshal ip addr threshold actions failed: " + err.Error())
} else {
buffer.WriteString("window.IP_ADDR_THRESHOLD_ACTIONS = ")
buffer.Write(ipAddrThresholdActionsJSON)
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)
if err != nil {
return err
}
_, err = io.Copy(fp, buffer)
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,13 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package gen
import "testing"
func TestGenerate(t *testing.T) {
err := Generate()
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}

View File

@@ -326,6 +326,16 @@ func (this *AdminNode) listenSock() error {
case "demo":
teaconst.IsDemoMode = !teaconst.IsDemoMode
_ = cmd.ReplyOk()
case "info":
exePath, _ := os.Executable()
_ = cmd.Reply(&gosock.Command{
Code: "info",
Params: map[string]interface{}{
"pid": os.Getpid(),
"version": teaconst.Version,
"path": exePath,
},
})
}
})

View File

@@ -27,11 +27,11 @@ type RPCClient struct {
apiConfig *configs.APIConfig
conns []*grpc.ClientConn
locker sync.Mutex
locker sync.RWMutex
}
// NewRPCClient 构造新的RPC客户端
func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
func NewRPCClient(apiConfig *configs.APIConfig, isPrimary bool) (*RPCClient, error) {
if apiConfig == nil {
return nil, errors.New("api config should not be nil")
}
@@ -46,7 +46,9 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
}
// 设置RPC
dao.SetRPC(client)
if isPrimary {
dao.SetRPC(client)
}
return client, nil
}
@@ -380,6 +382,18 @@ func (this *RPCClient) UserBillRPC() pb.UserBillServiceClient {
return pb.NewUserBillServiceClient(this.pickConn())
}
func (this *RPCClient) UserAccountRPC() pb.UserAccountServiceClient {
return pb.NewUserAccountServiceClient(this.pickConn())
}
func (this *RPCClient) UserAccountLogRPC() pb.UserAccountLogServiceClient {
return pb.NewUserAccountLogServiceClient(this.pickConn())
}
func (this *RPCClient) UserAccountDailyStatRPC() pb.UserAccountDailyStatServiceClient {
return pb.NewUserAccountDailyStatServiceClient(this.pickConn())
}
func (this *RPCClient) UserAccessKeyRPC() pb.UserAccessKeyServiceClient {
return pb.NewUserAccessKeyServiceClient(this.pickConn())
}
@@ -521,7 +535,11 @@ func (this *RPCClient) APIContext(apiNodeId int64) context.Context {
// UpdateConfig 修改配置
func (this *RPCClient) UpdateConfig(config *configs.APIConfig) error {
this.apiConfig = config
return this.init()
this.locker.Lock()
err := this.init()
this.locker.Unlock()
return err
}
// 初始化
@@ -599,3 +617,20 @@ func (this *RPCClient) pickConn() *grpc.ClientConn {
return this.conns[rands.Int(0, len(this.conns)-1)]
}
// Close 关闭
func (this *RPCClient) Close() error {
this.locker.Lock()
defer this.locker.Unlock()
var lastErr error
for _, conn := range this.conns {
var err = conn.Close()
if err != nil {
lastErr = err
continue
}
}
return lastErr
}

View File

@@ -18,7 +18,7 @@ func TestRPCClient_NodeRPC(t *testing.T) {
if err != nil {
t.Fatal(err)
}
rpc, err := NewRPCClient(config)
rpc, err := NewRPCClient(config, true)
if err != nil {
t.Fatal(err)
}
@@ -41,7 +41,7 @@ func TestRPC_Dial_HTTP(t *testing.T) {
},
NodeId: "a7e55782dab39bce0901058a1e14a0e6",
Secret: "lvyPobI3BszkJopz5nPTocOs0OLkEJ7y",
})
}, true)
if err != nil {
t.Fatal(err)
}
@@ -62,7 +62,7 @@ func TestRPC_Dial_HTTP_2(t *testing.T) {
},
NodeId: "a7e55782dab39bce0901058a1e14a0e6",
Secret: "lvyPobI3BszkJopz5nPTocOs0OLkEJ7y",
})
}, true)
if err != nil {
t.Fatal(err)
}
@@ -83,7 +83,7 @@ func TestRPC_Dial_HTTPS(t *testing.T) {
},
NodeId: "a7e55782dab39bce0901058a1e14a0e6",
Secret: "lvyPobI3BszkJopz5nPTocOs0OLkEJ7y",
})
}, true)
if err != nil {
t.Fatal(err)
}

View File

@@ -20,7 +20,7 @@ func SharedRPC() (*RPCClient, error) {
if err != nil {
return nil, err
}
client, err := NewRPCClient(config)
client, err := NewRPCClient(config, true)
if err != nil {
return nil, err
}

View File

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

View File

@@ -66,7 +66,7 @@ func (this *SyncAPINodesTask) Loop() error {
}
newEndpoints := []string{}
for _, node := range resp.Nodes {
for _, node := range resp.ApiNodes {
if !node.IsOn {
continue
}

View File

@@ -51,7 +51,7 @@ func (this *SyncClusterTask) loop() error {
}
ctx := rpcClient.Context(0)
tasksResp, err := rpcClient.NodeTaskRPC().FindNotifyingNodeTasks(ctx, &pb.FindNotifyingNodeTasksRequest{Size: 100})
tasksResp, err := rpcClient.NodeTaskRPC().FindNotifyingNodeTasks(ctx, &pb.FindNotifyingNodeTasksRequest{Size: 500})
if err != nil {
return err
}

View File

@@ -1,14 +1,17 @@
package utils
import (
"bytes"
"encoding/binary"
"errors"
"github.com/iwind/TeaGo/types"
"math/big"
"net"
"regexp"
"strings"
)
// 将IP转换为整型
// IP2Long 将IP转换为整型
func IP2Long(ip string) uint64 {
s := net.ParseIP(ip)
if len(s) != 16 {
@@ -23,7 +26,7 @@ func IP2Long(ip string) uint64 {
return uint64(binary.BigEndian.Uint32(s.To4()))
}
// 判断是否为IPv4
// IsIPv4 判断是否为IPv4
func IsIPv4(ip string) bool {
if !regexp.MustCompile(`^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$`).MatchString(ip) {
return false
@@ -34,10 +37,100 @@ func IsIPv4(ip string) bool {
return true
}
// 判断是否为IPv6
// IsIPv6 判断是否为IPv6
func IsIPv6(ip string) bool {
if !strings.Contains(ip, ":") {
return false
}
return len(net.ParseIP(ip)) == net.IPv6len
}
// ExtractIP 分解IP
// 只支持D段掩码的CIDR
// 最多只记录255个值
func ExtractIP(ipStrings string) ([]string, error) {
ipStrings = strings.ReplaceAll(ipStrings, " ", "")
// CIDR
if strings.Contains(ipStrings, "/") {
_, cidrNet, err := net.ParseCIDR(ipStrings)
if err != nil {
return nil, err
}
var index = strings.Index(ipStrings, "/")
var ipFrom = ipStrings[:index]
var bits = types.Int(ipStrings[index+1:])
if bits < 24 {
return nil, errors.New("CIDR bits should be greater than 24")
}
var ipv4 = net.ParseIP(ipFrom).To4()
if len(ipv4) == 0 {
return nil, errors.New("support IPv4 only")
}
var result = []string{}
ipv4[3] = 0 // 从0开始
for i := 0; i <= 255; i++ {
if cidrNet.Contains(ipv4) {
result = append(result, ipv4.String())
}
ipv4 = NextIP(ipv4)
}
return result, nil
}
// IP Range
if strings.Contains(ipStrings, "-") {
var index = strings.Index(ipStrings, "-")
var ipFromString = ipStrings[:index]
var ipToString = ipStrings[index+1:]
var ipFrom = net.ParseIP(ipFromString).To4()
if len(ipFrom) == 0 {
return nil, errors.New("invalid ip '" + ipFromString + "'")
}
var ipTo = net.ParseIP(ipToString).To4()
if len(ipTo) == 0 {
return nil, errors.New("invalid ip '" + ipToString + "'")
}
if bytes.Compare(ipFrom, ipTo) > 0 {
ipFrom, ipTo = ipTo, ipFrom
}
var result = []string{}
for i := 0; i < 255; i++ {
if bytes.Compare(ipFrom, ipTo) > 0 {
break
}
result = append(result, ipFrom.String())
ipFrom = NextIP(ipFrom)
}
return result, nil
}
return []string{ipStrings}, nil
}
// NextIP IP增加1
func NextIP(prevIP net.IP) net.IP {
var ip = make(net.IP, len(prevIP))
copy(ip, prevIP)
var index = len(ip) - 1
for {
if ip[index] == 255 {
ip[index] = 0
index--
if index < 0 {
break
}
} else {
ip[index]++
break
}
}
return ip
}

View File

@@ -1,6 +1,7 @@
package utils
import (
"net"
"testing"
)
@@ -83,3 +84,27 @@ func TestIsIPv6(t *testing.T) {
}
}
}
func TestExtractIP(t *testing.T) {
t.Log(ExtractIP("192.168.1.100"))
}
func TestExtractIP_CIDR(t *testing.T) {
t.Log(ExtractIP("192.168.2.100/24"))
}
func TestExtractIP_Range(t *testing.T) {
t.Log(ExtractIP("192.168.2.100 - 192.168.4.2"))
}
func TestNextIP(t *testing.T) {
for _, ip := range []string{"192.168.1.1", "0.0.0.0", "255.255.255.255", "192.168.2.255", "192.168.255.255"} {
t.Log(ip+":", NextIP(net.ParseIP(ip).To4()))
}
}
func TestNextIP_Copy(t *testing.T) {
var ip = net.ParseIP("192.168.1.100")
var nextIP = NextIP(ip)
t.Log(ip, nextIP)
}

View File

@@ -13,38 +13,30 @@ func FormatInt(value int) string {
return strconv.Itoa(value)
}
func FormatBytes(bytes int64) string {
if bytes < 1024 {
return FormatInt64(bytes) + "B"
} else if bytes < 1024*1024 {
return fmt.Sprintf("%.2fKB", float64(bytes)/1024)
} else if bytes < 1024*1024*1024 {
return fmt.Sprintf("%.2fMB", float64(bytes)/1024/1024)
} else if bytes < 1024*1024*1024*1024 {
return fmt.Sprintf("%.2fGB", float64(bytes)/1024/1024/1024)
} else if bytes < 1024*1024*1024*1024*1024 {
return fmt.Sprintf("%.2fTB", float64(bytes)/1024/1024/1024/1024)
} else if bytes < 1024*1024*1024*1024*1024*1024 {
return fmt.Sprintf("%.2fPB", float64(bytes)/1024/1024/1024/1024/1024)
} else {
return fmt.Sprintf("%.2fEB", float64(bytes)/1024/1024/1024/1024/1024/1024)
func Pow1024(n int) int64 {
if n <= 0 {
return 1
}
if n == 1 {
return 1024
}
return Pow1024(n-1) * 1024
}
func FormatBits(bits int64) string {
if bits < 1000 {
return FormatInt64(bits) + "B"
} else if bits < 1000*1000 {
return fmt.Sprintf("%.2fKB", float64(bits)/1000)
} else if bits < 1000*1000*1000 {
return fmt.Sprintf("%.2fMB", float64(bits)/1000/1000)
} else if bits < 1000*1000*1000*1000 {
return fmt.Sprintf("%.2fGB", float64(bits)/1000/1000/1000)
} else if bits < 1000*1000*1000*1000*1000 {
return fmt.Sprintf("%.2fTB", float64(bits)/1000/1000/1000/1000)
} else if bits < 1000*1000*1000*1000*1000*1000 {
return fmt.Sprintf("%.2fPB", float64(bits)/1000/1000/1000/1000/1000)
func FormatBytes(bytes int64) string {
if bytes < Pow1024(1) {
return FormatInt64(bytes) + "B"
} else if bytes < Pow1024(2) {
return fmt.Sprintf("%.2fKB", float64(bytes)/float64(Pow1024(1)))
} else if bytes < Pow1024(3) {
return fmt.Sprintf("%.2fMB", float64(bytes)/float64(Pow1024(2)))
} else if bytes < Pow1024(4) {
return fmt.Sprintf("%.2fGB", float64(bytes)/float64(Pow1024(3)))
} else if bytes < Pow1024(5) {
return fmt.Sprintf("%.2fTB", float64(bytes)/float64(Pow1024(4)))
} else if bytes < Pow1024(6) {
return fmt.Sprintf("%.2fPB", float64(bytes)/float64(Pow1024(5)))
} else {
return fmt.Sprintf("%.2fEB", float64(bits)/1000/1000/1000/1000/1000/1000)
return fmt.Sprintf("%.2fEB", float64(bytes)/float64(Pow1024(6)))
}
}

View File

@@ -0,0 +1,16 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package numberutils
import "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))
}

View File

@@ -13,16 +13,35 @@ type DeleteAction struct {
func (this *DeleteAction) RunPost(params struct {
NodeId int64
}) {
// TODO 检查权限
// 创建日志
defer this.CreateLog(oplogs.LevelInfo, "删除API节点 %d", params.NodeId)
_, err := this.RPC().APINodeRPC().DeleteAPINode(this.AdminContext(), &pb.DeleteAPINodeRequest{NodeId: params.NodeId})
// 检查是否是唯一的节点
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ApiNodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
var apiNode = nodeResp.ApiNode
if apiNode == nil {
this.Success()
}
if apiNode.IsOn {
countResp, err := this.RPC().APINodeRPC().CountAllEnabledAndOnAPINodes(this.AdminContext(), &pb.CountAllEnabledAndOnAPINodesRequest{})
if err != nil {
this.ErrorPage(err)
return
}
if countResp.Count == 1 {
this.Fail("无法删除此节点必须保留至少一个可用的API节点")
}
}
_, err = this.RPC().APINodeRPC().DeleteAPINode(this.AdminContext(), &pb.DeleteAPINodeRequest{ApiNodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
// 创建日志
defer this.CreateLog(oplogs.LevelInfo, "删除API节点 %d", params.NodeId)
this.Success()
}

View File

@@ -41,7 +41,7 @@ func (this *IndexAction) RunGet(params struct{}) {
return
}
for _, node := range nodesResp.Nodes {
for _, node := range nodesResp.ApiNodes {
// 状态
status := &nodeconfigs.NodeStatus{}
if len(node.StatusJSON) > 0 {

View File

@@ -180,7 +180,7 @@ func (this *CreatePopupAction) RunPost(params struct {
}
// 创建日志
defer this.CreateLog(oplogs.LevelInfo, "创建API节点 %d", createResp.NodeId)
defer this.CreateLog(oplogs.LevelInfo, "创建API节点 %d", createResp.ApiNodeId)
this.Success()
}

View File

@@ -20,12 +20,12 @@ func (this *IndexAction) Init() {
func (this *IndexAction) RunGet(params struct {
NodeId int64
}) {
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ApiNodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
node := nodeResp.Node
node := nodeResp.ApiNode
if node == nil {
this.NotFound("apiNode", params.NodeId)
return

View File

@@ -21,12 +21,12 @@ func (this *InstallAction) RunGet(params struct {
NodeId int64
}) {
// API节点信息
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ApiNodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
node := nodeResp.Node
node := nodeResp.ApiNode
if node == nil {
this.NotFound("apiNode", params.NodeId)
return

View File

@@ -31,12 +31,12 @@ func (this *LogsAction) RunGet(params struct {
this.Data["keyword"] = params.Keyword
this.Data["level"] = params.Level
apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ApiNodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
apiNode := apiNodeResp.Node
apiNode := apiNodeResp.ApiNode
if apiNode == nil {
this.NotFound("apiNode", params.NodeId)
return

View File

@@ -23,13 +23,13 @@ func (this *UpdateAction) RunGet(params struct {
NodeId int64
}) {
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{
NodeId: params.NodeId,
ApiNodeId: params.NodeId,
})
if err != nil {
this.ErrorPage(err)
return
}
node := nodeResp.Node
node := nodeResp.ApiNode
if node == nil {
this.WriteString("要操作的节点不存在")
return
@@ -281,7 +281,7 @@ func (this *UpdateAction) RunPost(params struct {
}
_, err = this.RPC().APINodeRPC().UpdateAPINode(this.AdminContext(), &pb.UpdateAPINodeRequest{
NodeId: params.NodeId,
ApiNodeId: params.NodeId,
Name: params.Name,
Description: params.Description,
HttpJSON: httpJSON,

View File

@@ -3,6 +3,7 @@ package cluster
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
@@ -75,7 +76,7 @@ func (this *CreateNodeAction) RunGet(params struct {
this.ErrorPage(err)
return
}
apiNodes := apiNodesResp.Nodes
apiNodes := apiNodesResp.ApiNodes
apiEndpoints := []string{}
for _, apiNode := range apiNodes {
if !apiNode.IsOn {
@@ -167,9 +168,13 @@ func (this *CreateNodeAction) RunPost(params struct {
nodeId := createResp.NodeId
// IP地址
var resultIPAddresses = []string{}
for _, addr := range ipAddresses {
var resultAddrIds = []int64{}
addrId := addr.GetInt64("id")
if addrId > 0 {
resultAddrIds = append(resultAddrIds, addrId)
_, err = this.RPC().NodeIPAddressRPC().UpdateNodeIPAddressNodeId(this.AdminContext(), &pb.UpdateNodeIPAddressNodeIdRequest{
NodeIPAddressId: addrId,
NodeId: nodeId,
@@ -178,20 +183,50 @@ func (this *CreateNodeAction) RunPost(params struct {
this.ErrorPage(err)
return
}
resultIPAddresses = append(resultIPAddresses, addr.GetString("ip"))
} else {
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
NodeId: nodeId,
Role: nodeconfigs.NodeRoleNode,
Name: addr.GetString("name"),
Ip: addr.GetString("ip"),
CanAccess: addr.GetBool("canAccess"),
IsUp: addr.GetBool("isUp"),
})
var ipStrings = addr.GetString("ip")
result, err := utils.ExtractIP(ipStrings)
if err != nil {
this.ErrorPage(err)
return
this.Fail("节点创建成功但是保存IP失败" + err.Error())
}
resultIPAddresses = append(resultIPAddresses, result...)
if len(result) == 1 {
// 单个创建
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
NodeId: nodeId,
Role: nodeconfigs.NodeRoleNode,
Name: addr.GetString("name"),
Ip: result[0],
CanAccess: addr.GetBool("canAccess"),
IsUp: addr.GetBool("isUp"),
})
if err != nil {
this.ErrorPage(err)
return
}
addrId = createResp.NodeIPAddressId
resultAddrIds = append(resultAddrIds, addrId)
} else if len(result) > 1 {
// 批量创建
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddresses(this.AdminContext(), &pb.CreateNodeIPAddressesRequest{
NodeId: nodeId,
Role: nodeconfigs.NodeRoleNode,
Name: addr.GetString("name"),
IpList: result,
CanAccess: addr.GetBool("canAccess"),
IsUp: addr.GetBool("isUp"),
GroupValue: ipStrings,
})
if err != nil {
this.ErrorPage(err)
return
}
resultAddrIds = append(resultAddrIds, createResp.NodeIPAddressIds...)
}
addrId = createResp.NodeIPAddressId
}
// 阈值
@@ -202,13 +237,16 @@ func (this *CreateNodeAction) RunPost(params struct {
this.ErrorPage(err)
return
}
_, err = this.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(this.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
NodeIPAddressId: addrId,
NodeIPAddressThresholdsJSON: thresholdsJSON,
})
if err != nil {
this.ErrorPage(err)
return
for _, addrId := range resultAddrIds {
_, err = this.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(this.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
NodeIPAddressId: addrId,
NodeIPAddressThresholdsJSON: thresholdsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
}
}
}
@@ -224,11 +262,6 @@ func (this *CreateNodeAction) RunPost(params struct {
return
}
if nodeResp.Node != nil {
var addresses = []string{}
for _, addrMap := range ipAddresses {
addresses = append(addresses, addrMap.GetString("ip"))
}
var grantMap maps.Map = nil
grantId := params.GrantId
if grantId > 0 {
@@ -253,7 +286,7 @@ func (this *CreateNodeAction) RunPost(params struct {
"name": nodeResp.Node.Name,
"uniqueId": nodeResp.Node.UniqueId,
"secret": nodeResp.Node.Secret,
"addresses": addresses,
"addresses": resultIPAddresses,
"login": maps.Map{
"id": 0,
"name": "SSH",

View File

@@ -49,7 +49,7 @@ func (this *InstallNodesAction) RunGet(params struct {
this.ErrorPage(err)
return
}
for _, apiNode := range apiNodesResp.Nodes {
for _, apiNode := range apiNodesResp.ApiNodes {
if !apiNode.IsOn {
continue
}

View File

@@ -86,9 +86,16 @@ func (this *DetailAction) RunGet(params struct {
return
}
// 是否有备用IP
var originIP = addr.Ip
if len(addr.BackupIP) > 0 {
addr.Ip = addr.BackupIP
}
ipAddressMaps = append(ipAddressMaps, maps.Map{
"id": addr.Id,
"name": addr.Name,
"originIP": originIP,
"ip": addr.Ip,
"canAccess": addr.CanAccess,
"isOn": addr.IsOn,

View File

@@ -70,7 +70,7 @@ func (this *InstallAction) RunGet(params struct {
this.ErrorPage(err)
return
}
apiNodes := apiNodesResp.Nodes
apiNodes := apiNodesResp.ApiNodes
apiEndpoints := []string{}
for _, apiNode := range apiNodes {
if !apiNode.IsOn {

View File

@@ -69,6 +69,20 @@ func (this *LogsAction) RunGet(params struct {
logs := []maps.Map{}
for _, log := range logsResp.NodeLogs {
// 服务信息
var serverMap = maps.Map{"id": 0}
if log.ServerId > 0 {
serverResp, err := this.RPC().ServerRPC().FindEnabledUserServerBasic(this.AdminContext(), &pb.FindEnabledUserServerBasicRequest{ServerId: log.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
var server = serverResp.Server
if server != nil {
serverMap = maps.Map{"id": server.Id, "name": server.Name}
}
}
logs = append(logs, maps.Map{
"tag": log.Tag,
"description": log.Description,
@@ -76,6 +90,7 @@ func (this *LogsAction) RunGet(params struct {
"level": log.Level,
"isToday": timeutil.FormatTime("Y-m-d", log.CreatedAt) == timeutil.Format("Y-m-d"),
"count": log.Count,
"server": serverMap,
})
}
this.Data["logs"] = logs

View File

@@ -8,6 +8,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 IndexAction struct {
@@ -65,22 +66,32 @@ func (this *IndexAction) RunGet(params struct {
this.Data["timeZoneLocation"] = nodeconfigs.FindTimeZoneLocation(cluster.TimeZone)
this.Data["cluster"] = maps.Map{
"id": cluster.Id,
"name": cluster.Name,
"installDir": cluster.InstallDir,
"timeZone": cluster.TimeZone,
"id": cluster.Id,
"name": cluster.Name,
"installDir": cluster.InstallDir,
"timeZone": cluster.TimeZone,
"nodeMaxThreads": cluster.NodeMaxThreads,
"nodeTCPMaxConnections": cluster.NodeTCPMaxConnections,
}
// 默认值
this.Data["defaultNodeMaxThreads"] = nodeconfigs.DefaultMaxThreads
this.Data["defaultNodeMaxThreadsMin"] = nodeconfigs.DefaultMaxThreadsMin
this.Data["defaultNodeMaxThreadsMax"] = nodeconfigs.DefaultMaxThreadsMax
this.Data["defaultNodeTCPMaxConnections"] = nodeconfigs.DefaultTCPMaxConnections
this.Show()
}
// RunPost 保存设置
func (this *IndexAction) RunPost(params struct {
ClusterId int64
Name string
GrantId int64
InstallDir string
TimeZone string
ClusterId int64
Name string
GrantId int64
InstallDir string
TimeZone string
NodeMaxThreads int32
NodeTCPMaxConnections int32
Must *actions.Must
}) {
@@ -91,12 +102,21 @@ func (this *IndexAction) RunPost(params struct {
Field("name", params.Name).
Require("请输入集群名称")
if params.NodeMaxThreads > 0 {
params.Must.
Field("nodeMaxThreads", params.NodeMaxThreads).
Gte(int64(nodeconfigs.DefaultMaxThreadsMin), "单节点最大线程数最小值不能小于"+types.String(nodeconfigs.DefaultMaxThreadsMin)).
Lte(int64(nodeconfigs.DefaultMaxThreadsMax), "单节点最大线程数最大值不能大于"+types.String(nodeconfigs.DefaultMaxThreadsMax))
}
_, err := this.RPC().NodeClusterRPC().UpdateNodeCluster(this.AdminContext(), &pb.UpdateNodeClusterRequest{
NodeClusterId: params.ClusterId,
Name: params.Name,
NodeGrantId: params.GrantId,
InstallDir: params.InstallDir,
TimeZone: params.TimeZone,
NodeClusterId: params.ClusterId,
Name: params.Name,
NodeGrantId: params.GrantId,
InstallDir: params.InstallDir,
TimeZone: params.TimeZone,
NodeMaxThreads: params.NodeMaxThreads,
NodeTCPMaxConnections: params.NodeTCPMaxConnections,
})
if err != nil {
this.ErrorPage(err)

View File

@@ -28,7 +28,9 @@ func (this *CreateAction) RunPost(params struct {
Username string
Password string
PrivateKey string
Passphrase string
Description string
Su bool
Must *actions.Must
}) {
@@ -58,7 +60,9 @@ func (this *CreateAction) RunPost(params struct {
Username: params.Username,
Password: params.Password,
PrivateKey: params.PrivateKey,
Passphrase: params.Passphrase,
Description: params.Description,
Su: params.Su,
NodeId: 0,
})
if err != nil {

View File

@@ -29,7 +29,9 @@ func (this *CreatePopupAction) RunPost(params struct {
Username string
Password string
PrivateKey string
Passphrase string
Description string
Su bool
Must *actions.Must
}) {
@@ -59,7 +61,9 @@ func (this *CreatePopupAction) RunPost(params struct {
Username: params.Username,
Password: params.Password,
PrivateKey: params.PrivateKey,
Passphrase: params.Passphrase,
Description: params.Description,
Su: params.Su,
NodeId: 0,
})
if err != nil {
@@ -72,6 +76,7 @@ func (this *CreatePopupAction) RunPost(params struct {
"name": params.Name,
"method": params.Method,
"methodName": grantutils.FindGrantMethodName(params.Method),
"username": params.Username,
}
// 创建日志

View File

@@ -40,6 +40,7 @@ func (this *GrantAction) RunGet(params struct {
"username": grant.Username,
"password": strings.Repeat("*", len(grant.Password)),
"privateKey": grant.PrivateKey,
"passphrase": strings.Repeat("*", len(grant.Passphrase)),
"description": grant.Description,
"su": grant.Su,
}

View File

@@ -43,6 +43,7 @@ func (this *UpdateAction) RunGet(params struct {
"username": grant.Username,
"password": grant.Password,
"privateKey": grant.PrivateKey,
"passphrase": grant.Passphrase,
"description": grant.Description,
"su": grant.Su,
}
@@ -57,7 +58,9 @@ func (this *UpdateAction) RunPost(params struct {
Username string
Password string
PrivateKey string
Passphrase string
Description string
Su bool
Must *actions.Must
}) {
@@ -93,7 +96,9 @@ func (this *UpdateAction) RunPost(params struct {
Username: params.Username,
Password: params.Password,
PrivateKey: params.PrivateKey,
Passphrase: params.Passphrase,
Description: params.Description,
Su: params.Su,
NodeId: 0,
})
if err != nil {

View File

@@ -43,6 +43,8 @@ func (this *UpdatePopupAction) RunGet(params struct {
"password": grant.Password,
"description": grant.Description,
"privateKey": grant.PrivateKey,
"passphrase": grant.Passphrase,
"su": grant.Su,
}
this.Show()
@@ -56,7 +58,9 @@ func (this *UpdatePopupAction) RunPost(params struct {
Username string
Password string
PrivateKey string
Passphrase string
Description string
Su bool
Must *actions.Must
}) {
@@ -91,8 +95,10 @@ func (this *UpdatePopupAction) RunPost(params struct {
Username: params.Username,
Password: params.Password,
PrivateKey: params.PrivateKey,
Passphrase: params.Passphrase,
Description: params.Description,
NodeId: params.NodeId,
Su: params.Su,
})
if err != nil {
this.ErrorPage(err)
@@ -105,6 +111,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
"name": params.Name,
"method": params.Method,
"methodName": grantutils.FindGrantMethodName(params.Method),
"username": params.Username,
}
this.Success()

View File

@@ -90,6 +90,20 @@ func (this *IndexAction) RunGet(params struct {
continue
}
// 服务信息
var serverMap = maps.Map{"id": 0}
if log.ServerId > 0 {
serverResp, err := this.RPC().ServerRPC().FindEnabledUserServerBasic(this.AdminContext(), &pb.FindEnabledUserServerBasicRequest{ServerId: log.ServerId})
if err != nil {
this.ErrorPage(err)
return
}
var server = serverResp.Server
if server != nil {
serverMap = maps.Map{"id": server.Id, "name": server.Name}
}
}
logs = append(logs, maps.Map{
"id": log.Id,
"tag": log.Tag,
@@ -107,6 +121,7 @@ func (this *IndexAction) RunGet(params struct {
},
"name": node.Name,
},
"server": serverMap,
})
}
this.Data["logs"] = logs

View File

@@ -15,6 +15,7 @@ func init() {
Prefix("/clusters/logs").
Get("", new(IndexAction)).
Post("/readLogs", new(ReadLogsAction)).
Post("/readAllLogs", new(ReadAllLogsAction)).
EndAll()
})
}

View File

@@ -0,0 +1,24 @@
// 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 ReadAllLogsAction struct {
actionutils.ParentAction
}
func (this *ReadAllLogsAction) RunPost(params struct {
LogIds []int64
}) {
_, err := this.RPC().NodeLogRPC().UpdateAllNodeLogsRead(this.AdminContext(), &pb.UpdateAllNodeLogsReadRequest{})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -10,7 +10,9 @@ type CheckAction struct {
}
func (this *CheckAction) RunPost(params struct{}) {
resp, err := this.RPC().NodeTaskRPC().ExistsNodeTasks(this.AdminContext(), &pb.ExistsNodeTasksRequest{})
resp, err := this.RPC().NodeTaskRPC().ExistsNodeTasks(this.AdminContext(), &pb.ExistsNodeTasksRequest{
ExcludeTypes: []string{"ipItemChanged"},
})
if err != nil {
this.ErrorPage(err)
return

View File

@@ -6,7 +6,7 @@ import (
"github.com/iwind/TeaGo/maps"
)
// 域名列表选项
// DomainOptionsAction 域名列表选项
type DomainOptionsAction struct {
actionutils.ParentAction
}
@@ -23,8 +23,8 @@ func (this *DomainOptionsAction) RunPost(params struct {
}
domainMaps := []maps.Map{}
for _, domain := range domainsResp.DnsDomains {
// 未开启的先跳过
if !domain.IsOn {
// 未开启或者已删除的先跳过
if !domain.IsOn || domain.IsDeleted {
continue
}

View File

@@ -0,0 +1,27 @@
package domains
import (
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
type RecoverAction struct {
actionutils.ParentAction
}
func (this *RecoverAction) RunPost(params struct {
DomainId int64
}) {
// 记录日志
defer this.CreateLog(oplogs.LevelInfo, "从DNS服务商中恢复域名 %d", params.DomainId)
// 执行恢复
_, err := this.RPC().DNSDomainRPC().RecoverDNSDomain(this.AdminContext(), &pb.RecoverDNSDomainRequest{DnsDomainId: params.DomainId})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -52,7 +52,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
// TODO 检查DomainId
// 记录日志
defer this.CreateLog(oplogs.LevelInfo, "修改管理域名到DNS服务商 %d", params.DomainId)
defer this.CreateLog(oplogs.LevelInfo, "修改DNS服务商域名 %d", params.DomainId)
params.Must.
Field("name", params.Name).

View File

@@ -43,6 +43,7 @@ func init() {
GetPost("/createPopup", new(domains.CreatePopupAction)).
GetPost("/updatePopup", new(domains.UpdatePopupAction)).
Post("/delete", new(domains.DeleteAction)).
Post("/recover", new(domains.RecoverAction)).
Post("/sync", new(domains.SyncAction)).
Get("/routesPopup", new(domains.RoutesPopupAction)).
GetPost("/selectPopup", new(domains.SelectPopupAction)).

View File

@@ -83,6 +83,7 @@ func (this *ProviderAction) RunGet(params struct {
"name": domain.Name,
"isOn": domain.IsOn,
"isUp": domain.IsUp,
"isDeleted": domain.IsDeleted,
"dataUpdatedTime": dataUpdatedTime,
"countRoutes": len(domain.Routes),
"countServerRecords": domain.CountServerRecords,

View File

@@ -43,6 +43,12 @@ func (this *IndexAction) RunGet(params struct {
return
}
//// 是否新安装
if setup.IsNewInstalled() {
this.RedirectURL("/setup/confirm")
return
}
// 已登录跳转到dashboard
if params.Auth.IsUser() {
this.RedirectURL("/dashboard")

View File

@@ -3,6 +3,7 @@ package ipAddresses
import (
"encoding/json"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/iwind/TeaGo/actions"
@@ -39,9 +40,15 @@ func (this *CreatePopupAction) RunPost(params struct {
Field("ip", params.IP).
Require("请输入IP地址")
ip := net.ParseIP(params.IP)
if len(ip) == 0 {
this.FailField("ip", "请输入正确的IP")
result, err := utils.ExtractIP(params.IP)
if err != nil {
this.Fail("IP格式错误'" + params.IP + "'")
}
for _, ip := range result {
if len(net.ParseIP(ip)) == 0 {
this.FailField("ip", "请输入正确的IP")
}
}
// 阈值设置

View File

@@ -2,6 +2,7 @@ package ipaddressutils
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -16,8 +17,11 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
return err
}
for _, addr := range addresses {
var resultAddrIds = []int64{}
addrId := addr.GetInt64("id")
if addrId > 0 {
resultAddrIds = append(resultAddrIds, addrId)
var isOn = false
if !addr.Has("isOn") { // 兼容老版本
isOn = true
@@ -37,18 +41,40 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
return err
}
} else {
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
NodeId: nodeId,
Role: role,
Name: addr.GetString("name"),
Ip: addr.GetString("ip"),
CanAccess: addr.GetBool("canAccess"),
IsUp: addr.GetBool("isUp"),
})
if err != nil {
return err
var ipStrings = addr.GetString("ip")
result, _ := utils.ExtractIP(ipStrings)
if len(result) == 1 {
// 单个创建
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
NodeId: nodeId,
Role: role,
Name: addr.GetString("name"),
Ip: result[0],
CanAccess: addr.GetBool("canAccess"),
IsUp: addr.GetBool("isUp"),
})
if err != nil {
return err
}
addrId = createResp.NodeIPAddressId
resultAddrIds = append(resultAddrIds, addrId)
} else if len(result) > 1 {
// 批量创建
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddresses(parentAction.AdminContext(), &pb.CreateNodeIPAddressesRequest{
NodeId: nodeId,
Role: role,
Name: addr.GetString("name"),
IpList: result,
CanAccess: addr.GetBool("canAccess"),
IsUp: addr.GetBool("isUp"),
GroupValue: ipStrings,
})
if err != nil {
return err
}
resultAddrIds = append(resultAddrIds, createResp.NodeIPAddressIds...)
}
addrId = createResp.NodeIPAddressId
}
// 保存阈值
@@ -58,12 +84,25 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
if err != nil {
return err
}
_, err = parentAction.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(parentAction.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
NodeIPAddressId: addrId,
NodeIPAddressThresholdsJSON: thresholdsJSON,
})
if err != nil {
return err
for _, addrId := range resultAddrIds {
_, err = parentAction.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(parentAction.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
NodeIPAddressId: addrId,
NodeIPAddressThresholdsJSON: thresholdsJSON,
})
if err != nil {
return err
}
}
} else {
for _, addrId := range resultAddrIds {
_, err = parentAction.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(parentAction.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
NodeIPAddressId: addrId,
NodeIPAddressThresholdsJSON: []byte("[]"),
})
if err != nil {
return err
}
}
}
}

View File

@@ -3,6 +3,7 @@ package ipAddresses
import (
"encoding/json"
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -57,9 +58,22 @@ func (this *UpdatePopupAction) RunPost(params struct {
}
}
ip := net.ParseIP(params.IP)
if len(ip) == 0 {
this.Fail("请输入正确的IP")
if params.AddressId > 0 {
ip := net.ParseIP(params.IP)
if len(ip) == 0 {
this.Fail("请输入正确的IP")
}
} else {
result, err := utils.ExtractIP(params.IP)
if err != nil {
this.Fail("IP格式错误'" + params.IP + "'")
}
for _, ip := range result {
if len(net.ParseIP(ip)) == 0 {
this.FailField("ip", "请输入正确的IP")
}
}
}
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}

View File

@@ -48,6 +48,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
wg := &sync.WaitGroup{}
wg.Add(len(nodes))
for _, node := range nodes {
// TODO 检查是否在线
@@ -68,7 +69,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
apiNodeId := node.ConnectedAPINodeIds[0]
rpcClient, ok := rpcMap[apiNodeId]
if !ok {
apiNodeResp, err := defaultRPCClient.APINodeRPC().FindEnabledAPINode(ctx, &pb.FindEnabledAPINodeRequest{NodeId: apiNodeId})
apiNodeResp, err := defaultRPCClient.APINodeRPC().FindEnabledAPINode(ctx, &pb.FindEnabledAPINodeRequest{ApiNodeId: apiNodeId})
if err != nil {
locker.Lock()
results = append(results, &MessageResult{
@@ -82,7 +83,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
continue
}
if apiNodeResp.Node == nil {
if apiNodeResp.ApiNode == nil {
locker.Lock()
results = append(results, &MessageResult{
NodeId: node.Id,
@@ -94,7 +95,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
wg.Done()
continue
}
apiNode := apiNodeResp.Node
apiNode := apiNodeResp.ApiNode
apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{
RPC: struct {
@@ -104,7 +105,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
},
NodeId: apiNode.UniqueId,
Secret: apiNode.Secret,
})
}, false)
if err != nil {
locker.Lock()
results = append(results, &MessageResult{
@@ -162,6 +163,11 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
})
}
// 关闭RPC
for _, rpcClient := range rpcMap {
_ = rpcClient.Close()
}
return
}
@@ -243,7 +249,7 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
apiNodeId := node.ConnectedAPINodeIds[0]
rpcClient, ok := rpcMap[apiNodeId]
if !ok {
apiNodeResp, err := defaultRPCClient.APINodeRPC().FindEnabledAPINode(ctx, &pb.FindEnabledAPINodeRequest{NodeId: apiNodeId})
apiNodeResp, err := defaultRPCClient.APINodeRPC().FindEnabledAPINode(ctx, &pb.FindEnabledAPINodeRequest{ApiNodeId: apiNodeId})
if err != nil {
locker.Lock()
results = append(results, &MessageResult{
@@ -257,7 +263,7 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
continue
}
if apiNodeResp.Node == nil {
if apiNodeResp.ApiNode == nil {
locker.Lock()
results = append(results, &MessageResult{
NodeId: node.Id,
@@ -269,7 +275,7 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
wg.Done()
continue
}
apiNode := apiNodeResp.Node
apiNode := apiNodeResp.ApiNode
apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{
RPC: struct {
@@ -279,7 +285,7 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
},
NodeId: apiNode.UniqueId,
Secret: apiNode.Secret,
})
}, false)
if err != nil {
locker.Lock()
results = append(results, &MessageResult{
@@ -337,5 +343,10 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
})
}
// 关闭RPC
for _, rpcClient := range rpcMap {
_ = rpcClient.Close()
}
return
}

View File

@@ -3,6 +3,7 @@ package cluster
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
@@ -87,14 +88,31 @@ func (this *CreateNodeAction) RunPost(params struct {
NodeId: nodeId,
})
} else {
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
NodeId: nodeId,
Role: nodeconfigs.NodeRoleDNS,
Name: addrMap.GetString("name"),
Ip: addrMap.GetString("ip"),
CanAccess: addrMap.GetBool("canAccess"),
IsUp: addrMap.GetBool("isUp"),
})
var ipStrings = addrMap.GetString("ip")
result, _ := utils.ExtractIP(ipStrings)
if len(result) == 1 {
// 单个创建
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
NodeId: nodeId,
Role: nodeconfigs.NodeRoleDNS,
Name: addrMap.GetString("name"),
Ip: result[0],
CanAccess: addrMap.GetBool("canAccess"),
IsUp: addrMap.GetBool("isUp"),
})
} else if len(result) > 1 {
// 批量创建
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddresses(this.AdminContext(), &pb.CreateNodeIPAddressesRequest{
NodeId: nodeId,
Role: nodeconfigs.NodeRoleDNS,
Name: addrMap.GetString("name"),
IpList: result,
CanAccess: addrMap.GetBool("canAccess"),
IsUp: addrMap.GetBool("isUp"),
GroupValue: ipStrings,
})
}
}
if err != nil {
this.ErrorPage(err)

View File

@@ -73,7 +73,7 @@ func (this *InstallAction) RunGet(params struct {
this.ErrorPage(err)
return
}
apiNodes := apiNodesResp.Nodes
apiNodes := apiNodesResp.ApiNodes
apiEndpoints := []string{}
for _, apiNode := range apiNodes {
if !apiNode.IsOn {

View File

@@ -42,7 +42,7 @@ func (this *UpdateHostsAction) RunPost(params struct {
},
NodeId: params.NodeId,
Secret: params.NodeSecret,
})
}, false)
if err != nil {
this.FailField("host", "测试API节点时出错请检查配置错误信息"+err.Error())
}
@@ -51,6 +51,10 @@ func (this *UpdateHostsAction) RunPost(params struct {
this.FailField("host", "无法连接此API节点错误信息"+err.Error())
}
defer func() {
_ = client.Close()
}()
// 获取管理员节点信息
apiTokensResp, err := client.APITokenRPC().FindAllEnabledAPITokens(client.APIContext(0), &pb.FindAllEnabledAPITokensRequest{Role: "admin"})
if err != nil {
@@ -69,7 +73,7 @@ func (this *UpdateHostsAction) RunPost(params struct {
this.Fail("获取API节点列表失败错误信息" + err.Error())
}
var endpoints = []string{}
for _, node := range nodesResp.Nodes {
for _, node := range nodesResp.ApiNodes {
if !node.IsOn {
continue
}
@@ -144,7 +148,7 @@ func (this *UpdateHostsAction) RunPost(params struct {
// 保存
_, err = client.APINodeRPC().UpdateAPINode(client.Context(0), &pb.UpdateAPINodeRequest{
NodeId: node.Id,
ApiNodeId: node.Id,
Name: node.Name,
Description: node.Description,
HttpJSON: node.HttpJSON,

View File

@@ -49,10 +49,15 @@ func (this *ValidateApiAction) RunPost(params struct {
},
NodeId: params.NodeId,
Secret: params.NodeSecret,
})
}, false)
if err != nil {
this.FailField("host", "测试API节点时出错请检查配置错误信息"+err.Error())
}
defer func() {
_ = client.Close()
}()
_, err = client.APINodeRPC().FindCurrentAPINodeVersion(client.APIContext(0), &pb.FindCurrentAPINodeVersionRequest{})
if err != nil {
this.FailField("host", "无法连接此API节点错误信息"+err.Error())
@@ -64,7 +69,7 @@ func (this *ValidateApiAction) RunPost(params struct {
this.Fail("获取API节点列表失败错误信息" + err.Error())
}
var hosts = []string{}
for _, node := range nodesResp.Nodes {
for _, node := range nodesResp.ApiNodes {
if !node.IsOn {
continue
}

View File

@@ -16,7 +16,7 @@ func (this *DeleteAction) RunPost(params struct {
// 创建日志
defer this.CreateLog(oplogs.LevelInfo, "删除SSL证书 %d", params.CertId)
// 是否正在被使用
// 是否正在被服务使用
countResp, err := this.RPC().ServerRPC().CountAllEnabledServersWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledServersWithSSLCertIdRequest{SslCertId: params.CertId})
if err != nil {
this.ErrorPage(err)
@@ -26,6 +26,26 @@ func (this *DeleteAction) RunPost(params struct {
this.Fail("此证书正在被某些服务引用,请先修改服务后再删除。")
}
// 是否正在被API节点使用
countResp, err = this.RPC().APINodeRPC().CountAllEnabledAPINodesWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledAPINodesWithSSLCertIdRequest{SslCertId: params.CertId})
if err != nil {
this.ErrorPage(err)
return
}
if countResp.Count > 0 {
this.Fail("此证书正在被某些API节点引用请先修改API节点后再删除")
}
// 是否正在被用户节点使用
countResp, err = this.RPC().UserNodeRPC().CountAllEnabledUserNodesWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledUserNodesWithSSLCertIdRequest{SslCertId: params.CertId})
if err != nil {
this.ErrorPage(err)
return
}
if countResp.Count > 0 {
this.Fail("此证书正在被某些用户节点引用,请先修改用户节点后再删除")
}
_, err = this.RPC().SSLCertRPC().DeleteSSLCert(this.AdminContext(), &pb.DeleteSSLCertRequest{SslCertId: params.CertId})
if err != nil {
this.ErrorPage(err)

View File

@@ -33,7 +33,7 @@ func (this *IndexAction) RunGet(params struct{}) {
globalConfig := &serverconfigs.GlobalConfig{}
// 默认值
globalConfig.HTTPAll.DomainAuditingIsOn = true
globalConfig.HTTPAll.DomainAuditingIsOn = false
if len(valueJSON) > 0 {
err = json.Unmarshal(valueJSON, globalConfig)

View File

@@ -30,6 +30,7 @@ func (this *CreateGroupPopupAction) RunPost(params struct {
Type string
Name string
Code string
Description string
IsOn bool
@@ -52,6 +53,7 @@ func (this *CreateGroupPopupAction) RunPost(params struct {
createResp, err := this.RPC().HTTPFirewallRuleGroupRPC().CreateHTTPFirewallRuleGroup(this.AdminContext(), &pb.CreateHTTPFirewallRuleGroupRequest{
IsOn: params.IsOn,
Name: params.Name,
Code: params.Code,
Description: params.Description,
})
if err != nil {

View File

@@ -73,6 +73,7 @@ func (this *CreateSetPopupAction) RunPost(params struct {
RulesJSON []byte
Connector string
ActionsJSON []byte
IgnoreLocal bool
Must *actions.Must
}) {
@@ -124,6 +125,7 @@ func (this *CreateSetPopupAction) RunPost(params struct {
RuleRefs: nil,
Rules: rules,
Actions: actionConfigs,
IgnoreLocal: params.IgnoreLocal,
}
setConfigJSON, err := json.Marshal(setConfig)

View File

@@ -32,24 +32,36 @@ func (this *ExportAction) RunGet(params struct {
return
}
inboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
outboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
enabledInboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
enabledOutboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
disabledInboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
disabledOutboundGroups := []*firewallconfigs.HTTPFirewallRuleGroup{}
if policy.Inbound != nil {
for _, g := range policy.Inbound.Groups {
if g.IsOn {
inboundGroups = append(inboundGroups, g)
enabledInboundGroups = append(enabledInboundGroups, g)
} else {
disabledInboundGroups = append(disabledInboundGroups, g)
}
}
}
if policy.Outbound != nil {
for _, g := range policy.Outbound.Groups {
if g.IsOn {
outboundGroups = append(outboundGroups, g)
enabledOutboundGroups = append(enabledOutboundGroups, g)
} else {
disabledOutboundGroups = append(disabledOutboundGroups, g)
}
}
}
this.Data["inboundGroups"] = inboundGroups
this.Data["outboundGroups"] = outboundGroups
this.Data["enabledInboundGroups"] = enabledInboundGroups
this.Data["enabledOutboundGroups"] = enabledOutboundGroups
this.Data["disabledInboundGroups"] = disabledInboundGroups
this.Data["disabledOutboundGroups"] = disabledOutboundGroups
this.Show()
}
@@ -116,5 +128,6 @@ func (this *ExportAction) RunPost(params struct {
ttlcache.DefaultCache.Write(key, configJSON, time.Now().Unix()+600)
this.Data["key"] = key
this.Data["id"] = params.FirewallPolicyId
this.Success()
}

View File

@@ -3,6 +3,7 @@ package waf
import (
"github.com/TeaOSLab/EdgeAdmin/internal/ttlcache"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/types"
"strconv"
)
@@ -15,7 +16,8 @@ func (this *ExportDownloadAction) Init() {
}
func (this *ExportDownloadAction) RunGet(params struct {
Key string
Key string
PolicyId int64
}) {
item := ttlcache.DefaultCache.Read(params.Key)
if item == nil || item.Value == nil {
@@ -27,7 +29,7 @@ func (this *ExportDownloadAction) RunGet(params struct {
data, ok := item.Value.([]byte)
if ok {
this.AddHeader("Content-Disposition", "attachment; filename=\"WAF.json\";")
this.AddHeader("Content-Disposition", "attachment; filename=\"WAF-"+types.String(params.PolicyId)+".json\";")
this.AddHeader("Content-Length", strconv.Itoa(len(data)))
this.Write(data)
} else {

View File

@@ -43,7 +43,8 @@ func (this *GroupsAction) RunGet(params struct {
"isOn": g.IsOn,
"description": g.Description,
"countSets": len(g.Sets),
"canDelete": len(g.Code) == 0,
"isTemplate": g.IsTemplate,
"canDelete": !g.IsTemplate,
})
}
}
@@ -60,7 +61,8 @@ func (this *GroupsAction) RunGet(params struct {
"isOn": g.IsOn,
"description": g.Description,
"countSets": len(g.Sets),
"canDelete": len(g.Code) == 0,
"isTemplate": g.IsTemplate,
"canDelete": !g.IsTemplate,
})
}
}

View File

@@ -41,6 +41,7 @@ func init() {
GetPost("/updateSetPopup", new(UpdateSetPopupAction)).
Post("/count", new(CountAction)).
Get("/selectPopup", new(SelectPopupAction)).
Post("/testRegexp", new(TestRegexpAction)).
// IP管理
GetPost("/ipadmin", new(ipadmin.IndexAction)).

View File

@@ -59,14 +59,56 @@ func (this *ListsAction) RunGet(params struct {
expiredTime = timeutil.FormatTime("Y-m-d H:i:s", item.ExpiredAt)
}
// policy
var sourcePolicyMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallPolicy != nil {
sourcePolicyMap = maps.Map{
"id": item.SourceHTTPFirewallPolicy.Id,
"name": item.SourceHTTPFirewallPolicy.Name,
"serverId": item.SourceHTTPFirewallPolicy.ServerId,
}
}
// group
var sourceGroupMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallRuleGroup != nil {
sourceGroupMap = maps.Map{
"id": item.SourceHTTPFirewallRuleGroup.Id,
"name": item.SourceHTTPFirewallRuleGroup.Name,
}
}
// set
var sourceSetMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallRuleSet != nil {
sourceSetMap = maps.Map{
"id": item.SourceHTTPFirewallRuleSet.Id,
"name": item.SourceHTTPFirewallRuleSet.Name,
}
}
// server
var sourceServerMap = maps.Map{"id": 0}
if item.SourceServer != nil {
sourceServerMap = maps.Map{
"id": item.SourceServer.Id,
"name": item.SourceServer.Name,
}
}
itemMaps = append(itemMaps, maps.Map{
"id": item.Id,
"ipFrom": item.IpFrom,
"ipTo": item.IpTo,
"createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt),
"expiredTime": expiredTime,
"reason": item.Reason,
"type": item.Type,
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(item.EventLevel),
"sourcePolicy": sourcePolicyMap,
"sourceGroup": sourceGroupMap,
"sourceSet": sourceSetMap,
"sourceServer": sourceServerMap,
})
}
this.Data["items"] = itemMaps

View File

@@ -60,6 +60,7 @@ func (this *TestAction) RunPost(params struct {
"ipFrom": resp.IpItem.IpFrom,
"ipTo": resp.IpItem.IpTo,
"reason": resp.IpItem.Reason,
"createdTime": timeutil.FormatTime("Y-m-d", resp.IpItem.CreatedAt),
"expiredAt": resp.IpItem.ExpiredAt,
"expiredTime": timeutil.FormatTime("Y-m-d H:i:s", resp.IpItem.ExpiredAt),
"type": resp.IpItem.Type,

View File

@@ -0,0 +1,48 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package waf
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/iwind/TeaGo/maps"
"regexp"
"strings"
)
type TestRegexpAction struct {
actionutils.ParentAction
}
func (this *TestRegexpAction) RunPost(params struct {
Regexp string
IsCaseInsensitive bool
Body string
}) {
var exp = params.Regexp
if params.IsCaseInsensitive && !strings.HasPrefix(params.Regexp, "(?i)") {
exp = "(?i)" + exp
}
reg, err := regexp.Compile(exp)
if err != nil {
this.Data["result"] = maps.Map{
"isOk": false,
"message": "解析正则出错:" + err.Error(),
}
this.Success()
}
if reg.MatchString(params.Body) {
this.Data["result"] = maps.Map{
"isOk": true,
"message": "匹配成功",
}
this.Success()
}
this.Data["result"] = maps.Map{
"isOk": false,
"message": "匹配失败",
}
this.Success()
}

View File

@@ -35,6 +35,7 @@ func (this *UpdateGroupPopupAction) RunGet(params struct {
"name": groupConfig.Name,
"description": groupConfig.Description,
"isOn": groupConfig.IsOn,
"code": groupConfig.Code,
}
this.Show()
@@ -43,6 +44,7 @@ func (this *UpdateGroupPopupAction) RunGet(params struct {
func (this *UpdateGroupPopupAction) RunPost(params struct {
GroupId int64
Name string
Code string
Description string
IsOn bool
@@ -59,6 +61,7 @@ func (this *UpdateGroupPopupAction) RunPost(params struct {
FirewallRuleGroupId: params.GroupId,
IsOn: params.IsOn,
Name: params.Name,
Code: params.Code,
Description: params.Description,
})
if err != nil {

View File

@@ -97,6 +97,7 @@ func (this *UpdateSetPopupAction) RunPost(params struct {
RulesJSON []byte
Connector string
ActionsJSON []byte
IgnoreLocal bool
Must *actions.Must
}) {
@@ -144,6 +145,7 @@ func (this *UpdateSetPopupAction) RunPost(params struct {
setConfig.Connector = params.Connector
setConfig.Rules = rules
setConfig.Actions = actionConfigs
setConfig.IgnoreLocal = params.IgnoreLocal
setConfigJSON, err := json.Marshal(setConfig)
if err != nil {

View File

@@ -57,14 +57,26 @@ func (this *CreateAction) RunGet(params struct{}) {
// 服务类型
this.Data["serverTypes"] = serverconfigs.AllServerTypes()
// 检查是否有用户
countUsersResp, err := this.RPC().UserRPC().CountAllEnabledUsers(this.AdminContext(), &pb.CountAllEnabledUsersRequest{})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["hasUsers"] = countUsersResp.Count > 0
this.Show()
}
func (this *CreateAction) RunPost(params struct {
Name string
Description string
ClusterId int64
GroupIds []int64
UserId int64
UserPlanId int64
ClusterId int64
GroupIds []int64
ServerType string
Addresses string
@@ -77,6 +89,7 @@ func (this *CreateAction) RunPost(params struct {
CacheIsOn bool
WafIsOn bool
RemoteAddrIsOn bool
StatIsOn bool
WebRoot string
@@ -86,11 +99,24 @@ func (this *CreateAction) RunPost(params struct {
Field("name", params.Name).
Require("请输入服务名称")
if params.ClusterId <= 0 {
this.Fail("请选择部署的集群")
var clusterId = params.ClusterId
// 用户
var userId = params.UserId
if userId > 0 {
clusterIdResp, err := this.RPC().UserRPC().FindUserNodeClusterId(this.AdminContext(), &pb.FindUserNodeClusterIdRequest{UserId: userId})
if err != nil {
this.ErrorPage(err)
return
}
clusterId = clusterIdResp.NodeClusterId
if clusterId <= 0 {
this.Fail("请选择部署的集群")
}
}
// TODO 验证集群ID
// 套餐
var userPlanId = params.UserPlanId
// 端口地址
var httpConfig *serverconfigs.HTTPProtocolConfig = nil
@@ -260,7 +286,7 @@ func (this *CreateAction) RunPost(params struct {
if len(allServerNames) > 0 {
dupResp, err := this.RPC().ServerRPC().CheckServerNameDuplicationInNodeCluster(this.AdminContext(), &pb.CheckServerNameDuplicationInNodeClusterRequest{
ServerNames: allServerNames,
NodeClusterId: params.ClusterId,
NodeClusterId: clusterId,
})
if err != nil {
this.ErrorPage(err)
@@ -339,7 +365,7 @@ func (this *CreateAction) RunPost(params struct {
this.ErrorPage(err)
return
}
webId = webResp.WebId
webId = webResp.HttpWebId
}
// 包含条件
@@ -359,13 +385,14 @@ func (this *CreateAction) RunPost(params struct {
}
req := &pb.CreateServerRequest{
UserId: 0,
UserId: userId,
UserPlanId: userPlanId,
AdminId: this.AdminId(),
Type: params.ServerType,
Name: params.Name,
ServerNamesJON: []byte(params.ServerNames),
Description: params.Description,
NodeClusterId: params.ClusterId,
NodeClusterId: clusterId,
IncludeNodesJSON: includeNodesJSON,
ExcludeNodesJSON: excludeNodesJSON,
WebId: webId,
@@ -436,11 +463,11 @@ func (this *CreateAction) RunPost(params struct {
// 访问日志
if params.AccessLogIsOn {
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebAccessLog(this.AdminContext(), &pb.UpdateHTTPWebAccessLogRequest{
WebId: webConfig.Id,
HttpWebId: webConfig.Id,
AccessLogJSON: []byte(`{
"isPrior": false,
"isOn": true,
"fields": [],
"fields": [1, 2, 6, 7],
"status1": true,
"status2": true,
"status3": true,
@@ -475,7 +502,7 @@ func (this *CreateAction) RunPost(params struct {
} else {
websocketId := createWebSocketResp.WebsocketId
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebWebsocket(this.AdminContext(), &pb.UpdateHTTPWebWebsocketRequest{
WebId: webConfig.Id,
HttpWebId: webConfig.Id,
WebsocketJSON: []byte(` {
"isPrior": false,
"isOn": true,
@@ -496,7 +523,7 @@ func (this *CreateAction) RunPost(params struct {
AddStatusHeader: true,
PurgeIsOn: false,
PurgeKey: "",
CacheRefs: nil,
CacheRefs: []*serverconfigs.HTTPCacheRef{},
}
cacheConfigJSON, err := json.Marshal(cacheConfig)
if err != nil {
@@ -504,7 +531,7 @@ func (this *CreateAction) RunPost(params struct {
return
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebCache(this.AdminContext(), &pb.UpdateHTTPWebCacheRequest{
WebId: webConfig.Id,
HttpWebId: webConfig.Id,
CacheJSON: cacheConfigJSON,
})
if err != nil {
@@ -526,7 +553,7 @@ func (this *CreateAction) RunPost(params struct {
return
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebFirewall(this.AdminContext(), &pb.UpdateHTTPWebFirewallRequest{
WebId: webConfig.Id,
HttpWebId: webConfig.Id,
FirewallJSON: firewallRefJSON,
})
if err != nil {
@@ -549,13 +576,34 @@ func (this *CreateAction) RunPost(params struct {
return
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebRemoteAddr(this.AdminContext(), &pb.UpdateHTTPWebRemoteAddrRequest{
WebId: webConfig.Id,
HttpWebId: webConfig.Id,
RemoteAddrJSON: remoteAddrConfigJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
// 统计
if params.StatIsOn {
var statConfig = &serverconfigs.HTTPStatRef{
IsPrior: false,
IsOn: true,
}
statJSON, err := json.Marshal(statConfig)
if err != nil {
this.ErrorPage(err)
return
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebStat(this.AdminContext(), &pb.UpdateHTTPWebStatRequest{
HttpWebId: webConfig.Id,
StatJSON: statJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
}
}
}

View File

@@ -12,9 +12,9 @@ type FixLogAction struct {
}
func (this *FixLogAction) RunPost(params struct {
LogId int64
LogIds []int64
}) {
_, err := this.RPC().NodeLogRPC().FixNodeLog(this.AdminContext(), &pb.FixNodeLogRequest{NodeLogId: params.LogId})
_, err := this.RPC().NodeLogRPC().FixNodeLogs(this.AdminContext(), &pb.FixNodeLogsRequest{NodeLogIds: params.LogIds})
if err != nil {
this.ErrorPage(err)
return

View File

@@ -144,6 +144,15 @@ func InitGroup(parent *actionutils.ParentAction, groupId int64, menuItem string)
"isActive": menuItem == "remoteAddr",
"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,
})
}
parent.Data["leftMenuItems"] = leftMenuItems
}

View File

@@ -56,7 +56,7 @@ func (this *IndexAction) RunPost(params struct {
// TODO 检查参数
_, err := this.RPC().HTTPWebRPC().UpdateHTTPWebAccessLog(this.AdminContext(), &pb.UpdateHTTPWebAccessLogRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
AccessLogJSON: params.AccessLogJSON,
})
if err != nil {

View File

@@ -76,7 +76,7 @@ func (this *IndexAction) RunPost(params struct {
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebCache(this.AdminContext(), &pb.UpdateHTTPWebCacheRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
CacheJSON: cacheJSON,
})
if err != nil {

View File

@@ -52,7 +52,7 @@ func (this *IndexAction) RunPost(params struct {
defer this.CreateLog(oplogs.LevelInfo, "修改Web %d 的字符集设置", params.WebId)
_, err := this.RPC().HTTPWebRPC().UpdateHTTPWebCharset(this.AdminContext(), &pb.UpdateHTTPWebCharsetRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
CharsetJSON: params.CharsetJSON,
})
if err != nil {

View File

@@ -66,7 +66,7 @@ func (this *IndexAction) RunPost(params struct {
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebCompression(this.AdminContext(), &pb.UpdateHTTPWebCompressionRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
CompressionJSON: params.CompressionJSON,
})
if err != nil {

View File

@@ -55,7 +55,7 @@ func (this *IndexAction) RunGet(params struct {
return
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebRequestHeader(this.AdminContext(), &pb.UpdateHTTPWebRequestHeaderRequest{
WebId: webId,
HttpWebId: webId,
HeaderJSON: refJSON,
})
if err != nil {
@@ -82,7 +82,7 @@ func (this *IndexAction) RunGet(params struct {
return
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebResponseHeader(this.AdminContext(), &pb.UpdateHTTPWebResponseHeaderRequest{
WebId: webId,
HttpWebId: webId,
HeaderJSON: refJSON,
})
if err != nil {
@@ -129,7 +129,7 @@ func (this *IndexAction) RunPost(params struct {
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebRequestHeader(this.AdminContext(), &pb.UpdateHTTPWebRequestHeaderRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
HeaderJSON: params.RequestHeaderJSON,
})
if err != nil {
@@ -145,7 +145,7 @@ func (this *IndexAction) RunPost(params struct {
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebResponseHeader(this.AdminContext(), &pb.UpdateHTTPWebResponseHeaderRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
HeaderJSON: params.ResponseHeaderJSON,
})
if err != nil {

View File

@@ -52,7 +52,7 @@ func (this *IndexAction) RunPost(params struct {
// TODO 检查配置
_, err := this.RPC().HTTPWebRPC().UpdateHTTPWebPages(this.AdminContext(), &pb.UpdateHTTPWebPagesRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
PagesJSON: []byte(params.PagesJSON),
})
if err != nil {
@@ -61,7 +61,7 @@ func (this *IndexAction) RunPost(params struct {
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebShutdown(this.AdminContext(), &pb.UpdateHTTPWebShutdownRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
ShutdownJSON: []byte(params.ShutdownJSON),
})
if err != nil {

View File

@@ -56,7 +56,7 @@ func (this *IndexAction) RunPost(params struct {
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebRemoteAddr(this.AdminContext(), &pb.UpdateHTTPWebRemoteAddrRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
RemoteAddrJSON: params.RemoteAddrJSON,
})
if err != nil {

View File

@@ -0,0 +1,62 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package requestlimit
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "setting", "index")
this.SecondMenu("requestLimit")
}
func (this *IndexAction) RunGet(params struct {
GroupId int64
}) {
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "requestLimit")
if err != nil {
this.ErrorPage(err)
return
}
webConfig, err := dao.SharedHTTPWebDAO.FindWebConfigWithServerGroupId(this.AdminContext(), params.GroupId)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["webId"] = webConfig.Id
this.Data["requestLimitConfig"] = webConfig.RequestLimit
this.Show()
}
func (this *IndexAction) RunPost(params struct {
WebId int64
RequestLimitJSON []byte
Must *actions.Must
CSRF *actionutils.CSRF
}) {
defer this.CreateLogInfo("修改Web %d 请求限制", params.WebId)
_, err := this.RPC().HTTPWebRPC().UpdateHTTPWebRequestLimit(this.AdminContext(), &pb.UpdateHTTPWebRequestLimitRequest{
HttpWebId: params.WebId,
RequestLimitJSON: params.RequestLimitJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,19 @@
package requestlimit
import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"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)).
Data("teaMenu", "servers").
Data("teaSubMenu", "group").
Prefix("/servers/groups/group/settings/requestLimit").
GetPost("", new(IndexAction)).
EndAll()
})
}

View File

@@ -49,8 +49,8 @@ func (this *IndexAction) RunPost(params struct {
// TODO 校验配置
_, err := this.RPC().HTTPWebRPC().UpdateHTTPWebStat(this.AdminContext(), &pb.UpdateHTTPWebStatRequest{
WebId: params.WebId,
StatJSON: params.StatJSON,
HttpWebId: params.WebId,
StatJSON: params.StatJSON,
})
if err != nil {
this.ErrorPage(err)

View File

@@ -64,7 +64,7 @@ func (this *IndexAction) RunPost(params struct {
// TODO 检查配置
_, err := this.RPC().HTTPWebRPC().UpdateHTTPWebFirewall(this.AdminContext(), &pb.UpdateHTTPWebFirewallRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
FirewallJSON: params.FirewallJSON,
})
if err != nil {

View File

@@ -70,15 +70,57 @@ func (this *AllowListAction) RunGet(params struct {
expiredTime = timeutil.FormatTime("Y-m-d H:i:s", item.ExpiredAt)
}
// policy
var sourcePolicyMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallPolicy != nil {
sourcePolicyMap = maps.Map{
"id": item.SourceHTTPFirewallPolicy.Id,
"name": item.SourceHTTPFirewallPolicy.Name,
"serverId": item.SourceHTTPFirewallPolicy.ServerId,
}
}
// group
var sourceGroupMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallRuleGroup != nil {
sourceGroupMap = maps.Map{
"id": item.SourceHTTPFirewallRuleGroup.Id,
"name": item.SourceHTTPFirewallRuleGroup.Name,
}
}
// set
var sourceSetMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallRuleSet != nil {
sourceSetMap = maps.Map{
"id": item.SourceHTTPFirewallRuleSet.Id,
"name": item.SourceHTTPFirewallRuleSet.Name,
}
}
// server
var sourceServerMap = maps.Map{"id": 0}
if item.SourceServer != nil {
sourceServerMap = maps.Map{
"id": item.SourceServer.Id,
"name": item.SourceServer.Name,
}
}
itemMaps = append(itemMaps, maps.Map{
"id": item.Id,
"ipFrom": item.IpFrom,
"ipTo": item.IpTo,
"createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt),
"expiredTime": expiredTime,
"reason": item.Reason,
"type": item.Type,
"isExpired": item.ExpiredAt > 0 && item.ExpiredAt < time.Now().Unix(),
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(item.EventLevel),
"sourcePolicy": sourcePolicyMap,
"sourceGroup": sourceGroupMap,
"sourceSet": sourceSetMap,
"sourceServer": sourceServerMap,
})
}
this.Data["items"] = itemMaps

View File

@@ -70,15 +70,57 @@ func (this *DenyListAction) RunGet(params struct {
expiredTime = timeutil.FormatTime("Y-m-d H:i:s", item.ExpiredAt)
}
// policy
var sourcePolicyMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallPolicy != nil {
sourcePolicyMap = maps.Map{
"id": item.SourceHTTPFirewallPolicy.Id,
"name": item.SourceHTTPFirewallPolicy.Name,
"serverId": item.SourceHTTPFirewallPolicy.ServerId,
}
}
// group
var sourceGroupMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallRuleGroup != nil {
sourceGroupMap = maps.Map{
"id": item.SourceHTTPFirewallRuleGroup.Id,
"name": item.SourceHTTPFirewallRuleGroup.Name,
}
}
// set
var sourceSetMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallRuleSet != nil {
sourceSetMap = maps.Map{
"id": item.SourceHTTPFirewallRuleSet.Id,
"name": item.SourceHTTPFirewallRuleSet.Name,
}
}
// server
var sourceServerMap = maps.Map{"id": 0}
if item.SourceServer != nil {
sourceServerMap = maps.Map{
"id": item.SourceServer.Id,
"name": item.SourceServer.Name,
}
}
itemMaps = append(itemMaps, maps.Map{
"id": item.Id,
"ipFrom": item.IpFrom,
"ipTo": item.IpTo,
"createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt),
"expiredTime": expiredTime,
"reason": item.Reason,
"type": item.Type,
"isExpired": item.ExpiredAt > 0 && item.ExpiredAt < time.Now().Unix(),
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(item.EventLevel),
"sourcePolicy": sourcePolicyMap,
"sourceGroup": sourceGroupMap,
"sourceSet": sourceSetMap,
"sourceServer": sourceServerMap,
})
}
this.Data["items"] = itemMaps

View File

@@ -74,6 +74,7 @@ func (this *TestAction) RunPost(params struct {
"ipTo": resp.IpItem.IpTo,
"reason": resp.IpItem.Reason,
"expiredAt": resp.IpItem.ExpiredAt,
"createdTime": timeutil.FormatTime("Y-m-d", resp.IpItem.CreatedAt),
"expiredTime": timeutil.FormatTime("Y-m-d H:i:s", resp.IpItem.ExpiredAt),
"type": resp.IpItem.Type,
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(resp.IpItem.EventLevel),

View File

@@ -47,8 +47,8 @@ func (this *IndexAction) RunPost(params struct {
defer this.CreateLogInfo("修改Web %d 的首页文件名", params.WebId)
_, err := this.RPC().HTTPWebRPC().UpdateHTTPWeb(this.AdminContext(), &pb.UpdateHTTPWebRequest{
WebId: params.WebId,
RootJSON: params.RootJSON,
HttpWebId: params.WebId,
RootJSON: params.RootJSON,
})
if err != nil {
this.ErrorPage(err)

View File

@@ -56,8 +56,8 @@ func (this *IndexAction) RunPost(params struct {
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebWebP(this.AdminContext(), &pb.UpdateHTTPWebWebPRequest{
WebId: params.WebId,
WebpJSON: params.WebpJSON,
HttpWebId: params.WebId,
WebpJSON: params.WebpJSON,
})
if err != nil {
this.ErrorPage(err)

View File

@@ -110,7 +110,7 @@ func (this *IndexAction) RunPost(params struct {
return
}
_, err = this.RPC().HTTPWebRPC().UpdateHTTPWebWebsocket(this.AdminContext(), &pb.UpdateHTTPWebWebsocketRequest{
WebId: params.WebId,
HttpWebId: params.WebId,
WebsocketJSON: websocketRefJSON,
})
if err != nil {

View File

@@ -199,6 +199,12 @@ func (this *IndexAction) RunGet(params struct {
}
}
// 提交审核时间
var auditingTime = ""
if server.AuditingAt > 0 {
auditingTime = timeutil.FormatTime("Y-m-d", server.AuditingAt)
}
serverMaps = append(serverMaps, maps.Map{
"id": server.Id,
"isOn": server.IsOn,
@@ -215,6 +221,7 @@ func (this *IndexAction) RunGet(params struct {
"isAuditing": server.IsAuditing,
"auditingIsOk": auditingIsOk,
"user": userMap,
"auditingTime": auditingTime,
})
}
this.Data["servers"] = serverMaps
@@ -258,7 +265,7 @@ func (this *IndexAction) RunGet(params struct {
NodeId: 0,
Role: nodeconfigs.NodeRoleNode,
Offset: 0,
Size: 10,
Size: 20,
Level: "",
FixedState: int32(configutils.BoolStateNo),
AllServers: true,
@@ -279,7 +286,7 @@ func (this *IndexAction) RunGet(params struct {
var server = serverResp.Server
if server == nil {
// 设置为已修复
_, err = this.RPC().NodeLogRPC().FixNodeLog(this.AdminContext(), &pb.FixNodeLogRequest{NodeLogId: errorLog.Id})
_, err = this.RPC().NodeLogRPC().FixNodeLogs(this.AdminContext(), &pb.FixNodeLogsRequest{NodeLogIds: []int64{errorLog.Id}})
if err != nil {
this.ErrorPage(err)
return
@@ -297,7 +304,7 @@ func (this *IndexAction) RunGet(params struct {
var node = nodeResp.Node
if node == nil || node.NodeCluster == nil {
// 设置为已修复
_, err = this.RPC().NodeLogRPC().FixNodeLog(this.AdminContext(), &pb.FixNodeLogRequest{NodeLogId: errorLog.Id})
_, err = this.RPC().NodeLogRPC().FixNodeLogs(this.AdminContext(), &pb.FixNodeLogsRequest{NodeLogIds: []int64{errorLog.Id}})
if err != nil {
this.ErrorPage(err)
return

View File

@@ -2,6 +2,7 @@ package servers
import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/users"
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
"github.com/iwind/TeaGo"
)
@@ -24,6 +25,12 @@ func init() {
GetPost("/addOriginPopup", new(AddOriginPopupAction)).
Get("/serverNamesPopup", new(ServerNamesPopupAction)).
Post("/status", new(StatusAction)).
//
Post("/users/options", new(users.OptionsAction)).
Post("/users/plans", new(users.PlansAction)).
//
EndAll()
})
}

View File

@@ -14,19 +14,30 @@ type AddIPAction struct {
}
func (this *AddIPAction) RunPost(params struct {
ListId int64
Ip string
ListId int64
Ip string
ExpiredAt int64
}) {
var itemId int64 = 0
defer func() {
this.CreateLogInfo("在名单 %d 中创建IP %d", params.ListId, itemId)
}()
var ipType = "ipv4"
if strings.Contains(params.Ip, ":") {
ipType = "ipv6"
}
_, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
if params.ExpiredAt <= 0 {
params.ExpiredAt = time.Now().Unix() + 86400
}
createResp, err := this.RPC().IPItemRPC().CreateIPItem(this.AdminContext(), &pb.CreateIPItemRequest{
IpListId: params.ListId,
IpFrom: params.Ip,
IpTo: "",
ExpiredAt: time.Now().Unix() + 86400, // TODO 可以自定义时间
ExpiredAt: params.ExpiredAt,
Reason: "从IPBox中加入名单",
Type: ipType,
EventLevel: "critical",
@@ -36,5 +47,7 @@ func (this *AddIPAction) RunPost(params struct {
return
}
itemId = createResp.IpItemId
this.Success()
}

View File

@@ -0,0 +1,27 @@
// 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 DeleteFromListAction struct {
actionutils.ParentAction
}
func (this *DeleteFromListAction) RunPost(params struct {
ListId int64
ItemId int64
}) {
defer this.CreateLogInfo("从IP名单 %d 中删除IP %d", params.ListId, params.ItemId)
_, err := this.RPC().IPItemRPC().DeleteIPItem(this.AdminContext(), &pb.DeleteIPItemRequest{IpItemId: params.ItemId})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -37,17 +37,44 @@ func (this *IndexAction) RunGet(params struct {
this.Data["isp"] = regionResp.IpRegion.Isp
// IP列表
ipListResp, err := this.RPC().IPListRPC().FindEnabledIPListContainsIP(this.AdminContext(), &pb.FindEnabledIPListContainsIPRequest{Ip: params.Ip})
ipListResp, err := this.RPC().IPListRPC().FindEnabledIPListContainsIP(this.AdminContext(), &pb.FindEnabledIPListContainsIPRequest{
Ip: params.Ip,
})
if err != nil {
this.ErrorPage(err)
return
}
var ipListMaps = []maps.Map{}
for _, ipList := range ipListResp.IpLists {
itemsResp, err := this.RPC().IPItemRPC().ListIPItemsWithListId(this.AdminContext(), &pb.ListIPItemsWithListIdRequest{
IpListId: ipList.Id,
Keyword: "",
IpFrom: params.Ip,
IpTo: "",
Offset: 0,
Size: 1,
})
if err != nil {
this.ErrorPage(err)
return
}
var items = itemsResp.IpItems
if len(items) == 0 {
continue
}
var item = items[0]
var expiredTime = ""
if item.ExpiredAt > 0 {
expiredTime = timeutil.FormatTime("Y-m-d H:i:s", item.ExpiredAt)
}
ipListMaps = append(ipListMaps, maps.Map{
"id": ipList.Id,
"name": ipList.Name,
"type": ipList.Type,
"id": ipList.Id,
"name": ipList.Name,
"type": ipList.Type,
"itemExpiredTime": expiredTime,
"itemId": item.Id,
})
}
this.Data["ipLists"] = ipListMaps
@@ -58,7 +85,7 @@ func (this *IndexAction) RunGet(params struct {
IsPublic: true,
Keyword: "",
Offset: 0,
Size: 10, // TODO 将来考虑到支持更多的黑名单
Size: 20, // TODO 将来考虑到支持更多的黑名单
})
if err != nil {
this.ErrorPage(err)

View File

@@ -15,6 +15,7 @@ func init() {
Prefix("/servers/ipbox").
Get("", new(IndexAction)).
Post("/addIP", new(AddIPAction)).
Post("/deleteFromList", new(DeleteFromListAction)).
EndAll()
})
}

View File

@@ -29,6 +29,7 @@ func (this *CreatePopupAction) RunPost(params struct {
Name string
Type string
Description string
IsGlobal bool
Must *actions.Must
CSRF *actionutils.CSRF
@@ -49,6 +50,7 @@ func (this *CreatePopupAction) RunPost(params struct {
TimeoutJSON: nil,
IsPublic: true,
Description: params.Description,
IsGlobal: params.IsGlobal,
})
if err != nil {
this.ErrorPage(err)

View File

@@ -0,0 +1,37 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package iplists
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/types"
"strings"
)
type DeleteItemsAction struct {
actionutils.ParentAction
}
func (this *DeleteItemsAction) RunPost(params struct {
ItemIds []int64
}) {
if len(params.ItemIds) == 0 {
this.Success()
}
var itemIdStrings = []string{}
for _, itemId := range params.ItemIds {
itemIdStrings = append(itemIdStrings, types.String(itemId))
}
defer this.CreateLogInfo("批量删除IP名单中的IP" + strings.Join(itemIdStrings, ", "))
_, err := this.RPC().IPItemRPC().DeleteIPItems(this.AdminContext(), &pb.DeleteIPItemsRequest{IpItemIds: params.ItemIds})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -5,8 +5,10 @@ package iplists
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ipconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
"time"
)
type IndexAction struct {
@@ -18,59 +20,123 @@ func (this *IndexAction) Init() {
}
func (this *IndexAction) RunGet(params struct {
Type string
Keyword string
Ip string
GlobalOnly bool
}) {
if len(params.Type) == 0 {
params.Type = ipconfigs.IPListTypeBlack
}
this.Data["type"] = params.Type
this.Data["keyword"] = params.Keyword
this.Data["type"] = ""
this.Data["ip"] = params.Ip
this.Data["globalOnly"] = params.GlobalOnly
countResp, err := this.RPC().IPListRPC().CountAllEnabledIPLists(this.AdminContext(), &pb.CountAllEnabledIPListsRequest{
Type: params.Type,
IsPublic: true,
Keyword: params.Keyword,
countResp, err := this.RPC().IPItemRPC().CountAllEnabledIPItems(this.AdminContext(), &pb.CountAllEnabledIPItemsRequest{
Ip: params.Ip,
GlobalOnly: params.GlobalOnly,
})
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()
listsResp, err := this.RPC().IPListRPC().ListEnabledIPLists(this.AdminContext(), &pb.ListEnabledIPListsRequest{
Type: params.Type,
IsPublic: true,
Keyword: params.Keyword,
Offset: page.Offset,
Size: page.Size,
itemsResp, err := this.RPC().IPItemRPC().ListAllEnabledIPItems(this.AdminContext(), &pb.ListAllEnabledIPItemsRequest{
Ip: params.Ip,
GlobalOnly: params.GlobalOnly,
Offset: page.Offset,
Size: page.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
var listMaps = []maps.Map{}
for _, list := range listsResp.IpLists {
// 包含的IP数量
countItemsResp, err := this.RPC().IPItemRPC().CountIPItemsWithListId(this.AdminContext(), &pb.CountIPItemsWithListIdRequest{IpListId: list.Id})
if err != nil {
this.ErrorPage(err)
return
}
var countItems = countItemsResp.Count
listMaps = append(listMaps, maps.Map{
"id": list.Id,
"isOn": list.IsOn,
"name": list.Name,
"description": list.Description,
"countItems": countItems,
"type": list.Type,
var itemMaps = []maps.Map{}
for _, result := range itemsResp.Results {
var item = result.IpItem
expiredTime := ""
if item.ExpiredAt > 0 {
expiredTime = timeutil.FormatTime("Y-m-d H:i:s", item.ExpiredAt)
}
// policy
var sourcePolicyMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallPolicy != nil {
sourcePolicyMap = maps.Map{
"id": item.SourceHTTPFirewallPolicy.Id,
"name": item.SourceHTTPFirewallPolicy.Name,
"serverId": item.SourceHTTPFirewallPolicy.ServerId,
}
}
// group
var sourceGroupMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallRuleGroup != nil {
sourceGroupMap = maps.Map{
"id": item.SourceHTTPFirewallRuleGroup.Id,
"name": item.SourceHTTPFirewallRuleGroup.Name,
}
}
// set
var sourceSetMap = maps.Map{"id": 0}
if item.SourceHTTPFirewallRuleSet != nil {
sourceSetMap = maps.Map{
"id": item.SourceHTTPFirewallRuleSet.Id,
"name": item.SourceHTTPFirewallRuleSet.Name,
}
}
// server
var sourceServerMap = maps.Map{"id": 0}
if item.SourceServer != nil {
sourceServerMap = maps.Map{
"id": item.SourceServer.Id,
"name": item.SourceServer.Name,
}
}
// IP名单
var listMap = maps.Map{"id": 0}
if result.IpList != nil {
listMap = maps.Map{
"id": result.IpList.Id,
"name": result.IpList.Name,
"type": result.IpList.Type,
}
}
// policy
var policyMap = maps.Map{"id": 0}
if result.HttpFirewallPolicy != nil {
policyMap = maps.Map{
"id": result.HttpFirewallPolicy.Id,
"name": result.HttpFirewallPolicy.Name,
}
if result.Server != nil {
policyMap["server"] = maps.Map{"id": result.Server.Id, "name": result.Server.Name}
}
}
itemMaps = append(itemMaps, maps.Map{
"id": item.Id,
"ipFrom": item.IpFrom,
"ipTo": item.IpTo,
"createdTime": timeutil.FormatTime("Y-m-d", item.CreatedAt),
"isExpired": item.ExpiredAt < time.Now().Unix(),
"expiredTime": expiredTime,
"reason": item.Reason,
"type": item.Type,
"eventLevelName": firewallconfigs.FindFirewallEventLevelName(item.EventLevel),
"sourcePolicy": sourcePolicyMap,
"sourceGroup": sourceGroupMap,
"sourceSet": sourceSetMap,
"sourceServer": sourceServerMap,
"list": listMap,
"policy": policyMap,
})
}
this.Data["lists"] = listMaps
this.Data["items"] = itemMaps
this.Show()
}

View File

@@ -14,12 +14,14 @@ func init() {
Data("teaSubMenu", "iplist").
Prefix("/servers/iplists").
Get("", new(IndexAction)).
Get("/lists", new(ListsAction)).
GetPost("/createPopup", new(CreatePopupAction)).
Get("/list", new(ListAction)).
GetPost("/import", new(ImportAction)).
GetPost("/export", new(ExportAction)).
Get("/exportData", new(ExportDataAction)).
Post("/delete", new(DeleteAction)).
Post("/deleteItems", new(DeleteItemsAction)).
GetPost("/test", new(TestAction)).
GetPost("/update", new(UpdateAction)).
Get("/items", new(ItemsAction)).
@@ -38,7 +40,6 @@ func init() {
// 选项数据
Post("/levelOptions", new(LevelOptionsAction)).
EndAll()
})
}

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