Compare commits
126 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2965d39af | ||
|
|
8279d15ebb | ||
|
|
9731fa35d8 | ||
|
|
53be4db22b | ||
|
|
0202fa2ca3 | ||
|
|
d5262b5474 | ||
|
|
cb2e1d54c2 | ||
|
|
6392297a27 | ||
|
|
6001d4eba3 | ||
|
|
79588e4bbc | ||
|
|
2b21c38382 | ||
|
|
481d25845e | ||
|
|
e0f8bfe283 | ||
|
|
d2ecb01358 | ||
|
|
316e793b1e | ||
|
|
6df6809ab3 | ||
|
|
c71f892601 | ||
|
|
d0b5a16ce7 | ||
|
|
84638d3228 | ||
|
|
bb21a2aa5f | ||
|
|
c37c948129 | ||
|
|
5155476dd7 | ||
|
|
7ef4f60309 | ||
|
|
b0865cbbdc | ||
|
|
990c1070e2 | ||
|
|
65bdd413eb | ||
|
|
60fa35eb73 | ||
|
|
32cfd5c233 | ||
|
|
7852495527 | ||
|
|
3679a78f47 | ||
|
|
6b21568408 | ||
|
|
04a5aa41d7 | ||
|
|
fea1a2199c | ||
|
|
9c8492efb9 | ||
|
|
20b89a8ddd | ||
|
|
5a8e281fb1 | ||
|
|
a9bb413199 | ||
|
|
428d8ab1b1 | ||
|
|
c2675bcdb6 | ||
|
|
1fe228e4c0 | ||
|
|
c5a6497f10 | ||
|
|
f25a82585f | ||
|
|
01209b66ac | ||
|
|
4e19817d6f | ||
|
|
a48adff8ac | ||
|
|
ab3b32fda1 | ||
|
|
cafab78ab4 | ||
|
|
2d497dee7d | ||
|
|
280ecd9aea | ||
|
|
3a980a3bc0 | ||
|
|
556a5bdd4e | ||
|
|
eca26a345f | ||
|
|
eacff7232d | ||
|
|
3c071db207 | ||
|
|
6609c56063 | ||
|
|
f7ae3de914 | ||
|
|
d82bc4e77e | ||
|
|
31e1df0afd | ||
|
|
700e9236f9 | ||
|
|
ee1e62aff0 | ||
|
|
aa0c38d66f | ||
|
|
4e4d9e33f0 | ||
|
|
f78daa98bc | ||
|
|
dad8802fb0 | ||
|
|
529b7041e7 | ||
|
|
5de1eecf92 | ||
|
|
08ee301f89 | ||
|
|
4154904b21 | ||
|
|
79282809e3 | ||
|
|
108c2533c2 | ||
|
|
fd7309cd17 | ||
|
|
c5f871edf6 | ||
|
|
3f2d2b238d | ||
|
|
e6a30b99d3 | ||
|
|
08ce2b7799 | ||
|
|
dbe7336f32 | ||
|
|
aac953f483 | ||
|
|
49bc469430 | ||
|
|
f3ac8a5cc5 | ||
|
|
847d08a9bb | ||
|
|
0563a363c2 | ||
|
|
f9dc0d6b54 | ||
|
|
40ef3604aa | ||
|
|
970604dc73 | ||
|
|
d6617f214d | ||
|
|
860fccbd4c | ||
|
|
b3adb839e0 | ||
|
|
5e9654c3bc | ||
|
|
43c6bff964 | ||
|
|
aef84189a4 | ||
|
|
04f8bfc975 | ||
|
|
d139e93160 | ||
|
|
1fcc0694ca | ||
|
|
7ba7858076 | ||
|
|
b1cbc433ed | ||
|
|
8beaf97306 | ||
|
|
e626364f45 | ||
|
|
ebaec51f67 | ||
|
|
36b90451af | ||
|
|
e0b1c2a6a4 | ||
|
|
42c6f4264e | ||
|
|
78641e7052 | ||
|
|
6bf0118d20 | ||
|
|
0415cd3719 | ||
|
|
a3412b2f95 | ||
|
|
6a4b3b026f | ||
|
|
f213976a5d | ||
|
|
3605f71f70 | ||
|
|
dc08847a7d | ||
|
|
a34204e25e | ||
|
|
25d73ac0a2 | ||
|
|
f67c0c0e75 | ||
|
|
08c8255d59 | ||
|
|
157efaa02e | ||
|
|
a56a29495e | ||
|
|
c454cd75b3 | ||
|
|
633684f576 | ||
|
|
de50b5e0a1 | ||
|
|
855f287e39 | ||
|
|
f018dee75e | ||
|
|
7d3b218e24 | ||
|
|
536382ce34 | ||
|
|
f6f003d524 | ||
|
|
8126de4048 | ||
|
|
4c41df85a0 | ||
|
|
2c9f78bb9e |
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
function build() {
|
||||
ROOT=$(dirname $0)
|
||||
ROOT=$(dirname "$0")
|
||||
JS_ROOT=$ROOT/../web/public/js
|
||||
NAME="edge-admin"
|
||||
DIST=$ROOT/"../dist/${NAME}"
|
||||
@@ -9,15 +9,15 @@ function build() {
|
||||
ARCH=${2}
|
||||
TAG=${3}
|
||||
|
||||
if [ -z $OS ]; then
|
||||
if [ -z "$OS" ]; then
|
||||
echo "usage: build.sh OS ARCH"
|
||||
exit
|
||||
fi
|
||||
if [ -z $ARCH ]; then
|
||||
if [ -z "$ARCH" ]; then
|
||||
echo "usage: build.sh OS ARCH"
|
||||
exit
|
||||
fi
|
||||
if [ -z $TAG ]; then
|
||||
if [ -z "$TAG" ]; then
|
||||
TAG="community"
|
||||
fi
|
||||
|
||||
@@ -25,7 +25,7 @@ function build() {
|
||||
echo "checking required commands ..."
|
||||
commands=("zip" "unzip" "go" "find" "sed")
|
||||
for cmd in "${commands[@]}"; do
|
||||
if [ `which ${cmd}` ]; then
|
||||
if [ "$(which "${cmd}")" ]; then
|
||||
echo "checking ${cmd}: ok"
|
||||
else
|
||||
echo "checking ${cmd}: not found"
|
||||
@@ -33,49 +33,49 @@ function build() {
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION=$(lookup-version $ROOT/../internal/const/const.go)
|
||||
VERSION=$(lookup-version "$ROOT"/../internal/const/const.go)
|
||||
ZIP="${NAME}-${OS}-${ARCH}-${TAG}-v${VERSION}.zip"
|
||||
|
||||
# build edge-api
|
||||
APINodeVersion=$(lookup-version $ROOT"/../../EdgeAPI/internal/const/const.go")
|
||||
APINodeVersion=$(lookup-version "$ROOT""/../../EdgeAPI/internal/const/const.go")
|
||||
echo "building edge-api v${APINodeVersion} ..."
|
||||
EDGE_API_BUILD_SCRIPT=$ROOT"/../../EdgeAPI/build/build.sh"
|
||||
if [ ! -f $EDGE_API_BUILD_SCRIPT ]; then
|
||||
if [ ! -f "$EDGE_API_BUILD_SCRIPT" ]; then
|
||||
echo "unable to find edge-api build script 'EdgeAPI/build/build.sh'"
|
||||
exit
|
||||
fi
|
||||
|
||||
cd $ROOT"/../../EdgeAPI/build"
|
||||
cd "$ROOT""/../../EdgeAPI/build" || exit
|
||||
echo "=============================="
|
||||
./build.sh $OS $ARCH $TAG
|
||||
./build.sh "$OS" "$ARCH" $TAG
|
||||
echo "=============================="
|
||||
cd -
|
||||
cd - || exit
|
||||
|
||||
# generate files
|
||||
echo "generating files ..."
|
||||
go run -tags $TAG $ROOT/../cmd/edge-admin/main.go generate
|
||||
if [ `which uglifyjs` ]; then
|
||||
go run -tags $TAG "$ROOT"/../cmd/edge-admin/main.go generate
|
||||
if [ "$(which uglifyjs)" ]; then
|
||||
echo "compress to component.js ..."
|
||||
uglifyjs --compress --mangle -- ${JS_ROOT}/components.src.js > ${JS_ROOT}/components.js
|
||||
uglifyjs --compress --mangle -- "${JS_ROOT}"/components.src.js > "${JS_ROOT}"/components.js
|
||||
else
|
||||
echo "copy to component.js ..."
|
||||
cp ${JS_ROOT}/components.src.js ${JS_ROOT}/components.js
|
||||
cp "${JS_ROOT}"/components.src.js "${JS_ROOT}"/components.js
|
||||
fi
|
||||
|
||||
# create dir & copy files
|
||||
echo "copying ..."
|
||||
if [ ! -d $DIST ]; then
|
||||
mkdir $DIST
|
||||
mkdir $DIST/bin
|
||||
mkdir $DIST/configs
|
||||
mkdir $DIST/logs
|
||||
if [ ! -d "$DIST" ]; then
|
||||
mkdir "$DIST"
|
||||
mkdir "$DIST"/bin
|
||||
mkdir "$DIST"/configs
|
||||
mkdir "$DIST"/logs
|
||||
fi
|
||||
|
||||
cp -R $ROOT/../web $DIST/
|
||||
rm -f $DIST/web/tmp/*
|
||||
rm -rf $DIST/web/public/js/components
|
||||
rm -f $DIST/web/public/js/components.src.js
|
||||
cp $ROOT/configs/server.template.yaml $DIST/configs/
|
||||
cp -R "$ROOT"/../web "$DIST"/
|
||||
rm -f "$DIST"/web/tmp/*
|
||||
rm -rf "$DIST"/web/public/js/components
|
||||
rm -f "$DIST"/web/public/js/components.src.js
|
||||
cp "$ROOT"/configs/server.template.yaml "$DIST"/configs/
|
||||
|
||||
# change _plus.[ext] to .[ext]
|
||||
if [ "${TAG}" = "plus" ]; then
|
||||
@@ -83,30 +83,30 @@ function build() {
|
||||
exts=("html" "js" "css")
|
||||
for ext in "${exts[@]}"; do
|
||||
pattern="*_plus."${ext}
|
||||
find $DIST/web/views -type f -name $pattern | \
|
||||
find "$DIST"/web/views -type f -name "$pattern" | \
|
||||
while read filename; do
|
||||
mv ${filename} "${filename/_plus."${ext}"/."${ext}"}"
|
||||
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/
|
||||
unzip -q $(basename $EDGE_API_ZIP_FILE)
|
||||
rm -f $(basename $EDGE_API_ZIP_FILE)
|
||||
cd -
|
||||
cp "$EDGE_API_ZIP_FILE" "$DIST"/
|
||||
cd "$DIST"/ || exit
|
||||
unzip -q "$(basename "$EDGE_API_ZIP_FILE")"
|
||||
rm -f "$(basename "$EDGE_API_ZIP_FILE")"
|
||||
cd - || exit
|
||||
|
||||
# build
|
||||
echo "building "${NAME}" ..."
|
||||
env GOOS=$OS GOARCH=$ARCH go build -tags $TAG -ldflags="-s -w" -o $DIST/bin/${NAME} $ROOT/../cmd/edge-admin/main.go
|
||||
echo "building ${NAME} ..."
|
||||
env GOOS="$OS" GOARCH="$ARCH" go build -trimpath -tags $TAG -ldflags="-s -w" -o "$DIST"/bin/${NAME} "$ROOT"/../cmd/edge-admin/main.go
|
||||
|
||||
# delete hidden files
|
||||
find $DIST -name ".DS_Store" -delete
|
||||
find $DIST -name ".gitignore" -delete
|
||||
find $DIST -name "*.less" -delete
|
||||
find $DIST -name "*.css.map" -delete
|
||||
find $DIST -name "*.js.map" -delete
|
||||
find "$DIST" -name ".DS_Store" -delete
|
||||
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 ..."
|
||||
@@ -123,15 +123,15 @@ function build() {
|
||||
|
||||
function lookup-version() {
|
||||
FILE=$1
|
||||
VERSION_DATA=$(cat $FILE)
|
||||
VERSION_DATA=$(cat "$FILE")
|
||||
re="Version[ ]+=[ ]+\"([0-9.]+)\""
|
||||
if [[ $VERSION_DATA =~ $re ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
echo $VERSION
|
||||
echo "$VERSION"
|
||||
else
|
||||
echo "could not match version"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
build $1 $2 $3
|
||||
build "$1" "$2" "$3"
|
||||
|
||||
2
dist/.gitignore
vendored
2
dist/.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
*.zip
|
||||
shield-admin
|
||||
edge-admin
|
||||
31
go.mod
31
go.mod
@@ -1,27 +1,44 @@
|
||||
module github.com/TeaOSLab/EdgeAdmin
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
replace github.com/TeaOSLab/EdgeCommon => ../EdgeCommon
|
||||
|
||||
require (
|
||||
github.com/TeaOSLab/EdgeCommon v0.0.0-00010101000000-000000000000
|
||||
github.com/cespare/xxhash v1.1.0
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/frankban/quicktest v1.11.3 // indirect
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/iwind/TeaGo v0.0.0-20220304043459-0dd944a5b475
|
||||
github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/miekg/dns v1.1.43
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.22.5
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/tealeg/xlsx/v3 v3.2.3
|
||||
github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
|
||||
google.golang.org/grpc v1.45.0
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/frankban/quicktest v1.11.3 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/btree v1.0.0 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kr/pretty v0.2.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/rogpeppe/fastuuid v1.2.0 // indirect
|
||||
github.com/shabbyrobe/xmlwriter v0.0.0-20200208144257-9fca06d00ffa // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
)
|
||||
|
||||
2
go.sum
2
go.sum
@@ -12,8 +12,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
|
||||
@@ -22,6 +22,7 @@ const (
|
||||
AdminModuleCodePlan AdminModuleCode = "plan" // 套餐
|
||||
AdminModuleCodeLog AdminModuleCode = "log" // 日志
|
||||
AdminModuleCodeSetting AdminModuleCode = "setting" // 设置
|
||||
AdminModuleCodeTicket AdminModuleCode = "ticket" // 工单
|
||||
AdminModuleCodeCommon AdminModuleCode = "common" // 只要登录就可以访问的模块
|
||||
)
|
||||
|
||||
@@ -159,7 +160,7 @@ func UpdateAdminTheme(adminId int64, theme string) {
|
||||
|
||||
// AllModuleMaps 所有权限列表
|
||||
func AllModuleMaps() []maps.Map {
|
||||
m := []maps.Map{
|
||||
var m = []maps.Map{
|
||||
{
|
||||
"name": "看板",
|
||||
"code": AdminModuleCodeDashboard,
|
||||
@@ -204,11 +205,24 @@ func AllModuleMaps() []maps.Map {
|
||||
"code": AdminModuleCodeFinance,
|
||||
"url": "/finance",
|
||||
},
|
||||
{
|
||||
"name": "套餐管理",
|
||||
"code": AdminModuleCodePlan,
|
||||
"url": "/plans",
|
||||
},
|
||||
}...)
|
||||
|
||||
if teaconst.IsPlus {
|
||||
m = append(m, []maps.Map{
|
||||
{
|
||||
"name": "套餐管理",
|
||||
"code": AdminModuleCodePlan,
|
||||
"url": "/plans",
|
||||
},
|
||||
{
|
||||
"name": "工单系统",
|
||||
"code": AdminModuleCodeTicket,
|
||||
"url": "/tickets",
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
m = append(m, []maps.Map{
|
||||
{
|
||||
"name": "日志审计",
|
||||
"code": AdminModuleCodeLog,
|
||||
|
||||
@@ -26,6 +26,15 @@ func LoadAdminUIConfig() (*systemconfigs.AdminUIConfig, error) {
|
||||
return &v, nil
|
||||
}
|
||||
|
||||
func ReloadAdminUIConfig() error {
|
||||
locker.Lock()
|
||||
defer locker.Unlock()
|
||||
|
||||
sharedAdminUIConfig = nil
|
||||
_, err := loadAdminUIConfig()
|
||||
return err
|
||||
}
|
||||
|
||||
func UpdateAdminUIConfig(uiConfig *systemconfigs.AdminUIConfig) error {
|
||||
locker.Lock()
|
||||
defer locker.Unlock()
|
||||
|
||||
@@ -84,10 +84,13 @@ func loadUserUIConfig() (*systemconfigs.UserUIConfig, error) {
|
||||
|
||||
func defaultUserUIConfig() *systemconfigs.UserUIConfig {
|
||||
return &systemconfigs.UserUIConfig{
|
||||
ProductName: "GoEdge",
|
||||
UserSystemName: "GoEdge用户系统",
|
||||
ShowOpenSourceInfo: true,
|
||||
ShowVersion: true,
|
||||
ShowFinance: true,
|
||||
ProductName: "GoEdge",
|
||||
UserSystemName: "GoEdge用户系统",
|
||||
ShowOpenSourceInfo: true,
|
||||
ShowVersion: true,
|
||||
ShowFinance: true,
|
||||
BandwidthUnit: systemconfigs.BandwidthUnitBit,
|
||||
ShowBandwidthCharts: true,
|
||||
ShowTrafficCharts: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
@@ -12,7 +11,8 @@ import (
|
||||
// APIConfig API配置
|
||||
type APIConfig struct {
|
||||
RPC struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
} `yaml:"rpc"`
|
||||
NodeId string `yaml:"nodeId"`
|
||||
Secret string `yaml:"secret"`
|
||||
@@ -33,7 +33,7 @@ func LoadAPIConfig() (*APIConfig, error) {
|
||||
var data []byte
|
||||
var err error
|
||||
for _, path := range paths {
|
||||
data, err = ioutil.ReadFile(path)
|
||||
data, err = os.ReadFile(path)
|
||||
if err == nil {
|
||||
if path == localFile {
|
||||
isFromLocal = true
|
||||
@@ -53,7 +53,7 @@ func LoadAPIConfig() (*APIConfig, error) {
|
||||
|
||||
if !isFromLocal {
|
||||
// 恢复文件
|
||||
_ = ioutil.WriteFile(localFile, data, 0666)
|
||||
_ = os.WriteFile(localFile, data, 0666)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
@@ -109,41 +109,48 @@ func (this *APIConfig) WriteFile(path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.WriteFile(path, data, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 写入 ~/ 和 /etc/ 目录,因为是备份需要,所以不需要提示错误信息
|
||||
// 写入 ~/.edge-admin/
|
||||
filename := filepath.Base(path)
|
||||
// 这个用来判断用户是否为重装,所以比较重要
|
||||
var filename = filepath.Base(path)
|
||||
homeDir, homeErr := os.UserHomeDir()
|
||||
if homeErr == nil {
|
||||
dir := homeDir + "/." + teaconst.ProcessName
|
||||
stat, err := os.Stat(dir)
|
||||
if err == nil && stat.IsDir() {
|
||||
_ = ioutil.WriteFile(dir+"/"+filename, data, 0666)
|
||||
err = os.WriteFile(dir+"/"+filename, data, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err != nil && os.IsNotExist(err) {
|
||||
err = os.Mkdir(dir, 0777)
|
||||
if err == nil {
|
||||
_ = ioutil.WriteFile(dir+"/"+filename, data, 0666)
|
||||
err = os.WriteFile(dir+"/"+filename, data, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 写入 /etc/edge-admin
|
||||
{
|
||||
dir := "/etc/" + teaconst.ProcessName
|
||||
var dir = "/etc/" + teaconst.ProcessName
|
||||
stat, err := os.Stat(dir)
|
||||
if err == nil && stat.IsDir() {
|
||||
_ = ioutil.WriteFile(dir+"/"+filename, data, 0666)
|
||||
_ = os.WriteFile(dir+"/"+filename, data, 0666)
|
||||
} else if err != nil && os.IsNotExist(err) {
|
||||
err = os.Mkdir(dir, 0777)
|
||||
if err == nil {
|
||||
_ = ioutil.WriteFile(dir+"/"+filename, data, 0666)
|
||||
_ = os.WriteFile(dir+"/"+filename, data, 0666)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(path, data, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ package configs
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
var plusConfigFile = "plus.cache.json"
|
||||
@@ -17,7 +17,7 @@ type PlusConfig struct {
|
||||
}
|
||||
|
||||
func ReadPlusConfig() *PlusConfig {
|
||||
data, err := ioutil.ReadFile(Tea.ConfigFile(plusConfigFile))
|
||||
data, err := os.ReadFile(Tea.ConfigFile(plusConfigFile))
|
||||
if err != nil {
|
||||
return &PlusConfig{IsPlus: false}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ func WritePlusConfig(config *PlusConfig) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = ioutil.WriteFile(Tea.ConfigFile(plusConfigFile), configJSON, 0777)
|
||||
err = os.WriteFile(Tea.ConfigFile(plusConfigFile), configJSON, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
// +build !plus
|
||||
//go:build !plus
|
||||
|
||||
package teaconst
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
Version = "0.4.8"
|
||||
Version = "0.5.2.1"
|
||||
|
||||
APINodeVersion = "0.4.8"
|
||||
APINodeVersion = "0.5.2.1"
|
||||
|
||||
ProductName = "Edge Admin"
|
||||
ProcessName = "edge-admin"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package teaconst
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// 生成Token
|
||||
// Generate 生成Token
|
||||
func Generate() string {
|
||||
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
|
||||
|
||||
@@ -23,7 +23,7 @@ func Generate() string {
|
||||
return token
|
||||
}
|
||||
|
||||
// 校验Token
|
||||
// Validate 校验Token
|
||||
func Validate(token string) (b bool) {
|
||||
if len(token) == 0 {
|
||||
return
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"github.com/iwind/gosock/pkg/gosock"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
@@ -173,9 +172,9 @@ func (this *AdminNode) checkServer() error {
|
||||
if os.IsNotExist(err) {
|
||||
// 创建文件
|
||||
templateFile := Tea.ConfigFile("server.template.yaml")
|
||||
data, err := ioutil.ReadFile(templateFile)
|
||||
data, err := os.ReadFile(templateFile)
|
||||
if err == nil {
|
||||
err = ioutil.WriteFile(configFile, data, 0666)
|
||||
err = os.WriteFile(configFile, data, 0666)
|
||||
if err != nil {
|
||||
return errors.New("create config file failed: " + err.Error())
|
||||
}
|
||||
@@ -195,7 +194,7 @@ https:
|
||||
cert: ""
|
||||
key: ""
|
||||
`
|
||||
err = ioutil.WriteFile(configFile, []byte(templateYAML), 0666)
|
||||
err = os.WriteFile(configFile, []byte(templateYAML), 0666)
|
||||
if err != nil {
|
||||
return errors.New("create config file failed: " + err.Error())
|
||||
}
|
||||
@@ -210,7 +209,7 @@ https:
|
||||
// 添加端口到防火墙
|
||||
func (this *AdminNode) addPortsToFirewall() {
|
||||
var configFile = Tea.ConfigFile("server.yaml")
|
||||
data, err := ioutil.ReadFile(configFile)
|
||||
data, err := os.ReadFile(configFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -263,9 +262,9 @@ func (this *AdminNode) startAPINode() {
|
||||
for _, path := range paths {
|
||||
_, err = os.Stat(path)
|
||||
if err == nil {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
data, err := os.ReadFile(path)
|
||||
if err == nil {
|
||||
err = ioutil.WriteFile(configPath, data, 0666)
|
||||
err = os.WriteFile(configPath, data, 0666)
|
||||
if err == nil {
|
||||
logs.Println("[NODE]recover 'edge-api/configs/api.yaml' from '" + path + "'")
|
||||
canStart = true
|
||||
@@ -289,9 +288,9 @@ func (this *AdminNode) startAPINode() {
|
||||
for _, path := range paths {
|
||||
_, err = os.Stat(path)
|
||||
if err == nil {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
data, err := os.ReadFile(path)
|
||||
if err == nil {
|
||||
err = ioutil.WriteFile(dbPath, data, 0666)
|
||||
err = os.WriteFile(dbPath, data, 0666)
|
||||
if err == nil {
|
||||
logs.Println("[NODE]recover 'edge-api/configs/db.yaml' from '" + path + "'")
|
||||
break
|
||||
@@ -316,12 +315,12 @@ func (this *AdminNode) startAPINode() {
|
||||
// 生成Secret
|
||||
func (this *AdminNode) genSecret() string {
|
||||
tmpFile := os.TempDir() + "/edge-admin-secret.tmp"
|
||||
data, err := ioutil.ReadFile(tmpFile)
|
||||
data, err := os.ReadFile(tmpFile)
|
||||
if err == nil && len(data) == 32 {
|
||||
return string(data)
|
||||
}
|
||||
secret := rands.String(32)
|
||||
_ = ioutil.WriteFile(tmpFile, []byte(secret), 0666)
|
||||
_ = os.WriteFile(tmpFile, []byte(secret), 0666)
|
||||
return secret
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
"google.golang.org/grpc"
|
||||
@@ -19,7 +20,9 @@ import (
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/encoding/gzip"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@@ -38,7 +41,7 @@ func NewRPCClient(apiConfig *configs.APIConfig, isPrimary bool) (*RPCClient, err
|
||||
return nil, errors.New("api config should not be nil")
|
||||
}
|
||||
|
||||
client := &RPCClient{
|
||||
var client = &RPCClient{
|
||||
apiConfig: apiConfig,
|
||||
}
|
||||
|
||||
@@ -123,6 +126,10 @@ func (this *RPCClient) ServerRPC() pb.ServerServiceClient {
|
||||
return pb.NewServerServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ServerBandwidthStatRPC() pb.ServerBandwidthStatServiceClient {
|
||||
return pb.NewServerBandwidthStatServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ServerClientSystemMonthlyStatRPC() pb.ServerClientSystemMonthlyStatServiceClient {
|
||||
return pb.NewServerClientSystemMonthlyStatServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -316,22 +323,18 @@ func (this *RPCClient) IPLibraryRPC() pb.IPLibraryServiceClient {
|
||||
return pb.NewIPLibraryServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) IPLibraryFileRPC() pb.IPLibraryFileServiceClient {
|
||||
return pb.NewIPLibraryFileServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) IPLibraryArtifactRPC() pb.IPLibraryArtifactServiceClient {
|
||||
return pb.NewIPLibraryArtifactServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) IPListRPC() pb.IPListServiceClient {
|
||||
return pb.NewIPListServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ReportNodeRPC() pb.ReportNodeServiceClient {
|
||||
return pb.NewReportNodeServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ReportNodeGroupRPC() pb.ReportNodeGroupServiceClient {
|
||||
return pb.NewReportNodeGroupServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ReportResultRPC() pb.ReportResultServiceClient {
|
||||
return pb.NewReportResultServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) IPItemRPC() pb.IPItemServiceClient {
|
||||
return pb.NewIPItemServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -356,6 +359,10 @@ func (this *RPCClient) RegionCityRPC() pb.RegionCityServiceClient {
|
||||
return pb.NewRegionCityServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) RegionTownRPC() pb.RegionTownServiceClient {
|
||||
return pb.NewRegionTownServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) RegionProviderRPC() pb.RegionProviderServiceClient {
|
||||
return pb.NewRegionProviderServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -424,6 +431,10 @@ func (this *RPCClient) UserAccessKeyRPC() pb.UserAccessKeyServiceClient {
|
||||
return pb.NewUserAccessKeyServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) UserIdentityRPC() pb.UserIdentityServiceClient {
|
||||
return pb.NewUserIdentityServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) LoginRPC() pb.LoginServiceClient {
|
||||
return pb.NewLoginServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -444,42 +455,6 @@ func (this *RPCClient) LatestItemRPC() pb.LatestItemServiceClient {
|
||||
return pb.NewLatestItemServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSClusterRPC() pb.NSClusterServiceClient {
|
||||
return pb.NewNSClusterServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSNodeRPC() pb.NSNodeServiceClient {
|
||||
return pb.NewNSNodeServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSDomainRPC() pb.NSDomainServiceClient {
|
||||
return pb.NewNSDomainServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSRecordRPC() pb.NSRecordServiceClient {
|
||||
return pb.NewNSRecordServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSKeyRPC() pb.NSKeyServiceClient {
|
||||
return pb.NewNSKeyServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSRouteRPC() pb.NSRouteServiceClient {
|
||||
return pb.NewNSRouteServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSAccessLogRPC() pb.NSAccessLogServiceClient {
|
||||
return pb.NewNSAccessLogServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSRPC() pb.NSServiceClient {
|
||||
return pb.NewNSServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NSQuestionOptionRPC() pb.NSQuestionOptionServiceClient {
|
||||
return pb.NewNSQuestionOptionServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) MetricItemRPC() pb.MetricItemServiceClient {
|
||||
return pb.NewMetricItemServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -522,8 +497,8 @@ func (this *RPCClient) TrafficDailyStatRPC() pb.TrafficDailyStatServiceClient {
|
||||
|
||||
// Context 构造Admin上下文
|
||||
func (this *RPCClient) Context(adminId int64) context.Context {
|
||||
ctx := context.Background()
|
||||
m := maps.Map{
|
||||
var ctx = context.Background()
|
||||
var m = maps.Map{
|
||||
"timestamp": time.Now().Unix(),
|
||||
"type": "admin",
|
||||
"userId": adminId,
|
||||
@@ -538,15 +513,15 @@ func (this *RPCClient) Context(adminId int64) context.Context {
|
||||
utils.PrintError(err)
|
||||
return context.Background()
|
||||
}
|
||||
token := base64.StdEncoding.EncodeToString(data)
|
||||
var token = base64.StdEncoding.EncodeToString(data)
|
||||
ctx = metadata.AppendToOutgoingContext(ctx, "nodeId", this.apiConfig.NodeId, "token", token)
|
||||
return ctx
|
||||
}
|
||||
|
||||
// APIContext 构造API上下文
|
||||
func (this *RPCClient) APIContext(apiNodeId int64) context.Context {
|
||||
ctx := context.Background()
|
||||
m := maps.Map{
|
||||
var ctx = context.Background()
|
||||
var m = maps.Map{
|
||||
"timestamp": time.Now().Unix(),
|
||||
"type": "api",
|
||||
"userId": apiNodeId,
|
||||
@@ -561,7 +536,7 @@ func (this *RPCClient) APIContext(apiNodeId int64) context.Context {
|
||||
utils.PrintError(err)
|
||||
return context.Background()
|
||||
}
|
||||
token := base64.StdEncoding.EncodeToString(data)
|
||||
var token = base64.StdEncoding.EncodeToString(data)
|
||||
ctx = metadata.AppendToOutgoingContext(ctx, "nodeId", this.apiConfig.NodeId, "token", token)
|
||||
return ctx
|
||||
}
|
||||
@@ -578,20 +553,39 @@ func (this *RPCClient) UpdateConfig(config *configs.APIConfig) error {
|
||||
|
||||
// 初始化
|
||||
func (this *RPCClient) init() error {
|
||||
// 当前的IP地址
|
||||
var localIPAddrs = this.localIPAddrs()
|
||||
|
||||
// 重新连接
|
||||
conns := []*grpc.ClientConn{}
|
||||
var conns = []*grpc.ClientConn{}
|
||||
for _, endpoint := range this.apiConfig.RPC.Endpoints {
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return errors.New("parse endpoint failed: " + err.Error())
|
||||
}
|
||||
|
||||
var apiHost = u.Host
|
||||
|
||||
// 如果本机,则将地址修改为回路地址
|
||||
if lists.ContainsString(localIPAddrs, u.Hostname()) {
|
||||
if strings.Contains(apiHost, "[") { // IPv6 [host]:port
|
||||
apiHost = "[::1]"
|
||||
} else {
|
||||
apiHost = "127.0.0.1"
|
||||
}
|
||||
var port = u.Port()
|
||||
if len(port) > 0 {
|
||||
apiHost += ":" + port
|
||||
}
|
||||
}
|
||||
|
||||
var conn *grpc.ClientConn
|
||||
var callOptions = grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(128*1024*1024),
|
||||
grpc.UseCompressor(gzip.Name))
|
||||
if u.Scheme == "http" {
|
||||
conn, err = grpc.Dial(u.Host, grpc.WithTransportCredentials(insecure.NewCredentials()), callOptions)
|
||||
conn, err = grpc.Dial(apiHost, grpc.WithTransportCredentials(insecure.NewCredentials()), callOptions)
|
||||
} else if u.Scheme == "https" {
|
||||
conn, err = grpc.Dial(u.Host, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
|
||||
conn, err = grpc.Dial(apiHost, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
})), callOptions)
|
||||
} else {
|
||||
@@ -618,7 +612,7 @@ func (this *RPCClient) pickConn() *grpc.ClientConn {
|
||||
|
||||
// 检查连接状态
|
||||
if len(this.conns) > 0 {
|
||||
availableConns := []*grpc.ClientConn{}
|
||||
var availableConns = []*grpc.ClientConn{}
|
||||
for _, state := range []connectivity.State{connectivity.Ready, connectivity.Idle, connectivity.Connecting} {
|
||||
for _, conn := range this.conns {
|
||||
if conn.GetState() == state {
|
||||
@@ -670,3 +664,18 @@ func (this *RPCClient) Close() error {
|
||||
|
||||
return lastErr
|
||||
}
|
||||
|
||||
func (this *RPCClient) localIPAddrs() []string {
|
||||
localInterfaceAddrs, err := net.InterfaceAddrs()
|
||||
var localIPAddrs = []string{}
|
||||
if err == nil {
|
||||
for _, addr := range localInterfaceAddrs {
|
||||
var addrString = addr.String()
|
||||
var index = strings.Index(addrString, "/")
|
||||
if index > 0 {
|
||||
localIPAddrs = append(localIPAddrs, addrString[:index])
|
||||
}
|
||||
}
|
||||
}
|
||||
return localIPAddrs
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ func TestRPCClient_NodeRPC(t *testing.T) {
|
||||
func TestRPC_Dial_HTTP(t *testing.T) {
|
||||
client, err := NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
}{
|
||||
Endpoints: []string{"http://127.0.0.1:8004"},
|
||||
},
|
||||
@@ -56,7 +57,8 @@ func TestRPC_Dial_HTTP(t *testing.T) {
|
||||
func TestRPC_Dial_HTTP_2(t *testing.T) {
|
||||
client, err := NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
}{
|
||||
Endpoints: []string{"https://127.0.0.1:8003"},
|
||||
},
|
||||
@@ -77,7 +79,8 @@ func TestRPC_Dial_HTTP_2(t *testing.T) {
|
||||
func TestRPC_Dial_HTTPS(t *testing.T) {
|
||||
client, err := NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
}{
|
||||
Endpoints: []string{"https://127.0.0.1:8004"},
|
||||
},
|
||||
@@ -94,3 +97,53 @@ func TestRPC_Dial_HTTPS(t *testing.T) {
|
||||
}
|
||||
t.Log(resp.Node)
|
||||
}
|
||||
|
||||
func BenchmarkNewRPCClient(b *testing.B) {
|
||||
config, err := configs.LoadAPIConfig()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
rpc, err := NewRPCClient(config, true)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
resp, err := rpc.AdminRPC().LoginAdmin(rpc.Context(0), &pb.LoginAdminRequest{
|
||||
Username: "admin",
|
||||
Password: stringutil.Md5("123456"),
|
||||
})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
_ = resp
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewRPCClient_2(b *testing.B) {
|
||||
config, err := configs.LoadAPIConfig()
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
rpc, err := NewRPCClient(config, true)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
var conn = rpc.AdminRPC()
|
||||
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
resp, err := conn.LoginAdmin(rpc.Context(0), &pb.LoginAdminRequest{
|
||||
Username: "admin",
|
||||
Password: stringutil.Md5("123456"),
|
||||
})
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
_ = resp
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -95,7 +95,7 @@ func (this *CheckUpdatesTask) Loop() error {
|
||||
defer func() {
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.New("read api failed: " + err.Error())
|
||||
}
|
||||
|
||||
@@ -58,6 +58,16 @@ func (this *SyncAPINodesTask) Loop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
config, err := configs.LoadAPIConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 是否禁止自动升级
|
||||
if config.RPC.DisableUpdate {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 获取所有可用的节点
|
||||
rpcClient, err := rpc.SharedRPC()
|
||||
if err != nil {
|
||||
@@ -68,7 +78,7 @@ func (this *SyncAPINodesTask) Loop() error {
|
||||
return err
|
||||
}
|
||||
|
||||
newEndpoints := []string{}
|
||||
var newEndpoints = []string{}
|
||||
for _, node := range resp.ApiNodes {
|
||||
if !node.IsOn {
|
||||
continue
|
||||
@@ -77,10 +87,6 @@ func (this *SyncAPINodesTask) Loop() error {
|
||||
}
|
||||
|
||||
// 和现有的对比
|
||||
config, err := configs.LoadAPIConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if this.isSame(newEndpoints, config.RPC.Endpoints) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package nodelogutils
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build linux
|
||||
//go:build linux
|
||||
|
||||
package utils
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/files"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
@@ -16,7 +15,7 @@ import (
|
||||
var systemdServiceFile = "/etc/systemd/system/edge-admin.service"
|
||||
var initServiceFile = "/etc/init.d/" + teaconst.SystemdServiceName
|
||||
|
||||
// 安装服务
|
||||
// Install 安装服务
|
||||
func (this *ServiceManager) Install(exePath string, args []string) error {
|
||||
if os.Getgid() != 0 {
|
||||
return errors.New("only root users can install the service")
|
||||
@@ -30,7 +29,7 @@ func (this *ServiceManager) Install(exePath string, args []string) error {
|
||||
return this.installSystemdService(systemd, exePath, args)
|
||||
}
|
||||
|
||||
// 启动服务
|
||||
// Start 启动服务
|
||||
func (this *ServiceManager) Start() error {
|
||||
if os.Getgid() != 0 {
|
||||
return errors.New("only root users can start the service")
|
||||
@@ -47,7 +46,7 @@ func (this *ServiceManager) Start() error {
|
||||
return exec.Command("service", teaconst.ProcessName, "start").Start()
|
||||
}
|
||||
|
||||
// 删除服务
|
||||
// Uninstall 删除服务
|
||||
func (this *ServiceManager) Uninstall() error {
|
||||
if os.Getgid() != 0 {
|
||||
return errors.New("only root users can uninstall the service")
|
||||
@@ -83,13 +82,13 @@ func (this *ServiceManager) installInitService(exePath string, args []string) er
|
||||
return errors.New("'scripts/" + shortName + "' file not exists")
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(scriptFile)
|
||||
data, err := os.ReadFile(scriptFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data = regexp.MustCompile("INSTALL_DIR=.+").ReplaceAll(data, []byte("INSTALL_DIR="+Tea.Root))
|
||||
err = ioutil.WriteFile(initServiceFile, data, 0777)
|
||||
err = os.WriteFile(initServiceFile, data, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -137,7 +136,7 @@ ExecReload=` + exePath + ` reload
|
||||
WantedBy=multi-user.target`
|
||||
|
||||
// write file
|
||||
err := ioutil.WriteFile(systemdServiceFile, []byte(desc), 0777)
|
||||
err := os.WriteFile(systemdServiceFile, []byte(desc), 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build !linux,!windows
|
||||
//go:build !linux && !windows
|
||||
|
||||
package utils
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// +build windows
|
||||
//go:build windows
|
||||
|
||||
package utils
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// format address
|
||||
// FormatAddress format address
|
||||
func FormatAddress(addr string) string {
|
||||
if strings.HasSuffix(addr, "unix:") {
|
||||
return addr
|
||||
@@ -17,7 +17,7 @@ func FormatAddress(addr string) string {
|
||||
return addr
|
||||
}
|
||||
|
||||
// 分割数字
|
||||
// SplitNumbers 分割数字
|
||||
func SplitNumbers(numbers string) (result []int64) {
|
||||
if len(numbers) == 0 {
|
||||
return
|
||||
|
||||
67
internal/utils/strings_stream.go
Normal file
67
internal/utils/strings_stream.go
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func FilterNotEmpty(item string) bool {
|
||||
return len(item) > 0
|
||||
}
|
||||
|
||||
func MapAddPrefixFunc(prefix string) func(item string) string {
|
||||
return func(item string) string {
|
||||
if !strings.HasPrefix(item, prefix) {
|
||||
return prefix + item
|
||||
}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
type StringsStream struct {
|
||||
s []string
|
||||
}
|
||||
|
||||
func NewStringsStream(s []string) *StringsStream {
|
||||
return &StringsStream{s: s}
|
||||
}
|
||||
|
||||
func (this *StringsStream) Map(f ...func(item string) string) *StringsStream {
|
||||
for index, item := range this.s {
|
||||
for _, f1 := range f {
|
||||
item = f1(item)
|
||||
}
|
||||
this.s[index] = item
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *StringsStream) Filter(f ...func(item string) bool) *StringsStream {
|
||||
for _, f1 := range f {
|
||||
var newStrings = []string{}
|
||||
for _, item := range this.s {
|
||||
if f1(item) {
|
||||
newStrings = append(newStrings, item)
|
||||
}
|
||||
}
|
||||
this.s = newStrings
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *StringsStream) Unique() *StringsStream {
|
||||
var newStrings = []string{}
|
||||
for _, item := range this.s {
|
||||
if !lists.ContainsString(newStrings, item) {
|
||||
newStrings = append(newStrings, item)
|
||||
}
|
||||
}
|
||||
this.s = newStrings
|
||||
return this
|
||||
}
|
||||
|
||||
func (this *StringsStream) Result() []string {
|
||||
return this.s
|
||||
}
|
||||
25
internal/utils/strings_stream_test.go
Normal file
25
internal/utils/strings_stream_test.go
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package utils_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStringsStream_Filter(t *testing.T) {
|
||||
var stream = utils.NewStringsStream([]string{"a", "b", "1", "2", "", "png", "a"})
|
||||
stream.Filter(func(item string) bool {
|
||||
return len(item) > 0
|
||||
})
|
||||
t.Log(stream.Result())
|
||||
stream.Map(func(item string) string {
|
||||
return "." + item
|
||||
})
|
||||
t.Log(stream.Result())
|
||||
stream.Unique()
|
||||
t.Log(stream.Result())
|
||||
stream.Map(strings.ToUpper, strings.ToLower)
|
||||
t.Log(stream.Result())
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func (this *Page) AsHTML() string {
|
||||
}
|
||||
|
||||
// 每页数
|
||||
result = append(result, `<select class="ui dropdown" style="height:34px;padding-top:0;padding-bottom:0;margin-left:1em;color:#666" onchange="ChangePageSize(this.value)">
|
||||
result = append(result, `<select class="ui dropdown" style="padding-top:0;padding-bottom:0;margin-left:1em;color:#666" onchange="ChangePageSize(this.value)">
|
||||
<option value="10">[每页]</option>`+this.renderSizeOption(10)+
|
||||
this.renderSizeOption(20)+
|
||||
this.renderSizeOption(30)+
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -68,7 +67,7 @@ func FailPage(action actions.ActionWrapper, err error) {
|
||||
var issuesHTML = ""
|
||||
if isLocalAPI {
|
||||
// 读取本地API节点的issues
|
||||
issuesData, issuesErr := ioutil.ReadFile(Tea.Root + "/edge-api/logs/issues.log")
|
||||
issuesData, issuesErr := os.ReadFile(Tea.Root + "/edge-api/logs/issues.log")
|
||||
if issuesErr == nil {
|
||||
var issueMaps = []maps.Map{}
|
||||
issuesErr = json.Unmarshal(issuesData, &issueMaps)
|
||||
|
||||
@@ -27,14 +27,14 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
admin := adminResp.Admin
|
||||
var admin = adminResp.Admin
|
||||
if admin == nil {
|
||||
this.NotFound("admin", params.AdminId)
|
||||
return
|
||||
}
|
||||
|
||||
// OTP认证
|
||||
otpLoginIsOn := false
|
||||
var otpLoginIsOn = false
|
||||
if admin.OtpLogin != nil {
|
||||
otpLoginIsOn = admin.OtpLogin.IsOn
|
||||
}
|
||||
@@ -45,7 +45,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
countAccessKeys := countAccessKeyResp.Count
|
||||
var countAccessKeys = countAccessKeyResp.Count
|
||||
|
||||
this.Data["admin"] = maps.Map{
|
||||
"id": admin.Id,
|
||||
@@ -59,7 +59,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 权限
|
||||
moduleMaps := configloaders.AllModuleMaps()
|
||||
var moduleMaps = configloaders.AllModuleMaps()
|
||||
for _, m := range moduleMaps {
|
||||
code := m.GetString("code")
|
||||
isChecked := false
|
||||
|
||||
@@ -5,9 +5,12 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"net"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 添加地址
|
||||
// CreateAddrPopupAction 添加地址
|
||||
type CreateAddrPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -30,12 +33,31 @@ func (this *CreateAddrPopupAction) RunPost(params struct {
|
||||
Field("addr", params.Addr).
|
||||
Require("请输入访问地址")
|
||||
|
||||
// 兼容URL
|
||||
if regexp.MustCompile(`^(?i)(http|https)://`).MatchString(params.Addr) {
|
||||
u, err := url.Parse(params.Addr)
|
||||
if err != nil {
|
||||
this.FailField("addr", "错误的访问地址,不需要添加http://或https://")
|
||||
}
|
||||
params.Addr = u.Host
|
||||
}
|
||||
|
||||
// 自动添加端口
|
||||
if !strings.Contains(params.Addr, ":") {
|
||||
switch params.Protocol {
|
||||
case "http":
|
||||
params.Addr += ":80"
|
||||
case "https":
|
||||
params.Addr += ":443"
|
||||
}
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(params.Addr)
|
||||
if err != nil {
|
||||
this.FailField("addr", "错误的访问地址")
|
||||
}
|
||||
|
||||
addrConfig := &serverconfigs.NetworkAddressConfig{
|
||||
var addrConfig = &serverconfigs.NetworkAddressConfig{
|
||||
Protocol: serverconfigs.Protocol(params.Protocol),
|
||||
Host: host,
|
||||
PortRange: port,
|
||||
|
||||
@@ -2,11 +2,17 @@ package node
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"time"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -25,7 +31,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.ApiNode
|
||||
var node = nodeResp.ApiNode
|
||||
if node == nil {
|
||||
this.NotFound("apiNode", params.NodeId)
|
||||
return
|
||||
@@ -33,7 +39,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
|
||||
// 监听地址
|
||||
var hasHTTPS = false
|
||||
httpConfig := &serverconfigs.HTTPProtocolConfig{}
|
||||
var httpConfig = &serverconfigs.HTTPProtocolConfig{}
|
||||
if len(node.HttpJSON) > 0 {
|
||||
err = json.Unmarshal(node.HttpJSON, httpConfig)
|
||||
if err != nil {
|
||||
@@ -41,7 +47,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
}
|
||||
httpsConfig := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var httpsConfig = &serverconfigs.HTTPSProtocolConfig{}
|
||||
if len(node.HttpsJSON) > 0 {
|
||||
err = json.Unmarshal(node.HttpsJSON, httpsConfig)
|
||||
if err != nil {
|
||||
@@ -52,21 +58,21 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 监听地址
|
||||
listens := []*serverconfigs.NetworkAddressConfig{}
|
||||
var listens = []*serverconfigs.NetworkAddressConfig{}
|
||||
listens = append(listens, httpConfig.Listen...)
|
||||
listens = append(listens, httpsConfig.Listen...)
|
||||
|
||||
// 证书信息
|
||||
certs := []*sslconfigs.SSLCertConfig{}
|
||||
var certs = []*sslconfigs.SSLCertConfig{}
|
||||
if httpsConfig.SSLPolicyRef != nil && httpsConfig.SSLPolicyRef.SSLPolicyId > 0 {
|
||||
sslPolicyConfigResp, err := this.RPC().SSLPolicyRPC().FindEnabledSSLPolicyConfig(this.AdminContext(), &pb.FindEnabledSSLPolicyConfigRequest{SslPolicyId: httpsConfig.SSLPolicyRef.SSLPolicyId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
sslPolicyConfigJSON := sslPolicyConfigResp.SslPolicyJSON
|
||||
var sslPolicyConfigJSON = sslPolicyConfigResp.SslPolicyJSON
|
||||
if len(sslPolicyConfigJSON) > 0 {
|
||||
sslPolicy := &sslconfigs.SSLPolicy{}
|
||||
var sslPolicy = &sslconfigs.SSLPolicy{}
|
||||
err = json.Unmarshal(sslPolicyConfigJSON, sslPolicy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -77,7 +83,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 访问地址
|
||||
accessAddrs := []*serverconfigs.NetworkAddressConfig{}
|
||||
var accessAddrs = []*serverconfigs.NetworkAddressConfig{}
|
||||
if len(node.AccessAddrsJSON) > 0 {
|
||||
err = json.Unmarshal(node.AccessAddrsJSON, &accessAddrs)
|
||||
if err != nil {
|
||||
@@ -87,10 +93,10 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// Rest地址
|
||||
restAccessAddrs := []*serverconfigs.NetworkAddressConfig{}
|
||||
var restAccessAddrs = []*serverconfigs.NetworkAddressConfig{}
|
||||
if node.RestIsOn {
|
||||
if len(node.RestHTTPJSON) > 0 {
|
||||
httpConfig := &serverconfigs.HTTPProtocolConfig{}
|
||||
var httpConfig = &serverconfigs.HTTPProtocolConfig{}
|
||||
err = json.Unmarshal(node.RestHTTPJSON, httpConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -102,7 +108,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
if len(node.RestHTTPSJSON) > 0 {
|
||||
httpsConfig := &serverconfigs.HTTPSProtocolConfig{}
|
||||
var httpsConfig = &serverconfigs.HTTPSProtocolConfig{}
|
||||
err = json.Unmarshal(node.RestHTTPSJSON, httpsConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -118,6 +124,27 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
// 状态
|
||||
var status = &nodeconfigs.NodeStatus{}
|
||||
var statusIsValid = false
|
||||
this.Data["newVersion"] = ""
|
||||
if len(node.StatusJSON) > 0 {
|
||||
err = json.Unmarshal(node.StatusJSON, &status)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
if status.UpdatedAt >= time.Now().Unix()-300 {
|
||||
statusIsValid = true
|
||||
|
||||
// 是否为新版本
|
||||
if stringutil.VersionCompare(status.BuildVersion, teaconst.APINodeVersion) < 0 {
|
||||
this.Data["newVersion"] = teaconst.APINodeVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.Data["node"] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
@@ -130,6 +157,26 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"hasHTTPS": hasHTTPS,
|
||||
"certs": certs,
|
||||
"isPrimary": node.IsPrimary,
|
||||
"statusIsValid": statusIsValid,
|
||||
"status": maps.Map{
|
||||
"isActive": status.IsActive,
|
||||
"updatedAt": status.UpdatedAt,
|
||||
"hostname": status.Hostname,
|
||||
"cpuUsage": status.CPUUsage,
|
||||
"cpuUsageText": fmt.Sprintf("%.2f%%", status.CPUUsage*100),
|
||||
"memUsage": status.MemoryUsage,
|
||||
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
||||
"connectionCount": status.ConnectionCount,
|
||||
"buildVersion": status.BuildVersion,
|
||||
"cpuPhysicalCount": status.CPUPhysicalCount,
|
||||
"cpuLogicalCount": status.CPULogicalCount,
|
||||
"load1m": numberutils.FormatFloat2(status.Load1m),
|
||||
"load5m": numberutils.FormatFloat2(status.Load5m),
|
||||
"load15m": numberutils.FormatFloat2(status.Load15m),
|
||||
"cacheTotalDiskSize": numberutils.FormatBytes(status.CacheTotalDiskSize),
|
||||
"cacheTotalMemorySize": numberutils.FormatBytes(status.CacheTotalMemorySize),
|
||||
"exePath": status.ExePath,
|
||||
},
|
||||
}
|
||||
|
||||
this.Show()
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
@@ -46,7 +45,7 @@ func (this *InstallAction) RunGet(params struct {
|
||||
"isNotFound": false,
|
||||
}
|
||||
dbConfigFile := Tea.ConfigFile("api_db.yaml")
|
||||
data, err := ioutil.ReadFile(dbConfigFile)
|
||||
data, err := os.ReadFile(dbConfigFile)
|
||||
dbConfigMap["config"] = string(data)
|
||||
if err != nil {
|
||||
dbConfigMap["error"] = err.Error()
|
||||
|
||||
@@ -5,6 +5,9 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"net"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type UpdateAddrPopupAction struct {
|
||||
@@ -27,6 +30,26 @@ func (this *UpdateAddrPopupAction) RunPost(params struct {
|
||||
params.Must.
|
||||
Field("addr", params.Addr).
|
||||
Require("请输入访问地址")
|
||||
|
||||
// 兼容URL
|
||||
if regexp.MustCompile(`^(?i)(http|https)://`).MatchString(params.Addr) {
|
||||
u, err := url.Parse(params.Addr)
|
||||
if err != nil {
|
||||
this.FailField("addr", "错误的访问地址,不需要添加http://或https://")
|
||||
}
|
||||
params.Addr = u.Host
|
||||
}
|
||||
|
||||
// 自动添加端口
|
||||
if !strings.Contains(params.Addr, ":") {
|
||||
switch params.Protocol {
|
||||
case "http":
|
||||
params.Addr += ":80"
|
||||
case "https":
|
||||
params.Addr += ":443"
|
||||
}
|
||||
}
|
||||
|
||||
host, port, err := net.SplitHostPort(params.Addr)
|
||||
if err != nil {
|
||||
this.FailField("addr", "错误的访问地址")
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/dns"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/ssh"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/system"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/thresholds"
|
||||
clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
@@ -56,7 +55,6 @@ func init() {
|
||||
GetPost("/settings/system", new(system.IndexAction)).
|
||||
GetPost("/settings/ssh", new(ssh.IndexAction)).
|
||||
GetPost("/settings/ssh/test", new(ssh.TestAction)).
|
||||
GetPost("/settings/thresholds", new(thresholds.IndexAction)).
|
||||
GetPost("/settings/ddos-protection", new(ddosProtection.IndexAction)).
|
||||
Post("/settings/ddos-protection/status", new(ddosProtection.StatusAction)).
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ func (this *DetailAction) Init() {
|
||||
}
|
||||
|
||||
func (this *DetailAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
NodeId int64
|
||||
ClusterId int64
|
||||
}) {
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
|
||||
@@ -43,13 +44,13 @@ func (this *DetailAction) RunGet(params struct {
|
||||
// 主集群
|
||||
var clusterMap maps.Map = nil
|
||||
if node.NodeCluster != nil {
|
||||
clusterId := node.NodeCluster.Id
|
||||
var clusterId = node.NodeCluster.Id
|
||||
clusterResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeCluster(this.AdminContext(), &pb.FindEnabledNodeClusterRequest{NodeClusterId: clusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
cluster := clusterResp.NodeCluster
|
||||
var cluster = clusterResp.NodeCluster
|
||||
if cluster != nil {
|
||||
clusterMap = maps.Map{
|
||||
"id": cluster.Id,
|
||||
@@ -69,6 +70,14 @@ func (this *DetailAction) RunGet(params struct {
|
||||
})
|
||||
}
|
||||
|
||||
// 当前访问集群的DNS设置
|
||||
clusterDNSInfo, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["dnsIsExcludingLnNode"] = clusterDNSInfo != nil && !clusterDNSInfo.IncludingLnNodes && node.Level > 1
|
||||
|
||||
// IP地址
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
@@ -286,6 +295,11 @@ func (this *DetailAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
var lnAddrs = node.LnAddrs
|
||||
if lnAddrs == nil {
|
||||
lnAddrs = []string{}
|
||||
}
|
||||
|
||||
this.Data["node"] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
@@ -303,6 +317,7 @@ func (this *DetailAction) RunGet(params struct {
|
||||
"routes": routeMaps,
|
||||
"level": node.Level,
|
||||
"levelInfo": nodeconfigs.FindNodeLevel(int(node.Level)),
|
||||
"lnAddrs": lnAddrs,
|
||||
|
||||
"status": maps.Map{
|
||||
"isActive": status.IsActive,
|
||||
@@ -321,6 +336,7 @@ func (this *DetailAction) RunGet(params struct {
|
||||
"load15m": numberutils.FormatFloat2(status.Load15m),
|
||||
"cacheTotalDiskSize": numberutils.FormatBytes(status.CacheTotalDiskSize),
|
||||
"cacheTotalMemorySize": numberutils.FormatBytes(status.CacheTotalMemorySize),
|
||||
"exePath": status.ExePath,
|
||||
},
|
||||
|
||||
"group": groupMap,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package nodeutils
|
||||
|
||||
|
||||
@@ -102,8 +102,12 @@ func (this *IndexAction) RunPost(params struct {
|
||||
this.FailField("tcpMaxConnectionsPerIP", "TCP: 单IP TCP最大连接数不能小于"+types.String(nodeconfigs.DefaultTCPMinConnectionsPerIP))
|
||||
}
|
||||
|
||||
if tcpConfig.NewConnectionsRate > 0 && tcpConfig.NewConnectionsRate < nodeconfigs.DefaultTCPNewConnectionsMinRate {
|
||||
this.FailField("tcpNewConnectionsRate", "TCP: 单IP连接速率不能小于"+types.String(nodeconfigs.DefaultTCPNewConnectionsMinRate))
|
||||
if tcpConfig.NewConnectionsMinutelyRate > 0 && tcpConfig.NewConnectionsMinutelyRate < nodeconfigs.DefaultTCPNewConnectionsMinMinutelyRate {
|
||||
this.FailField("tcpNewConnectionsMinutelyRate", "TCP: 单IP连接速率不能小于"+types.String(nodeconfigs.DefaultTCPNewConnectionsMinMinutelyRate))
|
||||
}
|
||||
|
||||
if tcpConfig.NewConnectionsSecondlyRate > 0 && tcpConfig.NewConnectionsSecondlyRate < nodeconfigs.DefaultTCPNewConnectionsMinSecondlyRate {
|
||||
this.FailField("tcpNewConnectionsSecondlyRate", "TCP: 单IP连接速率不能小于"+types.String(nodeconfigs.DefaultTCPNewConnectionsMinSecondlyRate))
|
||||
}
|
||||
|
||||
// Port
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"net"
|
||||
)
|
||||
|
||||
type UpdateAction struct {
|
||||
@@ -61,7 +62,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
ipAddressMaps := []maps.Map{}
|
||||
var ipAddressMaps = []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
thresholds, err := ipaddressutils.InitNodeIPAddressThresholds(this.Parent(), addr.Id)
|
||||
if err != nil {
|
||||
@@ -109,6 +110,12 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
"level": node.Level,
|
||||
}
|
||||
|
||||
if node.LnAddrs == nil {
|
||||
nodeMap["lnAddrs"] = []string{}
|
||||
} else {
|
||||
nodeMap["lnAddrs"] = node.LnAddrs
|
||||
}
|
||||
|
||||
if node.NodeCluster != nil {
|
||||
nodeMap["primaryCluster"] = maps.Map{
|
||||
"id": node.NodeCluster.Id,
|
||||
@@ -149,6 +156,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
SecondaryClusterIds []byte
|
||||
IsOn bool
|
||||
Level int32
|
||||
LnAddrs []string
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -178,7 +186,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddresses := []maps.Map{}
|
||||
var ipAddresses = []maps.Map{}
|
||||
if len(params.IPAddressesJSON) > 0 {
|
||||
err := json.Unmarshal(params.IPAddressesJSON, &ipAddresses)
|
||||
if err != nil {
|
||||
@@ -195,6 +203,27 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
this.Fail("没有权限修改节点级别:" + types.String(params.Level))
|
||||
}
|
||||
|
||||
// 检查Ln节点地址
|
||||
var lnAddrs = []string{}
|
||||
if params.Level > 1 {
|
||||
for _, lnAddr := range params.LnAddrs {
|
||||
if len(lnAddr) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// 处理 host:port
|
||||
host, _, err := net.SplitHostPort(lnAddr)
|
||||
if err == nil {
|
||||
lnAddr = host
|
||||
}
|
||||
|
||||
if net.ParseIP(lnAddr) == nil {
|
||||
this.Fail("L2级别访问地址 '" + lnAddr + "' 格式错误,请纠正后再提交")
|
||||
}
|
||||
lnAddrs = append(lnAddrs, lnAddr)
|
||||
}
|
||||
}
|
||||
|
||||
_, err := this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{
|
||||
NodeId: params.NodeId,
|
||||
NodeGroupId: params.GroupId,
|
||||
@@ -204,6 +233,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
SecondaryNodeClusterIds: secondaryClusterIds,
|
||||
IsOn: params.IsOn,
|
||||
Level: params.Level,
|
||||
LnAddrs: lnAddrs,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package node
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
this.Data["groups"] = groupMaps
|
||||
|
||||
// 所有区域
|
||||
regionsResp, err := this.RPC().NodeRegionRPC().FindAllEnabledAndOnNodeRegions(this.AdminContext(), &pb.FindAllEnabledAndOnNodeRegionsRequest{})
|
||||
regionsResp, err := this.RPC().NodeRegionRPC().FindAllAvailableNodeRegions(this.AdminContext(), &pb.FindAllAvailableNodeRegionsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -75,8 +75,12 @@ func (this *IndexAction) RunPost(params struct {
|
||||
this.FailField("tcpMaxConnectionsPerIP", "TCP: 单IP TCP最大连接数不能小于"+types.String(nodeconfigs.DefaultTCPMinConnectionsPerIP))
|
||||
}
|
||||
|
||||
if tcpConfig.NewConnectionsRate > 0 && tcpConfig.NewConnectionsRate < nodeconfigs.DefaultTCPNewConnectionsMinRate {
|
||||
this.FailField("tcpNewConnectionsRate", "TCP: 单IP连接速率不能小于"+types.String(nodeconfigs.DefaultTCPNewConnectionsMinRate))
|
||||
if tcpConfig.NewConnectionsMinutelyRate > 0 && tcpConfig.NewConnectionsMinutelyRate < nodeconfigs.DefaultTCPNewConnectionsMinMinutelyRate {
|
||||
this.FailField("tcpNewConnectionsMinutelyRate", "TCP: 单IP连接速率不能小于"+types.String(nodeconfigs.DefaultTCPNewConnectionsMinMinutelyRate))
|
||||
}
|
||||
|
||||
if tcpConfig.NewConnectionsSecondlyRate > 0 && tcpConfig.NewConnectionsSecondlyRate < nodeconfigs.DefaultTCPNewConnectionsMinSecondlyRate {
|
||||
this.FailField("tcpNewConnectionsSecondlyRate", "TCP: 单IP连接速率不能小于"+types.String(nodeconfigs.DefaultTCPNewConnectionsMinSecondlyRate))
|
||||
}
|
||||
|
||||
// Port
|
||||
|
||||
@@ -52,6 +52,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["cnameRecords"] = dnsInfoResp.CnameRecords
|
||||
}
|
||||
this.Data["ttl"] = dnsInfoResp.Ttl
|
||||
this.Data["cnameAsDomain"] = dnsInfoResp.CnameAsDomain
|
||||
this.Data["includingLnNodes"] = dnsInfoResp.IncludingLnNodes
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -59,12 +61,16 @@ func (this *IndexAction) RunGet(params struct {
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
|
||||
DnsDomainId int64
|
||||
DnsName string
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
CnameRecords []string
|
||||
Ttl int32
|
||||
DnsDomainId int64
|
||||
DnsName string
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
CnameRecords []string
|
||||
Ttl int32
|
||||
CnameAsDomain bool
|
||||
IncludingLnNodes bool
|
||||
|
||||
ConfirmResetDomain bool // 是否确认重置域名
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -72,13 +78,15 @@ func (this *IndexAction) RunPost(params struct {
|
||||
// 创建日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改集群 %d DNS设置", params.ClusterId)
|
||||
|
||||
if params.DnsDomainId <= 0 {
|
||||
this.Fail("请选择集群的主域名")
|
||||
}
|
||||
if !params.ConfirmResetDomain {
|
||||
if params.DnsDomainId <= 0 {
|
||||
this.Fail("请选择集群的主域名")
|
||||
}
|
||||
|
||||
params.Must.
|
||||
Field("dnsName", params.DnsName).
|
||||
Require("请输入DNS子域名")
|
||||
params.Must.
|
||||
Field("dnsName", params.DnsName).
|
||||
Require("请输入DNS子域名")
|
||||
}
|
||||
|
||||
// 检查DNS名称
|
||||
if len(params.DnsName) > 0 {
|
||||
@@ -101,13 +109,15 @@ func (this *IndexAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
_, err := this.RPC().NodeClusterRPC().UpdateNodeClusterDNS(this.AdminContext(), &pb.UpdateNodeClusterDNSRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
DnsName: params.DnsName,
|
||||
DnsDomainId: params.DnsDomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
CnameRecords: params.CnameRecords,
|
||||
Ttl: params.Ttl,
|
||||
NodeClusterId: params.ClusterId,
|
||||
DnsName: params.DnsName,
|
||||
DnsDomainId: params.DnsDomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
CnameRecords: params.CnameRecords,
|
||||
Ttl: params.Ttl,
|
||||
CnameAsDomain: params.CnameAsDomain,
|
||||
IncludingLnNodes: params.IncludingLnNodes,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -7,10 +7,8 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/dns"
|
||||
firewallActions "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/firewall-actions"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/health"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/message"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/metrics"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/services"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/thresholds"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/toa"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/waf"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/webp"
|
||||
@@ -42,12 +40,6 @@ func init() {
|
||||
GetPost("", new(dns.IndexAction)).
|
||||
Post("/randomName", new(dns.RandomNameAction)).
|
||||
|
||||
// 消息
|
||||
Prefix("/clusters/cluster/settings/message").
|
||||
GetPost("", new(message.IndexAction)).
|
||||
Get("/selectReceiverPopup", new(message.SelectReceiverPopupAction)).
|
||||
Post("/selectedReceivers", new(message.SelectedReceiversAction)).
|
||||
|
||||
// TOA
|
||||
Prefix("/clusters/cluster/settings/toa").
|
||||
GetPost("", new(toa.IndexAction)).
|
||||
@@ -64,13 +56,6 @@ func init() {
|
||||
GetPost("/updatePopup", new(firewallActions.UpdatePopupAction)).
|
||||
Post("/delete", new(firewallActions.DeleteAction)).
|
||||
|
||||
// 阈值
|
||||
Prefix("/clusters/cluster/settings/thresholds").
|
||||
Get("", new(thresholds.IndexAction)).
|
||||
GetPost("/createPopup", new(thresholds.CreatePopupAction)).
|
||||
GetPost("/updatePopup", new(thresholds.UpdatePopupAction)).
|
||||
Post("/delete", new(thresholds.DeleteAction)).
|
||||
|
||||
// 指标
|
||||
Prefix("/clusters/cluster/settings/metrics").
|
||||
Get("", new(metrics.IndexAction)).
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "setting", "")
|
||||
this.SecondMenu("message")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
ReceiversJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改集群 %d 消息接收人", params.ClusterId)
|
||||
|
||||
receiverMaps := []maps.Map{}
|
||||
if len(params.ReceiversJSON) > 0 {
|
||||
err := json.Unmarshal(params.ReceiversJSON, &receiverMaps)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
pbReceiverOptions := &pb.UpdateMessageReceiversRequest_RecipientOptions{}
|
||||
for _, receiverMap := range receiverMaps {
|
||||
recipientId := int64(0)
|
||||
groupId := int64(0)
|
||||
receiverType := receiverMap.GetString("type")
|
||||
switch receiverType {
|
||||
case "recipient":
|
||||
recipientId = receiverMap.GetInt64("id")
|
||||
case "group":
|
||||
groupId = receiverMap.GetInt64("id")
|
||||
default:
|
||||
continue
|
||||
}
|
||||
pbReceiverOptions.RecipientOptions = append(pbReceiverOptions.RecipientOptions, &pb.UpdateMessageReceiversRequest_RecipientOption{
|
||||
MessageRecipientId: recipientId,
|
||||
MessageRecipientGroupId: groupId,
|
||||
})
|
||||
}
|
||||
|
||||
_, err := this.RPC().MessageReceiverRPC().UpdateMessageReceivers(this.AdminContext(), &pb.UpdateMessageReceiversRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeId: 0,
|
||||
ServerId: 0,
|
||||
ParamsJSON: nil,
|
||||
RecipientOptions: map[string]*pb.UpdateMessageReceiversRequest_RecipientOptions{
|
||||
"*": pbReceiverOptions,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type SelectReceiverPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SelectReceiverPopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *SelectReceiverPopupAction) RunGet(params struct {
|
||||
RecipientIds string
|
||||
GroupIds string
|
||||
}) {
|
||||
recipientIds := utils.SplitNumbers(params.RecipientIds)
|
||||
groupIds := utils.SplitNumbers(params.GroupIds)
|
||||
|
||||
// 所有接收人
|
||||
recipientsResp, err := this.RPC().MessageRecipientRPC().ListEnabledMessageRecipients(this.AdminContext(), &pb.ListEnabledMessageRecipientsRequest{
|
||||
AdminId: 0,
|
||||
MediaType: "",
|
||||
MessageRecipientGroupId: 0,
|
||||
Keyword: "",
|
||||
Offset: 0,
|
||||
Size: 1000, // TODO 支持搜索
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
recipientMaps := []maps.Map{}
|
||||
for _, recipient := range recipientsResp.MessageRecipients {
|
||||
if !recipient.IsOn {
|
||||
continue
|
||||
}
|
||||
if lists.ContainsInt64(recipientIds, recipient.Id) {
|
||||
continue
|
||||
}
|
||||
recipientMaps = append(recipientMaps, maps.Map{
|
||||
"id": recipient.Id,
|
||||
"name": recipient.Admin.Fullname,
|
||||
"instanceName": recipient.MessageMediaInstance.Name,
|
||||
})
|
||||
}
|
||||
this.Data["recipients"] = recipientMaps
|
||||
|
||||
// 所有分组
|
||||
groupsResp, err := this.RPC().MessageRecipientGroupRPC().FindAllEnabledMessageRecipientGroups(this.AdminContext(), &pb.FindAllEnabledMessageRecipientGroupsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
groupMaps := []maps.Map{}
|
||||
for _, group := range groupsResp.MessageRecipientGroups {
|
||||
if !group.IsOn {
|
||||
continue
|
||||
}
|
||||
if lists.ContainsInt64(groupIds, group.Id) {
|
||||
continue
|
||||
}
|
||||
groupMaps = append(groupMaps, maps.Map{
|
||||
"id": group.Id,
|
||||
"name": group.Name,
|
||||
})
|
||||
}
|
||||
this.Data["groups"] = groupMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package message
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type SelectedReceiversAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SelectedReceiversAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *SelectedReceiversAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
ServerId int64
|
||||
}) {
|
||||
receiversResp, err := this.RPC().MessageReceiverRPC().FindAllEnabledMessageReceivers(this.AdminContext(), &pb.FindAllEnabledMessageReceiversRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeId: params.NodeId,
|
||||
ServerId: params.ServerId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
receiverMaps := []maps.Map{}
|
||||
for _, receiver := range receiversResp.MessageReceivers {
|
||||
id := int64(0)
|
||||
name := ""
|
||||
receiverType := ""
|
||||
subName := ""
|
||||
if receiver.MessageRecipient != nil {
|
||||
id = receiver.MessageRecipient.Id
|
||||
name = receiver.MessageRecipient.Admin.Fullname
|
||||
subName = receiver.MessageRecipient.MessageMediaInstance.Name
|
||||
receiverType = "recipient"
|
||||
} else if receiver.MessageRecipientGroup != nil {
|
||||
id = receiver.MessageRecipientGroup.Id
|
||||
name = receiver.MessageRecipientGroup.Name
|
||||
receiverType = "group"
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
receiverMaps = append(receiverMaps, maps.Map{
|
||||
"id": id,
|
||||
"name": name,
|
||||
"subName": subName,
|
||||
"type": receiverType,
|
||||
})
|
||||
}
|
||||
this.Data["receivers"] = receiverMaps
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package thresholds
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
)
|
||||
|
||||
type CreatePopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
}) {
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
this.Data["items"] = nodeconfigs.FindAllNodeValueItemDefinitions()
|
||||
this.Data["operators"] = nodeconfigs.FindAllNodeValueOperatorDefinitions()
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *CreatePopupAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
Item string
|
||||
Param string
|
||||
SumMethod string
|
||||
Operator string
|
||||
Value string
|
||||
Duration int32
|
||||
DurationUnit string
|
||||
Message string
|
||||
NotifyDuration int32
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
if params.ClusterId <= 0 && params.NodeId >= 0 {
|
||||
this.Fail("集群或者节点至少需要填写其中一个参数")
|
||||
}
|
||||
|
||||
valueJSON, err := json.Marshal(params.Value)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
resp, err := this.RPC().NodeThresholdRPC().CreateNodeThreshold(this.AdminContext(), &pb.CreateNodeThresholdRequest{
|
||||
Role: "node",
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeId: params.NodeId,
|
||||
Item: params.Item,
|
||||
Param: params.Param,
|
||||
Operator: params.Operator,
|
||||
ValueJSON: valueJSON,
|
||||
Message: params.Message,
|
||||
Duration: params.Duration,
|
||||
DurationUnit: params.DurationUnit,
|
||||
SumMethod: params.SumMethod,
|
||||
NotifyDuration: params.NotifyDuration,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
defer this.CreateLogInfo("创建节点阈值 %d", resp.NodeThresholdId)
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package thresholds
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// DeleteAction 删除阈值
|
||||
type DeleteAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *DeleteAction) RunPost(params struct {
|
||||
ThresholdId int64
|
||||
}) {
|
||||
defer this.CreateLogInfo("删除阈值 %d", params.ThresholdId)
|
||||
|
||||
_, err := this.RPC().NodeThresholdRPC().DeleteNodeThreshold(this.AdminContext(), &pb.DeleteNodeThresholdRequest{NodeThresholdId: params.ThresholdId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package thresholds
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "setting", "setting")
|
||||
this.SecondMenu("threshold")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
}) {
|
||||
// 列出所有阈值
|
||||
thresholdsResp, err := this.RPC().NodeThresholdRPC().FindAllEnabledNodeThresholds(this.AdminContext(), &pb.FindAllEnabledNodeThresholdsRequest{
|
||||
Role: "node",
|
||||
NodeClusterId: params.ClusterId,
|
||||
NodeId: 0,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
thresholdMaps := []maps.Map{}
|
||||
for _, threshold := range thresholdsResp.NodeThresholds {
|
||||
var nodeMap maps.Map = nil
|
||||
if threshold.Node != nil {
|
||||
nodeMap = maps.Map{
|
||||
"id": threshold.Node.Id,
|
||||
"name": threshold.Node.Name,
|
||||
}
|
||||
}
|
||||
|
||||
thresholdMaps = append(thresholdMaps, maps.Map{
|
||||
"id": threshold.Id,
|
||||
"itemName": nodeconfigs.FindNodeValueItemName(threshold.Item),
|
||||
"paramName": nodeconfigs.FindNodeValueItemParamName(threshold.Item, threshold.Param),
|
||||
"operatorName": nodeconfigs.FindNodeValueOperatorName(threshold.Operator),
|
||||
"value": nodeconfigs.UnmarshalNodeValue(threshold.ValueJSON),
|
||||
"sumMethodName": nodeconfigs.FindNodeValueSumMethodName(threshold.SumMethod),
|
||||
"duration": threshold.Duration,
|
||||
"durationUnitName": nodeconfigs.FindNodeValueDurationUnitName(threshold.DurationUnit),
|
||||
"isOn": threshold.IsOn,
|
||||
"node": nodeMap,
|
||||
})
|
||||
}
|
||||
this.Data["thresholds"] = thresholdMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package thresholds
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type UpdatePopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) RunGet(params struct {
|
||||
ThresholdId int64
|
||||
}) {
|
||||
// 通用参数
|
||||
this.Data["items"] = nodeconfigs.FindAllNodeValueItemDefinitions()
|
||||
this.Data["operators"] = nodeconfigs.FindAllNodeValueOperatorDefinitions()
|
||||
|
||||
// 阈值详情
|
||||
thresholdResp, err := this.RPC().NodeThresholdRPC().FindEnabledNodeThreshold(this.AdminContext(), &pb.FindEnabledNodeThresholdRequest{NodeThresholdId: params.ThresholdId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
threshold := thresholdResp.NodeThreshold
|
||||
if threshold == nil {
|
||||
this.NotFound("nodeThreshold", params.ThresholdId)
|
||||
return
|
||||
}
|
||||
|
||||
valueInterface := new(interface{})
|
||||
err = json.Unmarshal(threshold.ValueJSON, valueInterface)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["threshold"] = maps.Map{
|
||||
"id": threshold.Id,
|
||||
"item": threshold.Item,
|
||||
"param": threshold.Param,
|
||||
"message": threshold.Message,
|
||||
"notifyDuration": threshold.NotifyDuration,
|
||||
"value": nodeconfigs.UnmarshalNodeValue(threshold.ValueJSON),
|
||||
"operator": threshold.Operator,
|
||||
"duration": threshold.Duration,
|
||||
"durationUnit": threshold.DurationUnit,
|
||||
"isOn": threshold.IsOn,
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) RunPost(params struct {
|
||||
ThresholdId int64
|
||||
Item string
|
||||
Param string
|
||||
SumMethod string
|
||||
Operator string
|
||||
Value string
|
||||
Duration int32
|
||||
DurationUnit string
|
||||
Message string
|
||||
NotifyDuration int32
|
||||
IsOn bool
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改节点阈值 %d", params.ThresholdId)
|
||||
|
||||
valueJSON, err := json.Marshal(params.Value)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
_, err = this.RPC().NodeThresholdRPC().UpdateNodeThreshold(this.AdminContext(), &pb.UpdateNodeThresholdRequest{
|
||||
NodeThresholdId: params.ThresholdId,
|
||||
Item: params.Item,
|
||||
Param: params.Param,
|
||||
Operator: params.Operator,
|
||||
ValueJSON: valueJSON,
|
||||
Message: params.Message,
|
||||
NotifyDuration: params.NotifyDuration,
|
||||
Duration: params.Duration,
|
||||
DurationUnit: params.DurationUnit,
|
||||
SumMethod: params.SumMethod,
|
||||
IsOn: params.IsOn,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -22,7 +22,7 @@ func NewClusterHelper() *ClusterHelper {
|
||||
}
|
||||
|
||||
func (this *ClusterHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNext bool) {
|
||||
action := actionPtr.Object()
|
||||
var action = actionPtr.Object()
|
||||
if action.Request.Method != http.MethodGet {
|
||||
return true
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func (this *ClusterHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNext
|
||||
return
|
||||
}
|
||||
|
||||
tabbar := actionutils.NewTabbar()
|
||||
var tabbar = actionutils.NewTabbar()
|
||||
tabbar.Add("集群列表", "", "/clusters", "", false)
|
||||
if teaconst.IsPlus {
|
||||
tabbar.Add("集群看板", "", "/clusters/cluster/boards?clusterId="+clusterIdString, "board", selectedTabbar == "board")
|
||||
@@ -118,10 +118,25 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
||||
})
|
||||
|
||||
items = append(items, maps.Map{
|
||||
"name": "DDoS防护",
|
||||
"url": "/clusters/cluster/settings/ddos-protection?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "ddosProtection",
|
||||
"isOn": info != nil && info.HasDDoSProtection,
|
||||
"name": "WebP",
|
||||
"url": "/clusters/cluster/settings/webp?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "webp",
|
||||
"isOn": info != nil && info.WebpIsOn,
|
||||
})
|
||||
|
||||
items = filterMenuItems1(items, info, clusterId, selectedItem)
|
||||
|
||||
items = append(items, maps.Map{
|
||||
"name": "-",
|
||||
"url": "",
|
||||
"isActive": false,
|
||||
})
|
||||
|
||||
items = append(items, maps.Map{
|
||||
"name": "DNS设置",
|
||||
"url": "/clusters/cluster/settings/dns?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "dns",
|
||||
"isOn": cluster.DnsDomainId > 0 || len(cluster.DnsName) > 0,
|
||||
})
|
||||
|
||||
items = append(items, maps.Map{
|
||||
@@ -132,16 +147,10 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
||||
})
|
||||
|
||||
items = append(items, maps.Map{
|
||||
"name": "DNS设置",
|
||||
"url": "/clusters/cluster/settings/dns?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "dns",
|
||||
"isOn": cluster.DnsDomainId > 0 || len(cluster.DnsName) > 0,
|
||||
})
|
||||
items = append(items, maps.Map{
|
||||
"name": "WebP",
|
||||
"url": "/clusters/cluster/settings/webp?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "webp",
|
||||
"isOn": info != nil && info.WebpIsOn,
|
||||
"name": "DDoS防护",
|
||||
"url": "/clusters/cluster/settings/ddos-protection?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "ddosProtection",
|
||||
"isOn": info != nil && info.HasDDoSProtection,
|
||||
})
|
||||
|
||||
items = append(items, maps.Map{
|
||||
@@ -155,21 +164,7 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
||||
"isOn": info != nil && info.HasMetricItems,
|
||||
})
|
||||
|
||||
if teaconst.IsPlus {
|
||||
items = append(items, maps.Map{
|
||||
"name": "阈值设置",
|
||||
"url": "/clusters/cluster/settings/thresholds?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "threshold",
|
||||
"isOn": info != nil && info.HasThresholds,
|
||||
})
|
||||
|
||||
items = append(items, maps.Map{
|
||||
"name": "消息通知",
|
||||
"url": "/clusters/cluster/settings/message?clusterId=" + clusterId,
|
||||
"isActive": selectedItem == "message",
|
||||
"isOn": info != nil && info.HasMessageReceivers,
|
||||
})
|
||||
}
|
||||
items = filterMenuItems2(items, info, clusterId, selectedItem)
|
||||
|
||||
items = append(items, maps.Map{
|
||||
"name": "-",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package clusterutils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
func filterMenuItems1(items []maps.Map, info *pb.FindEnabledNodeClusterConfigInfoResponse, clusterIdString string, selectedItem string) []maps.Map {
|
||||
return items
|
||||
}
|
||||
|
||||
func filterMenuItems2(items []maps.Map, info *pb.FindEnabledNodeClusterConfigInfoResponse, clusterIdString string, selectedItem string) []maps.Map {
|
||||
return items
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"strings"
|
||||
@@ -29,5 +30,8 @@ func (this *FixAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
// 通知左侧数字Badge更新
|
||||
helpers.NotifyNodeLogsCountChange()
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
@@ -21,5 +22,8 @@ func (this *FixAllAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
// 通知左侧数字Badge更新
|
||||
helpers.NotifyNodeLogsCountChange()
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -120,6 +120,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
var firstUnreadNodeMap maps.Map = nil
|
||||
|
||||
var logs = []maps.Map{}
|
||||
for _, log := range logsResp.NodeLogs {
|
||||
// 节点信息
|
||||
@@ -132,6 +134,13 @@ func (this *IndexAction) RunGet(params struct {
|
||||
continue
|
||||
}
|
||||
|
||||
if params.Type == "unread" && firstUnreadNodeMap == nil {
|
||||
firstUnreadNodeMap = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
}
|
||||
}
|
||||
|
||||
// 服务信息
|
||||
var serverMap = maps.Map{"id": 0}
|
||||
if log.ServerId > 0 {
|
||||
@@ -174,5 +183,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["logs"] = logs
|
||||
|
||||
this.Data["firstUnreadNode"] = firstUnreadNodeMap
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
@@ -20,5 +21,8 @@ func (this *ReadAllLogsAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
// 通知左侧数字Badge更新
|
||||
helpers.NotifyNodeLogsCountChange()
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
@@ -13,14 +15,21 @@ type ReadLogsAction struct {
|
||||
|
||||
func (this *ReadLogsAction) RunPost(params struct {
|
||||
LogIds []int64
|
||||
|
||||
NodeId int64
|
||||
}) {
|
||||
_, err := this.RPC().NodeLogRPC().UpdateNodeLogsRead(this.AdminContext(), &pb.UpdateNodeLogsReadRequest{
|
||||
NodeLogIds: params.LogIds,
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 通知左侧数字Badge更新
|
||||
helpers.NotifyNodeLogsCountChange()
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
this.Data["groups"] = groupMaps
|
||||
|
||||
// 所有区域
|
||||
regionsResp, err := this.RPC().NodeRegionRPC().FindAllEnabledAndOnNodeRegions(this.AdminContext(), &pb.FindAllEnabledAndOnNodeRegionsRequest{})
|
||||
regionsResp, err := this.RPC().NodeRegionRPC().FindAllAvailableNodeRegions(this.AdminContext(), &pb.FindAllAvailableNodeRegionsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -20,7 +20,7 @@ func (this *PricesAction) Init() {
|
||||
|
||||
func (this *PricesAction) RunGet(params struct{}) {
|
||||
// 所有价格项目
|
||||
itemsResp, err := this.RPC().NodePriceItemRPC().FindAllEnabledAndOnNodePriceItems(this.AdminContext(), &pb.FindAllEnabledAndOnNodePriceItemsRequest{Type: regionutils.PriceTypeTraffic})
|
||||
itemsResp, err := this.RPC().NodePriceItemRPC().FindAllAvailableNodePriceItems(this.AdminContext(), &pb.FindAllAvailableNodePriceItemsRequest{Type: regionutils.PriceTypeTraffic})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -16,7 +16,7 @@ func (this *SelectPopupAction) Init() {
|
||||
}
|
||||
|
||||
func (this *SelectPopupAction) RunGet(params struct{}) {
|
||||
regionsResp, err := this.RPC().NodeRegionRPC().FindAllEnabledAndOnNodeRegions(this.AdminContext(), &pb.FindAllEnabledAndOnNodeRegionsRequest{})
|
||||
regionsResp, err := this.RPC().NodeRegionRPC().FindAllAvailableNodeRegions(this.AdminContext(), &pb.FindAllAvailableNodeRegionsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
169
internal/web/actions/default/dashboard/dashboardutils/utils.go
Normal file
169
internal/web/actions/default/dashboard/dashboardutils/utils.go
Normal file
@@ -0,0 +1,169 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package dashboardutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/sizes"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// CheckDiskPartitions 检查服务器磁盘空间
|
||||
func CheckDiskPartitions(thresholdPercent float64) (path string, usage uint64, usagePercent float64, shouldWarning bool) {
|
||||
partitions, err := disk.Partitions(false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !lists.ContainsString([]string{"darwin", "linux", "freebsd"}, runtime.GOOS) {
|
||||
return
|
||||
}
|
||||
|
||||
var rootFS = ""
|
||||
|
||||
for _, p := range partitions {
|
||||
if p.Mountpoint == "/" {
|
||||
rootFS = p.Fstype
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range partitions {
|
||||
if p.Mountpoint == "/boot" {
|
||||
continue
|
||||
}
|
||||
if p.Fstype != rootFS {
|
||||
continue
|
||||
}
|
||||
stat, _ := disk.Usage(p.Mountpoint)
|
||||
if stat != nil {
|
||||
if stat.Used < 2*uint64(sizes.G) {
|
||||
continue
|
||||
}
|
||||
if stat.UsedPercent > thresholdPercent {
|
||||
path = stat.Path
|
||||
usage = stat.Used
|
||||
usagePercent = stat.UsedPercent
|
||||
shouldWarning = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CheckLocalAPINode 检查本地的API节点
|
||||
func CheckLocalAPINode(rpcClient *rpc.RPCClient, ctx context.Context) (exePath string, runtimeVersion string, fileVersion string, ok bool) {
|
||||
resp, err := rpcClient.APINodeRPC().FindCurrentAPINode(ctx, &pb.FindCurrentAPINodeRequest{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if resp.ApiNode == nil {
|
||||
return
|
||||
}
|
||||
var instanceCode = resp.ApiNode.InstanceCode
|
||||
if len(instanceCode) == 0 {
|
||||
return
|
||||
}
|
||||
var statusJSON = resp.ApiNode.StatusJSON
|
||||
if len(statusJSON) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var status = &nodeconfigs.NodeStatus{}
|
||||
err = json.Unmarshal(statusJSON, status)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
runtimeVersion = status.BuildVersion
|
||||
|
||||
if len(runtimeVersion) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if stringutil.VersionCompare(runtimeVersion, teaconst.APINodeVersion) >= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
exePath = status.ExePath
|
||||
if len(exePath) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
stat, err := os.Stat(exePath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if stat.IsDir() {
|
||||
return
|
||||
}
|
||||
|
||||
// 实例信息
|
||||
{
|
||||
var outputBuffer = &bytes.Buffer{}
|
||||
var cmd = exec.Command(exePath, "instance")
|
||||
cmd.Stdout = outputBuffer
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var outputBytes = outputBuffer.Bytes()
|
||||
if len(outputBytes) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var instanceMap = maps.Map{}
|
||||
err = json.Unmarshal(bytes.TrimSpace(outputBytes), &instanceMap)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if instanceMap.GetString("code") != instanceCode {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 文件版本
|
||||
{
|
||||
var outputBuffer = &bytes.Buffer{}
|
||||
var cmd = exec.Command(exePath, "-v")
|
||||
cmd.Stdout = outputBuffer
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var outputString = outputBuffer.String()
|
||||
if len(outputString) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var subMatch = regexp.MustCompile(`\s+v([\d.]+)\s+`).FindStringSubmatch(outputString)
|
||||
if len(subMatch) == 0 {
|
||||
return
|
||||
}
|
||||
fileVersion = subMatch[1]
|
||||
|
||||
// 文件版本是否为最新
|
||||
if fileVersion != teaconst.APINodeVersion {
|
||||
fileVersion = runtimeVersion
|
||||
}
|
||||
}
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
@@ -7,16 +7,14 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/sizes"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dashboard/dashboardutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"regexp"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -28,6 +26,10 @@ func (this *IndexAction) Init() {
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct{}) {
|
||||
// 通知菜单数字Badge更新
|
||||
helpers.NotifyIPItemsCountChanges()
|
||||
helpers.NotifyNodeLogsCountChange()
|
||||
|
||||
if teaconst.IsPlus {
|
||||
this.RedirectURL("/dashboard/boards")
|
||||
return
|
||||
@@ -66,7 +68,7 @@ func (this *IndexAction) RunPost(params struct{}) {
|
||||
|
||||
// 检查当前服务器空间
|
||||
var diskUsageWarning = ""
|
||||
diskPath, diskUsage, diskUsagePercent, shouldWarning := this.checkDiskPartitions(90)
|
||||
diskPath, diskUsage, diskUsagePercent, shouldWarning := dashboardutils.CheckDiskPartitions(90)
|
||||
if shouldWarning {
|
||||
diskUsageWarning = "当前服务器磁盘空间不足,请立即扩充容量,文件路径:" + diskPath + ",已使用:" + types.String(diskUsage/1024/1024/1024) + "G,已使用比例:" + fmt.Sprintf("%.2f%%", diskUsagePercent) + ",仅剩余空间:" + fmt.Sprintf("%.2f%%", 100-diskUsagePercent) + "。"
|
||||
}
|
||||
@@ -263,49 +265,18 @@ func (this *IndexAction) RunPost(params struct{}) {
|
||||
this.Data["metricCharts"] = chartMaps
|
||||
}
|
||||
|
||||
// 当前API节点版本
|
||||
{
|
||||
exePath, runtimeVersion, fileVersion, ok := dashboardutils.CheckLocalAPINode(this.RPC(), this.AdminContext())
|
||||
if ok {
|
||||
this.Data["localLowerVersionAPINode"] = maps.Map{
|
||||
"exePath": exePath,
|
||||
"runtimeVersion": runtimeVersion,
|
||||
"fileVersion": fileVersion,
|
||||
"isRestarting": false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
// 检查服务器磁盘空间
|
||||
func (this *IndexAction) checkDiskPartitions(thresholdPercent float64) (path string, usage uint64, usagePercent float64, shouldWarning bool) {
|
||||
partitions, err := disk.Partitions(false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !lists.ContainsString([]string{"darwin", "linux", "freebsd"}, runtime.GOOS) {
|
||||
return
|
||||
}
|
||||
|
||||
var rootFS = ""
|
||||
|
||||
for _, p := range partitions {
|
||||
if p.Mountpoint == "/" {
|
||||
rootFS = p.Fstype
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range partitions {
|
||||
if p.Mountpoint == "/boot" {
|
||||
continue
|
||||
}
|
||||
if p.Fstype != rootFS {
|
||||
continue
|
||||
}
|
||||
stat, _ := disk.Usage(p.Mountpoint)
|
||||
if stat != nil {
|
||||
if stat.Used < 2*uint64(sizes.G) {
|
||||
continue
|
||||
}
|
||||
if stat.UsedPercent > thresholdPercent {
|
||||
path = stat.Path
|
||||
usage = stat.Used
|
||||
usagePercent = stat.UsedPercent
|
||||
shouldWarning = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ func init() {
|
||||
Data("teaMenu", "dashboard").
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeCommon)).
|
||||
GetPost("", new(IndexAction)).
|
||||
Post("/restartLocalAPINode", new(RestartLocalAPINodeAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RestartLocalAPINodeAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *RestartLocalAPINodeAction) RunPost(params struct {
|
||||
ExePath string
|
||||
}) {
|
||||
// 检查当前用户是超级用户
|
||||
adminResp, err := this.RPC().AdminRPC().FindEnabledAdmin(this.AdminContext(), &pb.FindEnabledAdminRequest{AdminId: this.AdminId()})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if adminResp.Admin == nil || !adminResp.Admin.IsSuper {
|
||||
this.Fail("请切换到超级用户进行此操作")
|
||||
}
|
||||
|
||||
var exePath = params.ExePath
|
||||
if len(exePath) == 0 {
|
||||
this.Fail("找不到要重启的API节点文件")
|
||||
}
|
||||
|
||||
{
|
||||
var stdoutBuffer = &bytes.Buffer{}
|
||||
var cmd = exec.Command(exePath, "restart")
|
||||
cmd.Stdout = stdoutBuffer
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
this.Fail("运行失败:输出:" + stdoutBuffer.String())
|
||||
}
|
||||
}
|
||||
|
||||
// 停止1秒等待命令运行完毕
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// 检查是否已启动
|
||||
var countTries = 120
|
||||
for {
|
||||
countTries--
|
||||
if countTries < 0 {
|
||||
this.Fail("启动超时,请尝试手动启动")
|
||||
break
|
||||
}
|
||||
|
||||
var stdoutBuffer = &bytes.Buffer{}
|
||||
var cmd = exec.Command(exePath, "status")
|
||||
cmd.Stdout = stdoutBuffer
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
time.Sleep(1 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
if regexp.MustCompile(`pid:\s*\d+`).
|
||||
MatchString(stdoutBuffer.String()) {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package providers
|
||||
|
||||
@@ -43,19 +42,7 @@ func (this *CreatePopupAction) RunGet(params struct{}) {
|
||||
this.Data["paramCustomHTTPSecret"] = rands.HexString(32)
|
||||
|
||||
// EdgeDNS集群列表
|
||||
nsClustersResp, err := this.RPC().NSClusterRPC().FindAllEnabledNSClusters(this.AdminContext(), &pb.FindAllEnabledNSClustersRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
nsClusterMaps := []maps.Map{}
|
||||
for _, nsCluster := range nsClustersResp.NsClusters {
|
||||
nsClusterMaps = append(nsClusterMaps, maps.Map{
|
||||
"id": nsCluster.Id,
|
||||
"name": nsCluster.Name,
|
||||
})
|
||||
}
|
||||
this.Data["nsClusters"] = nsClusterMaps
|
||||
this.Data["nsClusters"] = []maps.Map{}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -78,17 +65,10 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
ParamHuaweiAccessKeyId string
|
||||
ParamHuaweiAccessKeySecret string
|
||||
|
||||
// DNS.COM
|
||||
ParamApiKey string
|
||||
ParamApiSecret string
|
||||
|
||||
// CloudFlare
|
||||
ParamCloudFlareAPIKey string
|
||||
ParamCloudFlareEmail string
|
||||
|
||||
// Local EdgeDNS
|
||||
ParamLocalEdgeDNSClusterId int64
|
||||
|
||||
// CustomHTTP
|
||||
ParamCustomHTTPURL string
|
||||
ParamCustomHTTPSecret string
|
||||
@@ -133,15 +113,6 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
|
||||
apiParams["accessKeyId"] = params.ParamHuaweiAccessKeyId
|
||||
apiParams["accessKeySecret"] = params.ParamHuaweiAccessKeySecret
|
||||
case "dnscom":
|
||||
params.Must.
|
||||
Field("paramApiKey", params.ParamApiKey).
|
||||
Require("请输入ApiKey").
|
||||
Field("paramApiSecret", params.ParamApiSecret).
|
||||
Require("请输入ApiSecret")
|
||||
|
||||
apiParams["apiKey"] = params.ParamApiKey
|
||||
apiParams["apiSecret"] = params.ParamApiSecret
|
||||
case "cloudFlare":
|
||||
params.Must.
|
||||
Field("paramCloudFlareAPIKey", params.ParamCloudFlareAPIKey).
|
||||
@@ -150,11 +121,6 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
Email("请输入正确格式的邮箱地址")
|
||||
apiParams["apiKey"] = params.ParamCloudFlareAPIKey
|
||||
apiParams["email"] = params.ParamCloudFlareEmail
|
||||
case "localEdgeDNS":
|
||||
params.Must.
|
||||
Field("ParamLocalEdgeDNSClusterId", params.ParamLocalEdgeDNSClusterId).
|
||||
Gt(0, "请选择域名服务集群")
|
||||
apiParams["clusterId"] = params.ParamLocalEdgeDNSClusterId
|
||||
case "customHTTP":
|
||||
params.Must.
|
||||
Field("paramCustomHTTPURL", params.ParamCustomHTTPURL).
|
||||
|
||||
@@ -40,21 +40,10 @@ func (this *ProviderAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 本地EdgeDNS相关
|
||||
var localEdgeDNSMap = maps.Map{}
|
||||
if provider.Type == "localEdgeDNS" {
|
||||
nsClusterId := apiParams.GetInt64("clusterId")
|
||||
nsClusterResp, err := this.RPC().NSClusterRPC().FindEnabledNSCluster(this.AdminContext(), &pb.FindEnabledNSClusterRequest{NsClusterId: nsClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
nsCluster := nsClusterResp.NsCluster
|
||||
if nsCluster != nil {
|
||||
localEdgeDNSMap = maps.Map{
|
||||
"id": nsCluster.Id,
|
||||
"name": nsCluster.Name,
|
||||
}
|
||||
}
|
||||
localEdgeDNSMap, err := this.readEdgeDNS(provider, apiParams)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["provider"] = maps.Map{
|
||||
|
||||
13
internal/web/actions/default/dns/providers/provider_ext.go
Normal file
13
internal/web/actions/default/dns/providers/provider_ext.go
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package providers
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
func (this *ProviderAction) readEdgeDNS(provider *pb.DNSProvider, apiParams maps.Map) (maps.Map, error) {
|
||||
return maps.Map{}, nil
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package providers
|
||||
|
||||
@@ -68,19 +67,7 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
||||
this.Data["types"] = typeMaps
|
||||
|
||||
// EdgeDNS集群列表
|
||||
nsClustersResp, err := this.RPC().NSClusterRPC().FindAllEnabledNSClusters(this.AdminContext(), &pb.FindAllEnabledNSClustersRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
nsClusterMaps := []maps.Map{}
|
||||
for _, nsCluster := range nsClustersResp.NsClusters {
|
||||
nsClusterMaps = append(nsClusterMaps, maps.Map{
|
||||
"id": nsCluster.Id,
|
||||
"name": nsCluster.Name,
|
||||
})
|
||||
}
|
||||
this.Data["nsClusters"] = nsClusterMaps
|
||||
this.Data["nsClusters"] = []maps.Map{}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -105,17 +92,10 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
ParamHuaweiAccessKeyId string
|
||||
ParamHuaweiAccessKeySecret string
|
||||
|
||||
// DNS.COM
|
||||
ParamApiKey string
|
||||
ParamApiSecret string
|
||||
|
||||
// CloudFlare
|
||||
ParamCloudFlareAPIKey string
|
||||
ParamCloudFlareEmail string
|
||||
|
||||
// Local EdgeDNS
|
||||
ParamLocalEdgeDNSClusterId int64
|
||||
|
||||
// CustomHTTP
|
||||
ParamCustomHTTPURL string
|
||||
ParamCustomHTTPSecret string
|
||||
@@ -162,15 +142,6 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
|
||||
apiParams["accessKeyId"] = params.ParamHuaweiAccessKeyId
|
||||
apiParams["accessKeySecret"] = params.ParamHuaweiAccessKeySecret
|
||||
case "dnscom":
|
||||
params.Must.
|
||||
Field("paramApiKey", params.ParamApiKey).
|
||||
Require("请输入ApiKey").
|
||||
Field("paramApiSecret", params.ParamApiSecret).
|
||||
Require("请输入ApiSecret")
|
||||
|
||||
apiParams["apiKey"] = params.ParamApiKey
|
||||
apiParams["apiSecret"] = params.ParamApiSecret
|
||||
case "cloudFlare":
|
||||
params.Must.
|
||||
Field("paramCloudFlareAPIKey", params.ParamCloudFlareAPIKey).
|
||||
@@ -179,11 +150,6 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Email("请输入正确格式的邮箱地址")
|
||||
apiParams["apiKey"] = params.ParamCloudFlareAPIKey
|
||||
apiParams["email"] = params.ParamCloudFlareEmail
|
||||
case "localEdgeDNS":
|
||||
params.Must.
|
||||
Field("ParamLocalEdgeDNSClusterId", params.ParamLocalEdgeDNSClusterId).
|
||||
Gt(0, "请选择域名服务集群")
|
||||
apiParams["clusterId"] = params.ParamLocalEdgeDNSClusterId
|
||||
case "customHTTP":
|
||||
params.Must.
|
||||
Field("paramCustomHTTPURL", params.ParamCustomHTTPURL).
|
||||
|
||||
@@ -23,36 +23,38 @@ func (this *UpdateClusterPopupAction) RunGet(params struct {
|
||||
}) {
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
|
||||
dnsResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: params.ClusterId})
|
||||
dnsInfoResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["dnsName"] = dnsResp.Name
|
||||
this.Data["nodesAutoSync"] = dnsResp.NodesAutoSync
|
||||
this.Data["serversAutoSync"] = dnsResp.ServersAutoSync
|
||||
if dnsResp.Domain != nil {
|
||||
this.Data["domainId"] = dnsResp.Domain.Id
|
||||
this.Data["domain"] = dnsResp.Domain.Name
|
||||
this.Data["dnsName"] = dnsInfoResp.Name
|
||||
this.Data["nodesAutoSync"] = dnsInfoResp.NodesAutoSync
|
||||
this.Data["serversAutoSync"] = dnsInfoResp.ServersAutoSync
|
||||
if dnsInfoResp.Domain != nil {
|
||||
this.Data["domainId"] = dnsInfoResp.Domain.Id
|
||||
this.Data["domain"] = dnsInfoResp.Domain.Name
|
||||
} else {
|
||||
this.Data["domainId"] = 0
|
||||
this.Data["domain"] = ""
|
||||
}
|
||||
if dnsResp.Provider != nil {
|
||||
this.Data["providerType"] = dnsResp.Provider.Type
|
||||
this.Data["providerId"] = dnsResp.Provider.Id
|
||||
if dnsInfoResp.Provider != nil {
|
||||
this.Data["providerType"] = dnsInfoResp.Provider.Type
|
||||
this.Data["providerId"] = dnsInfoResp.Provider.Id
|
||||
} else {
|
||||
this.Data["providerType"] = ""
|
||||
this.Data["providerId"] = 0
|
||||
}
|
||||
|
||||
if len(dnsResp.CnameRecords) == 0 {
|
||||
if len(dnsInfoResp.CnameRecords) == 0 {
|
||||
this.Data["cnameRecords"] = []string{}
|
||||
} else {
|
||||
this.Data["cnameRecords"] = dnsResp.CnameRecords
|
||||
this.Data["cnameRecords"] = dnsInfoResp.CnameRecords
|
||||
}
|
||||
|
||||
this.Data["ttl"] = dnsResp.Ttl
|
||||
this.Data["ttl"] = dnsInfoResp.Ttl
|
||||
this.Data["cnameAsDomain"] = dnsInfoResp.CnameAsDomain
|
||||
this.Data["includingLnNodes"] = dnsInfoResp.IncludingLnNodes
|
||||
|
||||
// 所有服务商
|
||||
providerTypesResp, err := this.RPC().DNSProviderRPC().FindAllDNSProviderTypes(this.AdminContext(), &pb.FindAllDNSProviderTypesRequest{})
|
||||
@@ -73,13 +75,15 @@ func (this *UpdateClusterPopupAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
func (this *UpdateClusterPopupAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
DnsName string
|
||||
DomainId int64
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
CnameRecords []string
|
||||
Ttl int32
|
||||
ClusterId int64
|
||||
DnsName string
|
||||
DomainId int64
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
CnameRecords []string
|
||||
Ttl int32
|
||||
CnameAsDomain bool
|
||||
IncludingLnNodes bool
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -108,13 +112,15 @@ func (this *UpdateClusterPopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
_, err = this.RPC().NodeClusterRPC().UpdateNodeClusterDNS(this.AdminContext(), &pb.UpdateNodeClusterDNSRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
DnsName: params.DnsName,
|
||||
DnsDomainId: params.DomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
CnameRecords: params.CnameRecords,
|
||||
Ttl: params.Ttl,
|
||||
NodeClusterId: params.ClusterId,
|
||||
DnsName: params.DnsName,
|
||||
DnsDomainId: params.DomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
CnameRecords: params.CnameRecords,
|
||||
Ttl: params.Ttl,
|
||||
CnameAsDomain: params.CnameAsDomain,
|
||||
IncludingLnNodes: params.IncludingLnNodes,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
62
internal/web/actions/default/files/file.go
Normal file
62
internal/web/actions/default/files/file.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package files
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"mime"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type FileAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *FileAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *FileAction) RunGet(params struct {
|
||||
FileId int64
|
||||
}) {
|
||||
fileResp, err := this.RPC().FileRPC().FindEnabledFile(this.AdminContext(), &pb.FindEnabledFileRequest{FileId: params.FileId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
var file = fileResp.File
|
||||
if file == nil {
|
||||
this.NotFound("File", params.FileId)
|
||||
return
|
||||
}
|
||||
|
||||
chunkIdsResp, err := this.RPC().FileChunkRPC().FindAllFileChunkIds(this.AdminContext(), &pb.FindAllFileChunkIdsRequest{FileId: file.Id})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.AddHeader("Content-Length", types.String(file.Size))
|
||||
if len(file.MimeType) > 0 {
|
||||
this.AddHeader("Content-Type", file.MimeType)
|
||||
} else if len(file.Filename) > 0 {
|
||||
var ext = filepath.Ext(file.Filename)
|
||||
var mimeType = mime.TypeByExtension(ext)
|
||||
this.AddHeader("Content-Type", mimeType)
|
||||
}
|
||||
|
||||
for _, chunkId := range chunkIdsResp.FileChunkIds {
|
||||
chunkResp, err := this.RPC().FileChunkRPC().DownloadFileChunk(this.AdminContext(), &pb.DownloadFileChunkRequest{FileChunkId: chunkId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if chunkResp.FileChunk == nil {
|
||||
continue
|
||||
}
|
||||
this.Write(chunkResp.FileChunk.Data)
|
||||
}
|
||||
}
|
||||
14
internal/web/actions/default/files/init.go
Normal file
14
internal/web/actions/default/files/init.go
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package files
|
||||
|
||||
import "github.com/iwind/TeaGo"
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Prefix("/files").
|
||||
Get("/file", new(FileAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["isUser"] = false
|
||||
this.Data["menu"] = "signIn"
|
||||
|
||||
timestamp := fmt.Sprintf("%d", time.Now().Unix())
|
||||
var timestamp = fmt.Sprintf("%d", time.Now().Unix())
|
||||
this.Data["token"] = stringutil.Md5(TokenSalt+timestamp) + timestamp
|
||||
this.Data["from"] = params.From
|
||||
|
||||
@@ -111,11 +111,11 @@ func (this *IndexAction) RunPost(params struct {
|
||||
if len(params.Token) <= 32 {
|
||||
this.Fail("请通过登录页面登录")
|
||||
}
|
||||
timestampString := params.Token[32:]
|
||||
var timestampString = params.Token[32:]
|
||||
if stringutil.Md5(TokenSalt+timestampString) != params.Token[:32] {
|
||||
this.FailField("refresh", "登录页面已过期,请刷新后重试")
|
||||
}
|
||||
timestamp := types.Int64(timestampString)
|
||||
var timestamp = types.Int64(timestampString)
|
||||
if timestamp < time.Now().Unix()-1800 {
|
||||
this.FailField("refresh", "登录页面已过期,请刷新后重试")
|
||||
}
|
||||
@@ -157,7 +157,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
if otpLoginResp.Login != nil && otpLoginResp.Login.IsOn {
|
||||
loginParams := maps.Map{}
|
||||
var loginParams = maps.Map{}
|
||||
err = json.Unmarshal(otpLoginResp.Login.ParamsJSON, &loginParams)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -169,7 +169,7 @@ func (this *IndexAction) RunPost(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
adminId := resp.AdminId
|
||||
var adminId = resp.AdminId
|
||||
params.Auth.StoreAdmin(adminId, params.Remember)
|
||||
|
||||
// 记录日志
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"github.com/tealeg/xlsx/v3"
|
||||
"strconv"
|
||||
@@ -69,17 +68,13 @@ func (this *ExportExcelAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
if regionResp.IpRegion != nil {
|
||||
pieces := []string{}
|
||||
if len(regionResp.IpRegion.Country) > 0 {
|
||||
pieces = append(pieces, regionResp.IpRegion.Country)
|
||||
regionName = regionResp.IpRegion.Summary
|
||||
|
||||
// remove isp from regionName
|
||||
var index = strings.LastIndex(regionName, "|")
|
||||
if index > 0 {
|
||||
regionName = regionName[:index]
|
||||
}
|
||||
if len(regionResp.IpRegion.Province) > 0 && !lists.ContainsString(pieces, regionResp.IpRegion.Province) {
|
||||
pieces = append(pieces, regionResp.IpRegion.Province)
|
||||
}
|
||||
if len(regionResp.IpRegion.City) > 0 && !lists.ContainsString(pieces, regionResp.IpRegion.City) && !lists.ContainsString(pieces, strings.TrimSuffix(regionResp.IpRegion.Province, "市")) {
|
||||
pieces = append(pieces, regionResp.IpRegion.City)
|
||||
}
|
||||
regionName = strings.Join(pieces, " ")
|
||||
|
||||
if len(regionResp.IpRegion.Isp) > 0 {
|
||||
ispName = regionResp.IpRegion.Isp
|
||||
|
||||
@@ -4,10 +4,8 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -72,11 +70,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
if regionResp.IpRegion != nil {
|
||||
pieces := []string{regionResp.IpRegion.Summary}
|
||||
if len(regionResp.IpRegion.Isp) > 0 && !lists.ContainsString(pieces, regionResp.IpRegion.Isp) {
|
||||
pieces = append(pieces, "| "+regionResp.IpRegion.Isp)
|
||||
}
|
||||
regionName = strings.Join(pieces, " ")
|
||||
regionName = regionResp.IpRegion.Summary
|
||||
}
|
||||
|
||||
logMaps = append(logMaps, maps.Map{
|
||||
|
||||
@@ -102,7 +102,8 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
|
||||
|
||||
apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
}{
|
||||
Endpoints: apiNode.AccessAddrs,
|
||||
},
|
||||
@@ -282,7 +283,8 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
|
||||
|
||||
apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
}{
|
||||
Endpoints: apiNode.AccessAddrs,
|
||||
},
|
||||
|
||||
@@ -36,7 +36,8 @@ func (this *UpdateHostsAction) RunPost(params struct {
|
||||
|
||||
client, err := rpc.NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
}{
|
||||
Endpoints: []string{params.Protocol + "://" + configutils.QuoteIP(params.Host) + ":" + params.Port},
|
||||
},
|
||||
@@ -167,7 +168,8 @@ func (this *UpdateHostsAction) RunPost(params struct {
|
||||
// 修改api.yaml
|
||||
var apiConfig = &configs.APIConfig{
|
||||
RPC: struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
}{
|
||||
Endpoints: endpoints,
|
||||
},
|
||||
|
||||
@@ -43,7 +43,8 @@ func (this *ValidateApiAction) RunPost(params struct {
|
||||
Require("请输入节点secret")
|
||||
client, err := rpc.NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
Endpoints []string `yaml:"endpoints"`
|
||||
DisableUpdate bool `yaml:"disableUpdate"`
|
||||
}{
|
||||
Endpoints: []string{params.Protocol + "://" + configutils.QuoteIP(params.Host) + ":" + params.Port},
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
@@ -33,6 +34,10 @@ func (this *AddOriginPopupAction) RunPost(params struct {
|
||||
Protocol string
|
||||
Addr string
|
||||
|
||||
DomainsJSON []byte
|
||||
Host string
|
||||
FollowPort bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
params.Must.
|
||||
@@ -50,7 +55,7 @@ func (this *AddOriginPopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
addr = regexp.MustCompile(`\s+`).ReplaceAllString(addr, "")
|
||||
portIndex := strings.LastIndex(addr, ":")
|
||||
var portIndex = strings.LastIndex(addr, ":")
|
||||
if portIndex < 0 {
|
||||
if params.Protocol == "http" {
|
||||
addr += ":80"
|
||||
@@ -82,6 +87,21 @@ func (this *AddOriginPopupAction) RunPost(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
// 专属域名
|
||||
var domains = []string{}
|
||||
if len(params.DomainsJSON) > 0 {
|
||||
err := json.Unmarshal(params.DomainsJSON, &domains)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 去除可能误加的斜杠
|
||||
for index, domain := range domains {
|
||||
domains[index] = strings.TrimSuffix(domain, "/")
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := this.RPC().OriginRPC().CreateOrigin(this.AdminContext(), &pb.CreateOriginRequest{
|
||||
Name: "",
|
||||
Addr: &pb.NetworkAddress{
|
||||
@@ -92,6 +112,9 @@ func (this *AddOriginPopupAction) RunPost(params struct {
|
||||
Description: "",
|
||||
Weight: 10,
|
||||
IsOn: true,
|
||||
Domains: domains,
|
||||
Host: params.Host,
|
||||
FollowPort: params.FollowPort,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -26,7 +26,7 @@ func (this *AddPortPopupAction) RunGet(params struct {
|
||||
}) {
|
||||
this.Data["from"] = params.From
|
||||
|
||||
protocols := serverconfigs.AllServerProtocolsForType(params.ServerType)
|
||||
protocols := serverconfigs.FindAllServerProtocolsForType(params.ServerType)
|
||||
if len(params.Protocol) > 0 {
|
||||
result := []maps.Map{}
|
||||
for _, p := range protocols {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
@@ -29,11 +30,25 @@ func (this *AddServerNamePopupAction) RunPost(params struct {
|
||||
Must *actions.Must
|
||||
}) {
|
||||
if params.Mode == "single" {
|
||||
var serverName = strings.ToLower(params.ServerName)
|
||||
|
||||
// 去除空格
|
||||
serverName = regexp.MustCompile(`\s+`).ReplaceAllString(serverName, "")
|
||||
|
||||
// 处理URL
|
||||
if regexp.MustCompile(`^(?i)(http|https|ftp)://`).MatchString(serverName) {
|
||||
u, err := url.Parse(serverName)
|
||||
if err == nil && len(u.Host) > 0 {
|
||||
serverName = u.Host
|
||||
}
|
||||
}
|
||||
|
||||
params.Must.
|
||||
Field("serverName", params.ServerName).
|
||||
Field("serverName", serverName).
|
||||
Require("请输入域名")
|
||||
|
||||
this.Data["serverName"] = maps.Map{
|
||||
"name": params.ServerName,
|
||||
"name": serverName,
|
||||
"type": "full",
|
||||
}
|
||||
} else if params.Mode == "multiple" {
|
||||
@@ -41,14 +56,26 @@ func (this *AddServerNamePopupAction) RunPost(params struct {
|
||||
this.FailField("serverNames", "请输入至少域名")
|
||||
}
|
||||
|
||||
serverNames := []string{}
|
||||
var serverNames = []string{}
|
||||
for _, line := range strings.Split(params.ServerNames, "\n") {
|
||||
line := strings.TrimSpace(line)
|
||||
line = regexp.MustCompile(`\s+`).ReplaceAllString(line, "")
|
||||
if len(line) == 0 {
|
||||
var serverName = strings.TrimSpace(line)
|
||||
serverName = regexp.MustCompile(`\s+`).ReplaceAllString(serverName, "")
|
||||
if len(serverName) == 0 {
|
||||
continue
|
||||
}
|
||||
serverNames = append(serverNames, line)
|
||||
|
||||
// 处理URL
|
||||
if regexp.MustCompile(`^(?i)(http|https|ftp)://`).MatchString(serverName) {
|
||||
u, err := url.Parse(serverName)
|
||||
if err == nil && len(u.Host) > 0 {
|
||||
serverName = u.Host
|
||||
}
|
||||
}
|
||||
|
||||
// 转成小写
|
||||
serverName = strings.ToLower(serverName)
|
||||
|
||||
serverNames = append(serverNames, serverName)
|
||||
}
|
||||
this.Data["serverName"] = maps.Map{
|
||||
"name": "",
|
||||
|
||||
@@ -36,15 +36,11 @@ func (this *DeleteAction) RunPost(params struct {
|
||||
this.Fail("此证书正在被某些API节点引用,请先修改API节点后再删除")
|
||||
}
|
||||
|
||||
// 是否正在被用户节点使用
|
||||
countResp, err = this.RPC().UserNodeRPC().CountAllEnabledUserNodesWithSSLCertId(this.AdminContext(), &pb.CountAllEnabledUserNodesWithSSLCertIdRequest{SslCertId: params.CertId})
|
||||
err = this.filterDelete(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 {
|
||||
|
||||
8
internal/web/actions/default/servers/certs/delete_ext.go
Normal file
8
internal/web/actions/default/servers/certs/delete_ext.go
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
//go:build !plus
|
||||
|
||||
package certs
|
||||
|
||||
func (this *DeleteAction) filterDelete(certId int64) error {
|
||||
return nil
|
||||
}
|
||||
@@ -15,6 +15,7 @@ func init() {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Helper(NewHelper()).
|
||||
Data("teaMenu", "servers").
|
||||
Data("teaSubMenu", "cert").
|
||||
Prefix("/servers/certs").
|
||||
Data("leftMenuItem", "cert").
|
||||
|
||||
@@ -21,7 +21,9 @@ func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "purge")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct{}) {
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
KeyType string
|
||||
}) {
|
||||
// 初始化菜单数据
|
||||
err := InitMenu(this.Parent())
|
||||
if err != nil {
|
||||
@@ -29,6 +31,8 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["keyType"] = params.KeyType
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Data("teaMenu", "servers").
|
||||
Data("teaSubMenu", "global").
|
||||
Helper(NewHelper()).
|
||||
Prefix("/servers/components").
|
||||
|
||||
@@ -36,21 +36,21 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.NotFound("firewallPolicy", params.FirewallPolicyId)
|
||||
return
|
||||
}
|
||||
selectedCountryIds := []int64{}
|
||||
var selectedCountryIds = []int64{}
|
||||
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
||||
selectedCountryIds = policyConfig.Inbound.Region.DenyCountryIds
|
||||
}
|
||||
|
||||
countriesResp, err := this.RPC().RegionCountryRPC().FindAllEnabledRegionCountries(this.AdminContext(), &pb.FindAllEnabledRegionCountriesRequest{})
|
||||
countriesResp, err := this.RPC().RegionCountryRPC().FindAllRegionCountries(this.AdminContext(), &pb.FindAllRegionCountriesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
countryMaps := []maps.Map{}
|
||||
var countryMaps = []maps.Map{}
|
||||
for _, country := range countriesResp.RegionCountries {
|
||||
countryMaps = append(countryMaps, maps.Map{
|
||||
"id": country.Id,
|
||||
"name": country.Name,
|
||||
"name": country.DisplayName,
|
||||
"letter": strings.ToUpper(string(country.Pinyin[0][0])),
|
||||
"isChecked": lists.ContainsInt64(selectedCountryIds, country.Id),
|
||||
})
|
||||
|
||||
@@ -37,23 +37,23 @@ func (this *ProvincesAction) RunGet(params struct {
|
||||
this.NotFound("firewallPolicy", params.FirewallPolicyId)
|
||||
return
|
||||
}
|
||||
selectedProvinceIds := []int64{}
|
||||
var selectedProvinceIds = []int64{}
|
||||
if policyConfig.Inbound != nil && policyConfig.Inbound.Region != nil {
|
||||
selectedProvinceIds = policyConfig.Inbound.Region.DenyProvinceIds
|
||||
}
|
||||
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllEnabledRegionProvincesWithCountryId(this.AdminContext(), &pb.FindAllEnabledRegionProvincesWithCountryIdRequest{
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{
|
||||
RegionCountryId: int64(ChinaCountryId),
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
provinceMaps := []maps.Map{}
|
||||
var provinceMaps = []maps.Map{}
|
||||
for _, province := range provincesResp.RegionProvinces {
|
||||
provinceMaps = append(provinceMaps, maps.Map{
|
||||
"id": province.Id,
|
||||
"name": province.Name,
|
||||
"name": province.DisplayName,
|
||||
"isChecked": lists.ContainsInt64(selectedProvinceIds, province.Id),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ func (this *CreateAction) RunPost(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{
|
||||
var reverseProxyRef = &serverconfigs.ReverseProxyRef{
|
||||
IsOn: true,
|
||||
ReverseProxyId: resp.ReverseProxyId,
|
||||
}
|
||||
@@ -355,7 +355,7 @@ func (this *CreateAction) RunPost(params struct {
|
||||
var rootJSON []byte
|
||||
var err error
|
||||
if len(params.WebRoot) > 0 {
|
||||
rootConfig := &serverconfigs.HTTPRootConfig{}
|
||||
var rootConfig = &serverconfigs.HTTPRootConfig{}
|
||||
rootConfig.IsOn = true
|
||||
rootConfig.Dir = params.WebRoot
|
||||
rootConfig.Indexes = []string{"index.html", "index.htm"}
|
||||
@@ -375,7 +375,7 @@ func (this *CreateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 包含条件
|
||||
includeNodes := []maps.Map{}
|
||||
var includeNodes = []maps.Map{}
|
||||
includeNodesJSON, err := json.Marshal(includeNodes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -383,7 +383,7 @@ func (this *CreateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 排除条件
|
||||
excludeNodes := []maps.Map{}
|
||||
var excludeNodes = []maps.Map{}
|
||||
excludeNodesJSON, err := json.Marshal(excludeNodes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -396,7 +396,7 @@ func (this *CreateAction) RunPost(params struct {
|
||||
AdminId: this.AdminId(),
|
||||
Type: params.ServerType,
|
||||
Name: params.Name,
|
||||
ServerNamesJON: []byte(params.ServerNames),
|
||||
ServerNamesJON: params.ServerNames,
|
||||
Description: params.Description,
|
||||
NodeClusterId: clusterId,
|
||||
IncludeNodesJSON: includeNodesJSON,
|
||||
|
||||
@@ -49,8 +49,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
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()
|
||||
|
||||
// 服务列表
|
||||
@@ -64,7 +64,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
serverMaps := []maps.Map{}
|
||||
var serverMaps = []maps.Map{}
|
||||
for _, server := range serversResp.Servers {
|
||||
config := &serverconfigs.ServerConfig{}
|
||||
err = json.Unmarshal(server.Config, config)
|
||||
@@ -74,8 +74,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 端口列表
|
||||
portMaps := []maps.Map{}
|
||||
if len(server.HttpJSON) > 0 && config.HTTP.IsOn {
|
||||
var portMaps = []maps.Map{}
|
||||
if config.HTTP != nil && config.HTTP.IsOn {
|
||||
for _, listen := range config.HTTP.Listen {
|
||||
portMaps = append(portMaps, maps.Map{
|
||||
"protocol": listen.Protocol,
|
||||
@@ -125,7 +125,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 分组
|
||||
groupMaps := []maps.Map{}
|
||||
var groupMaps = []maps.Map{}
|
||||
if len(server.ServerGroups) > 0 {
|
||||
for _, group := range server.ServerGroups {
|
||||
groupMaps = append(groupMaps, maps.Map{
|
||||
@@ -136,11 +136,11 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 域名列表
|
||||
serverNames := []*serverconfigs.ServerNameConfig{}
|
||||
var serverNames = []*serverconfigs.ServerNameConfig{}
|
||||
if server.IsAuditing || (server.AuditingResult != nil && !server.AuditingResult.IsOk) {
|
||||
server.ServerNamesJSON = server.AuditingServerNamesJSON
|
||||
}
|
||||
auditingIsOk := true
|
||||
var auditingIsOk = true
|
||||
if !server.IsAuditing && server.AuditingResult != nil && !server.AuditingResult.IsOk {
|
||||
auditingIsOk = false
|
||||
}
|
||||
@@ -151,7 +151,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
}
|
||||
countServerNames := 0
|
||||
var countServerNames = 0
|
||||
for _, serverName := range serverNames {
|
||||
if len(serverName.SubNames) == 0 {
|
||||
countServerNames++
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
//go:build !plus
|
||||
// +build !plus
|
||||
|
||||
package servergrouputils
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
var reverseProxyRef = &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -42,7 +42,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
var reverseProxy = &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -50,21 +50,22 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
primaryOriginMaps := []maps.Map{}
|
||||
backupOriginMaps := []maps.Map{}
|
||||
var primaryOriginMaps = []maps.Map{}
|
||||
var backupOriginMaps = []maps.Map{}
|
||||
for _, originConfig := range reverseProxy.PrimaryOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
var m = maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
"followPort": originConfig.FollowPort,
|
||||
}
|
||||
primaryOriginMaps = append(primaryOriginMaps, m)
|
||||
}
|
||||
@@ -72,15 +73,16 @@ func (this *IndexAction) RunGet(params struct {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
var m = maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
"followPort": originConfig.FollowPort,
|
||||
}
|
||||
backupOriginMaps = append(backupOriginMaps, m)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
var reverseProxyRef = &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -42,7 +42,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
var reverseProxy = &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -50,21 +50,22 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
primaryOriginMaps := []maps.Map{}
|
||||
backupOriginMaps := []maps.Map{}
|
||||
var primaryOriginMaps = []maps.Map{}
|
||||
var backupOriginMaps = []maps.Map{}
|
||||
for _, originConfig := range reverseProxy.PrimaryOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
"followPort": originConfig.FollowPort,
|
||||
}
|
||||
primaryOriginMaps = append(primaryOriginMaps, m)
|
||||
}
|
||||
@@ -73,14 +74,15 @@ func (this *IndexAction) RunGet(params struct {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
"followPort": originConfig.FollowPort,
|
||||
}
|
||||
backupOriginMaps = append(backupOriginMaps, m)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
var reverseProxyRef = &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -42,7 +42,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
var reverseProxy = &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -50,21 +50,22 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
primaryOriginMaps := []maps.Map{}
|
||||
backupOriginMaps := []maps.Map{}
|
||||
var primaryOriginMaps = []maps.Map{}
|
||||
var backupOriginMaps = []maps.Map{}
|
||||
for _, originConfig := range reverseProxy.PrimaryOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
var m = maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
"followPort": originConfig.FollowPort,
|
||||
}
|
||||
primaryOriginMaps = append(primaryOriginMaps, m)
|
||||
}
|
||||
@@ -72,15 +73,16 @@ func (this *IndexAction) RunGet(params struct {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
var m = maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
"hasCert": originConfig.Cert != nil,
|
||||
"host": originConfig.RequestHost,
|
||||
"followPort": originConfig.FollowPort,
|
||||
}
|
||||
backupOriginMaps = append(backupOriginMaps, m)
|
||||
}
|
||||
|
||||
@@ -46,16 +46,16 @@ func (this *CountriesAction) RunGet(params struct {
|
||||
selectedCountryIds = policyConfig.Inbound.Region.DenyCountryIds
|
||||
}
|
||||
|
||||
countriesResp, err := this.RPC().RegionCountryRPC().FindAllEnabledRegionCountries(this.AdminContext(), &pb.FindAllEnabledRegionCountriesRequest{})
|
||||
countriesResp, err := this.RPC().RegionCountryRPC().FindAllRegionCountries(this.AdminContext(), &pb.FindAllRegionCountriesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
countryMaps := []maps.Map{}
|
||||
for _, country := range countriesResp.Countries {
|
||||
for _, country := range countriesResp.RegionCountries {
|
||||
countryMaps = append(countryMaps, maps.Map{
|
||||
"id": country.Id,
|
||||
"name": country.Name,
|
||||
"name": country.DisplayName,
|
||||
"letter": strings.ToUpper(string(country.Pinyin[0][0])),
|
||||
"isChecked": lists.ContainsInt64(selectedCountryIds, country.Id),
|
||||
})
|
||||
|
||||
@@ -46,18 +46,18 @@ func (this *ProvincesAction) RunGet(params struct {
|
||||
selectedProvinceIds = policyConfig.Inbound.Region.DenyProvinceIds
|
||||
}
|
||||
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllEnabledRegionProvincesWithCountryId(this.AdminContext(), &pb.FindAllEnabledRegionProvincesWithCountryIdRequest{
|
||||
CountryId: int64(ChinaCountryId),
|
||||
provincesResp, err := this.RPC().RegionProvinceRPC().FindAllRegionProvincesWithRegionCountryId(this.AdminContext(), &pb.FindAllRegionProvincesWithRegionCountryIdRequest{
|
||||
RegionCountryId: int64(ChinaCountryId),
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
provinceMaps := []maps.Map{}
|
||||
for _, province := range provincesResp.Provinces {
|
||||
for _, province := range provincesResp.RegionProvinces {
|
||||
provinceMaps = append(provinceMaps, maps.Map{
|
||||
"id": province.Id,
|
||||
"name": province.Name,
|
||||
"name": province.DisplayName,
|
||||
"isChecked": lists.ContainsInt64(selectedProvinceIds, province.Id),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ func init() {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Helper(NewHelper()).
|
||||
Data("teaMenu", "servers").
|
||||
Data("teaSubMenu", "group").
|
||||
Prefix("/servers/groups").
|
||||
Get("", new(IndexAction)).
|
||||
|
||||
@@ -27,6 +27,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
Keyword string
|
||||
AuditingFlag int32
|
||||
CheckDNS bool
|
||||
UserId int64
|
||||
|
||||
TrafficOutOrder string
|
||||
}) {
|
||||
@@ -36,6 +37,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["auditingFlag"] = params.AuditingFlag
|
||||
this.Data["checkDNS"] = params.CheckDNS
|
||||
this.Data["hasOrder"] = len(params.TrafficOutOrder) > 0
|
||||
this.Data["userId"] = params.UserId
|
||||
|
||||
isSearching := params.AuditingFlag == 1 || params.ClusterId > 0 || params.GroupId > 0 || len(params.Keyword) > 0
|
||||
|
||||
@@ -44,7 +46,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 常用的服务
|
||||
latestServerMaps := []maps.Map{}
|
||||
var latestServerMaps = []maps.Map{}
|
||||
if !isSearching {
|
||||
serversResp, err := this.RPC().ServerRPC().FindLatestServers(this.AdminContext(), &pb.FindLatestServersRequest{Size: 6})
|
||||
if err != nil {
|
||||
@@ -76,13 +78,14 @@ func (this *IndexAction) RunGet(params struct {
|
||||
ServerGroupId: params.GroupId,
|
||||
Keyword: params.Keyword,
|
||||
AuditingFlag: params.AuditingFlag,
|
||||
UserId: params.UserId,
|
||||
})
|
||||
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()
|
||||
|
||||
// 服务列表
|
||||
@@ -95,14 +98,15 @@ func (this *IndexAction) RunGet(params struct {
|
||||
AuditingFlag: params.AuditingFlag,
|
||||
TrafficOutDesc: params.TrafficOutOrder == "desc",
|
||||
TrafficOutAsc: params.TrafficOutOrder == "asc",
|
||||
UserId: params.UserId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
serverMaps := []maps.Map{}
|
||||
var serverMaps = []maps.Map{}
|
||||
for _, server := range serversResp.Servers {
|
||||
config := &serverconfigs.ServerConfig{}
|
||||
var config = &serverconfigs.ServerConfig{}
|
||||
err = json.Unmarshal(server.Config, config)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -110,8 +114,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 端口列表
|
||||
portMaps := []maps.Map{}
|
||||
if len(server.HttpJSON) > 0 && config.HTTP.IsOn {
|
||||
var portMaps = []maps.Map{}
|
||||
if config.HTTP != nil && config.HTTP.IsOn {
|
||||
for _, listen := range config.HTTP.Listen {
|
||||
portMaps = append(portMaps, maps.Map{
|
||||
"protocol": listen.Protocol,
|
||||
@@ -161,7 +165,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 分组
|
||||
groupMaps := []maps.Map{}
|
||||
var groupMaps = []maps.Map{}
|
||||
if len(server.ServerGroups) > 0 {
|
||||
for _, group := range server.ServerGroups {
|
||||
groupMaps = append(groupMaps, maps.Map{
|
||||
@@ -172,11 +176,11 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// 域名列表
|
||||
serverNames := []*serverconfigs.ServerNameConfig{}
|
||||
var serverNames = []*serverconfigs.ServerNameConfig{}
|
||||
if server.IsAuditing || (server.AuditingResult != nil && !server.AuditingResult.IsOk) {
|
||||
server.ServerNamesJSON = server.AuditingServerNamesJSON
|
||||
}
|
||||
auditingIsOk := true
|
||||
var auditingIsOk = true
|
||||
if !server.IsAuditing && server.AuditingResult != nil && !server.AuditingResult.IsOk {
|
||||
auditingIsOk = false
|
||||
}
|
||||
@@ -187,7 +191,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
}
|
||||
countServerNames := 0
|
||||
var countServerNames = 0
|
||||
for _, serverName := range serverNames {
|
||||
if len(serverName.SubNames) == 0 {
|
||||
countServerNames++
|
||||
@@ -213,11 +217,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
|
||||
// 统计数据
|
||||
var bandwidth = ""
|
||||
if server.LatestServerDailyStat != nil {
|
||||
var bytesPerSecond = server.LatestServerDailyStat.Bytes / 300
|
||||
if bytesPerSecond > 0 {
|
||||
bandwidth = numberutils.FormatBytes(bytesPerSecond)
|
||||
}
|
||||
if server.BandwidthBytes > 0 {
|
||||
bandwidth = numberutils.FormatBytes(server.BandwidthBytes)
|
||||
}
|
||||
|
||||
serverMaps = append(serverMaps, maps.Map{
|
||||
@@ -248,7 +249,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
clusterMaps := []maps.Map{}
|
||||
var clusterMaps = []maps.Map{}
|
||||
for _, cluster := range clustersResp.NodeClusters {
|
||||
clusterMaps = append(clusterMaps, maps.Map{
|
||||
"id": cluster.Id,
|
||||
@@ -263,9 +264,9 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
groupMaps := []maps.Map{}
|
||||
var groupMaps = []maps.Map{}
|
||||
for _, group := range groupsResp.ServerGroups {
|
||||
groupName := group.Name
|
||||
var groupName = group.Name
|
||||
groupMaps = append(groupMaps, maps.Map{
|
||||
"id": group.Id,
|
||||
"name": groupName,
|
||||
@@ -288,5 +289,13 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["countNeedFixLogs"] = countNeedFixLogsResp.Count
|
||||
|
||||
// 是否有用户
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -30,7 +31,14 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
if regionResp.IpRegion != nil {
|
||||
this.Data["regions"] = regionResp.IpRegion.Summary
|
||||
var regionName = regionResp.IpRegion.Summary
|
||||
|
||||
// remove isp from regionName
|
||||
var index = strings.LastIndex(regionName, "|")
|
||||
if index > 0 {
|
||||
regionName = regionName[:index]
|
||||
}
|
||||
this.Data["regions"] = regionName
|
||||
} else {
|
||||
this.Data["regions"] = ""
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
@@ -63,13 +64,15 @@ func (this *CreateIPPopupAction) RunPost(params struct {
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
// 校验IPList
|
||||
existsResp, err := this.RPC().IPListRPC().ExistsEnabledIPList(this.AdminContext(), &pb.ExistsEnabledIPListRequest{IpListId: params.ListId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if !existsResp.Exists {
|
||||
this.Fail("IP名单不存在")
|
||||
if params.ListId != firewallconfigs.GlobalListId {
|
||||
existsResp, err := this.RPC().IPListRPC().ExistsEnabledIPList(this.AdminContext(), &pb.ExistsEnabledIPListRequest{IpListId: params.ListId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if !existsResp.Exists {
|
||||
this.Fail("IP名单不存在")
|
||||
}
|
||||
}
|
||||
|
||||
type ipData struct {
|
||||
|
||||
@@ -4,6 +4,7 @@ package iplists
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
@@ -23,5 +24,8 @@ func (this *DeleteAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
// 通知左侧菜单Badge更新
|
||||
helpers.NotifyIPItemsCountChanges()
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package iplists
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
@@ -22,5 +23,8 @@ func (this *DeleteIPAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
// 通知左侧菜单Badge更新
|
||||
helpers.NotifyIPItemsCountChanges()
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user