Compare commits
233 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37933d814c | ||
|
|
5b26287264 | ||
|
|
bac20b1d1f | ||
|
|
904c641992 | ||
|
|
36004bfd94 | ||
|
|
0fcba7e90c | ||
|
|
2e9182933e | ||
|
|
e3674fa2c1 | ||
|
|
a14cbe1319 | ||
|
|
c03c35de88 | ||
|
|
dc6c649af8 | ||
|
|
b0d2bdb0ba | ||
|
|
9239dd9a8b | ||
|
|
07a368a0bd | ||
|
|
b8d6d1c249 | ||
|
|
0f1d6a1ad2 | ||
|
|
37c6928ffc | ||
|
|
7478b6dbe0 | ||
|
|
e3cd6e1441 | ||
|
|
8081d968b6 | ||
|
|
a226eee6ef | ||
|
|
8b5a21e593 | ||
|
|
2c71f6c6be | ||
|
|
1a50b01edf | ||
|
|
05f08eeb4c | ||
|
|
fdc3ebb5c5 | ||
|
|
8f06bccd48 | ||
|
|
16b4eb67d4 | ||
|
|
ffa545cb41 | ||
|
|
f67454d51c | ||
|
|
8ae54c56db | ||
|
|
9a17adcc6f | ||
|
|
4dd6903025 | ||
|
|
085770d0ad | ||
|
|
fbaba7c37d | ||
|
|
d5cea208d2 | ||
|
|
36397adca4 | ||
|
|
4971e25d44 | ||
|
|
150357441d | ||
|
|
c4ee663285 | ||
|
|
8c95b4a9b9 | ||
|
|
32ba919851 | ||
|
|
eb37345e85 | ||
|
|
681e454917 | ||
|
|
7c7b82dee4 | ||
|
|
2ae47af8f0 | ||
|
|
b72d91d0d4 | ||
|
|
56010e7203 | ||
|
|
f658698f7b | ||
|
|
b708b9c6df | ||
|
|
c2908e17fa | ||
|
|
302daab824 | ||
|
|
ec49f238d6 | ||
|
|
3e43a5d866 | ||
|
|
a99d5e68e9 | ||
|
|
28514276ec | ||
|
|
b611427c17 | ||
|
|
ce7a4ead04 | ||
|
|
5fe15a85fd | ||
|
|
ae412909f6 | ||
|
|
c6ed579797 | ||
|
|
b2a525268e | ||
|
|
eb78b4881c | ||
|
|
4ce6e5a9f6 | ||
|
|
15d7e75555 | ||
|
|
6453cc6ccc | ||
|
|
d882a2eb63 | ||
|
|
065ac4aa25 | ||
|
|
dea54fc55e | ||
|
|
8f425bd9c7 | ||
|
|
9d909d73b8 | ||
|
|
b417d50a28 | ||
|
|
aa93a2f702 | ||
|
|
ba7125e773 | ||
|
|
46a7eaa4bb | ||
|
|
887439a6fe | ||
|
|
0e2b07d06d | ||
|
|
b7d4bde11b | ||
|
|
9707360948 | ||
|
|
103a8eb092 | ||
|
|
dcba4f9376 | ||
|
|
12aaa6fcb1 | ||
|
|
d8393481a4 | ||
|
|
70d3202a2c | ||
|
|
c7f1bbc03d | ||
|
|
61a55cb3f4 | ||
|
|
6a484af775 | ||
|
|
3074d41cf2 | ||
|
|
54199058e3 | ||
|
|
87a533791b | ||
|
|
c3109bb2c6 | ||
|
|
031cb836d2 | ||
|
|
aa0a9134cb | ||
|
|
749eac74fe | ||
|
|
ac39908737 | ||
|
|
bb8f4bf488 | ||
|
|
db0d157a74 | ||
|
|
bd8e1bbe71 | ||
|
|
7aba898cf5 | ||
|
|
baf039755f | ||
|
|
70977f7d80 | ||
|
|
884342d6af | ||
|
|
411b0fb4c2 | ||
|
|
8053fb2399 | ||
|
|
ed42dcab9c | ||
|
|
866b5b0f2f | ||
|
|
5834a1a0fa | ||
|
|
8c6d845603 | ||
|
|
667f363f3c | ||
|
|
e209ff38d9 | ||
|
|
ea915993b6 | ||
|
|
72d0468c6a | ||
|
|
35ae13b1c3 | ||
|
|
1d9460f565 | ||
|
|
e9a3ed71b4 | ||
|
|
e344e5b7e6 | ||
|
|
e814064403 | ||
|
|
f5aeb5cbcd | ||
|
|
f41164b892 | ||
|
|
03073c8364 | ||
|
|
a359bff531 | ||
|
|
3789ac6433 | ||
|
|
9f53f59f18 | ||
|
|
521bd746e3 | ||
|
|
3d8e43a42b | ||
|
|
9452e1852d | ||
|
|
3920d24af6 | ||
|
|
3af11e6ba8 | ||
|
|
7bcde46d49 | ||
|
|
0b73041718 | ||
|
|
dcdc0cb8c1 | ||
|
|
ad6ac1aad6 | ||
|
|
249dc6accd | ||
|
|
939e5999ca | ||
|
|
1f91e57d56 | ||
|
|
81e749dc60 | ||
|
|
241b2afda8 | ||
|
|
94cc29f227 | ||
|
|
6d6659eee1 | ||
|
|
5220be0775 | ||
|
|
07ebbf0863 | ||
|
|
b60c767fc5 | ||
|
|
371c3b78c3 | ||
|
|
6a3aa219d5 | ||
|
|
df586ddfdd | ||
|
|
f3b2bbfec0 | ||
|
|
3ea2114798 | ||
|
|
809cf70e0e | ||
|
|
390619535f | ||
|
|
3392ac1fa8 | ||
|
|
b09d94abbe | ||
|
|
03ac01d21f | ||
|
|
12b1d785e5 | ||
|
|
71c58e9d2e | ||
|
|
13c2997a52 | ||
|
|
47b840cac9 | ||
|
|
3f7f243f50 | ||
|
|
1d1e83b18d | ||
|
|
6f3a602c76 | ||
|
|
afb7a4c6a7 | ||
|
|
d0c950d4ca | ||
|
|
63ee7d5211 | ||
|
|
6b0d875745 | ||
|
|
a47a9b9c0c | ||
|
|
27040a3e5c | ||
|
|
c7a8a40e22 | ||
|
|
408de6af63 | ||
|
|
8a324afaa1 | ||
|
|
54bc4cede0 | ||
|
|
4cfbea80b0 | ||
|
|
64cb8286bd | ||
|
|
3e92e0afc6 | ||
|
|
8a91308280 | ||
|
|
3da861d71e | ||
|
|
3566e18e99 | ||
|
|
6e608e627a | ||
|
|
65f7fb979b | ||
|
|
558b5e14f1 | ||
|
|
a5ee2dd03b | ||
|
|
9e9fe78b8d | ||
|
|
265e126faf | ||
|
|
af440e5c5b | ||
|
|
32b8c91113 | ||
|
|
dbc60ccca4 | ||
|
|
d5b5af5d3a | ||
|
|
8c1bd3bc4e | ||
|
|
8f638186a3 | ||
|
|
0b5a27e674 | ||
|
|
870f1aaaec | ||
|
|
23cb4dcbe5 | ||
|
|
4f125b4244 | ||
|
|
2b9de7938f | ||
|
|
75bb07184f | ||
|
|
1fb491d2e1 | ||
|
|
0bc8bdd841 | ||
|
|
71d4e2626e | ||
|
|
0b26cbdd01 | ||
|
|
ca72b3c18b | ||
|
|
8676f2711b | ||
|
|
788a86bdcf | ||
|
|
0df6b4b220 | ||
|
|
f14dcd5c28 | ||
|
|
f86548e046 | ||
|
|
9dea11ab11 | ||
|
|
00749f806c | ||
|
|
e4e3591413 | ||
|
|
3f847d7c7f | ||
|
|
67a10994a4 | ||
|
|
4016296e0b | ||
|
|
92777366ec | ||
|
|
beb34f8264 | ||
|
|
f6f8c5c858 | ||
|
|
a19c4dffcd | ||
|
|
a5754971f6 | ||
|
|
dbe6435809 | ||
|
|
7e5b980600 | ||
|
|
a6c3b70ee7 | ||
|
|
0a23e7951a | ||
|
|
e0e3fc8fef | ||
|
|
a8b947f5ca | ||
|
|
0f28df51f1 | ||
|
|
6e36528f35 | ||
|
|
a885fdbea7 | ||
|
|
713de74abb | ||
|
|
8db6a33e15 | ||
|
|
ed2d577be0 | ||
|
|
084eddecbf | ||
|
|
5e09ba302a | ||
|
|
fa37b40435 | ||
|
|
c95dde5187 | ||
|
|
4d5a4d501a | ||
|
|
ce97f20826 | ||
|
|
ab9cd13abc |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
*_plus.go
|
||||
*-plus.sh
|
||||
*_plus.html
|
||||
*_plus.js
|
||||
*@plus.js
|
||||
@@ -20,6 +20,18 @@ function build() {
|
||||
TAG="community"
|
||||
fi
|
||||
|
||||
# checking environment
|
||||
echo "checking required commands ..."
|
||||
commands=("zip" "unzip" "go" "find" "sed")
|
||||
for cmd in "${commands[@]}"; do
|
||||
if [ `which ${cmd}` ]; then
|
||||
echo "checking ${cmd}: ok"
|
||||
else
|
||||
echo "checking ${cmd}: not found"
|
||||
return
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION=$(lookup-version $ROOT/../internal/const/const.go)
|
||||
ZIP="${NAME}-${OS}-${ARCH}-${TAG}-v${VERSION}.zip"
|
||||
|
||||
@@ -38,6 +50,10 @@ function build() {
|
||||
echo "=============================="
|
||||
cd -
|
||||
|
||||
# generate files
|
||||
echo "generating files ..."
|
||||
go run -tags $TAG $ROOT/../cmd/edge-admin/main.go generate
|
||||
|
||||
# create dir & copy files
|
||||
echo "copying ..."
|
||||
if [ ! -d $DIST ]; then
|
||||
@@ -51,6 +67,19 @@ function build() {
|
||||
rm -f $DIST/web/tmp/*
|
||||
cp $ROOT/configs/server.template.yaml $DIST/configs/
|
||||
|
||||
# change _plus.[ext] to .[ext]
|
||||
if [ "${TAG}" = "plus" ]; then
|
||||
echo "converting filenames ..."
|
||||
exts=("html" "js" "css")
|
||||
for ext in "${exts[@]}"; do
|
||||
pattern="*_plus."${ext}
|
||||
find $DIST/web/views -type f -name $pattern | \
|
||||
while read filename; do
|
||||
mv ${filename} "${filename/_plus."${ext}"/."${ext}"}"
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
EDGE_API_ZIP_FILE=$ROOT"/../../EdgeAPI/dist/edge-api-${OS}-${ARCH}-${TAG}-v${APINodeVersion}.zip"
|
||||
cp $EDGE_API_ZIP_FILE $DIST/
|
||||
cd $DIST/
|
||||
@@ -60,11 +89,14 @@ function build() {
|
||||
|
||||
# build
|
||||
echo "building "${NAME}" ..."
|
||||
env GOOS=$OS GOARCH=$GOARCH go build -tags $TAG -ldflags="-s -w" -o $DIST/bin/${NAME} $ROOT/../cmd/edge-admin/main.go
|
||||
env GOOS=$OS GOARCH=$ARCH go build -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
|
||||
|
||||
# zip
|
||||
echo "zip files ..."
|
||||
|
||||
3
build/generate.sh
Executable file
3
build/generate.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
go run -tags=community ../cmd/edge-admin/main.go generate
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/apps"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configs"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/gen"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/nodes"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web"
|
||||
_ "github.com/iwind/TeaGo/bootstrap"
|
||||
@@ -70,6 +71,13 @@ func main() {
|
||||
}
|
||||
fmt.Println("change demo mode successfully")
|
||||
})
|
||||
app.On("generate", func() {
|
||||
err := gen.Generate()
|
||||
if err != nil {
|
||||
fmt.Println("generate failed: " + err.Error())
|
||||
return
|
||||
}
|
||||
})
|
||||
app.Run(func() {
|
||||
adminNode := nodes.NewAdminNode()
|
||||
adminNode.Run()
|
||||
|
||||
6
go.mod
6
go.mod
@@ -10,9 +10,11 @@ require (
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/iwind/TeaGo v0.0.0-20210720011303-fc255c995afa
|
||||
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3
|
||||
github.com/iwind/TeaGo v0.0.0-20211026123858-7de7a21cad24
|
||||
github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/miekg/dns v1.1.35
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
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
|
||||
|
||||
14
go.sum
14
go.sum
@@ -62,12 +62,18 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/iwind/TeaGo v0.0.0-20210628135026-38575a4ab060/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
||||
github.com/iwind/TeaGo v0.0.0-20210720011303-fc255c995afa h1:woN88uEmRRUNFD7pRZEtX9heDcjFn0ClMxjF5ButKow=
|
||||
github.com/iwind/TeaGo v0.0.0-20210720011303-fc255c995afa/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
||||
github.com/iwind/TeaGo v0.0.0-20210831140440-a2a442471b13 h1:HuEJ5xJfujW1Q6rNDhOu5LQXEBB2qLPah3jYslT8Gz4=
|
||||
github.com/iwind/TeaGo v0.0.0-20210831140440-a2a442471b13/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
||||
github.com/iwind/TeaGo v0.0.0-20211026123858-7de7a21cad24 h1:1cGulkD2SNJJRok5OKwyhP/Ddm+PgSWKOupn0cR36/A=
|
||||
github.com/iwind/TeaGo v0.0.0-20211026123858-7de7a21cad24/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
|
||||
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3 h1:aBSonas7vFcgTj9u96/bWGILGv1ZbUSTLiOzcI1ZT6c=
|
||||
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
|
||||
github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4 h1:VWGsCqTzObdlbf7UUE3oceIpcEKi4C/YBUszQXk118A=
|
||||
github.com/iwind/gosock v0.0.0-20211103081026-ee4652210ca4/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
@@ -77,8 +83,12 @@ github.com/miekg/dns v1.1.35 h1:oTfOaDH+mZkdcgdIjH6yBajRGtIwcwcaR+rt23ZSrJs=
|
||||
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
|
||||
@@ -19,6 +19,7 @@ const (
|
||||
AdminModuleCodeAdmin AdminModuleCode = "admin" // 系统用户
|
||||
AdminModuleCodeUser AdminModuleCode = "user" // 平台用户
|
||||
AdminModuleCodeFinance AdminModuleCode = "finance" // 财务
|
||||
AdminModuleCodePlan AdminModuleCode = "plan" // 套餐
|
||||
AdminModuleCodeLog AdminModuleCode = "log" // 日志
|
||||
AdminModuleCodeSetting AdminModuleCode = "setting" // 设置
|
||||
AdminModuleCodeCommon AdminModuleCode = "common" // 只要登录就可以访问的模块
|
||||
@@ -182,7 +183,7 @@ func AllModuleMaps() []maps.Map {
|
||||
}
|
||||
if teaconst.IsPlus {
|
||||
m = append(m, maps.Map{
|
||||
"name": "自建DNS",
|
||||
"name": "智能DNS",
|
||||
"code": AdminModuleCodeNS,
|
||||
"url": "/ns",
|
||||
})
|
||||
@@ -203,6 +204,11 @@ func AllModuleMaps() []maps.Map {
|
||||
"code": AdminModuleCodeFinance,
|
||||
"url": "/finance",
|
||||
},
|
||||
{
|
||||
"name": "套餐管理",
|
||||
"code": AdminModuleCodePlan,
|
||||
"url": "/plans",
|
||||
},
|
||||
{
|
||||
"name": "日志审计",
|
||||
"code": AdminModuleCodeLog,
|
||||
|
||||
@@ -11,7 +11,9 @@ import (
|
||||
var plusConfigFile = "plus.cache.json"
|
||||
|
||||
type PlusConfig struct {
|
||||
IsPlus bool `json:"isPlus"`
|
||||
IsPlus bool `json:"isPlus"`
|
||||
Components []string `json:"components"`
|
||||
DayTo string `json:"dayTo"`
|
||||
}
|
||||
|
||||
func ReadPlusConfig() *PlusConfig {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
Version = "0.3.0"
|
||||
Version = "0.3.8"
|
||||
|
||||
APINodeVersion = "0.3.0"
|
||||
APINodeVersion = "0.3.8"
|
||||
|
||||
ProductName = "Edge Admin"
|
||||
ProcessName = "edge-admin"
|
||||
@@ -18,4 +18,5 @@ const (
|
||||
CookieSID = "edgesid"
|
||||
|
||||
SystemdServiceName = "edge-admin"
|
||||
UpdatesURL = "https://goedge.cn/api/boot/versions?os=${os}&arch=${arch}"
|
||||
)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
//go:build community
|
||||
// +build community
|
||||
|
||||
package teaconst
|
||||
|
||||
// IsPlus 是否为企业版
|
||||
var IsPlus = false
|
||||
|
||||
@@ -4,9 +4,10 @@ package teaconst
|
||||
|
||||
var (
|
||||
IsRecoverMode = false
|
||||
)
|
||||
|
||||
var (
|
||||
IsDemoMode = false
|
||||
ErrorDemoOperation = "DEMO模式下无法进行创建、修改、删除等操作"
|
||||
|
||||
NewVersionCode = "" // 有新的版本
|
||||
NewVersionDownloadURL = "" // 新版本下载地址
|
||||
)
|
||||
|
||||
129
internal/gen/generate.go
Normal file
129
internal/gen/generate.go
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package gen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/conds/condutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/files"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func Generate() error {
|
||||
err := generateComponentsJSFile()
|
||||
if err != nil {
|
||||
return errors.New("generate 'components.js' failed: " + err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 生成Javascript文件
|
||||
func generateComponentsJSFile() error {
|
||||
var buffer = bytes.NewBuffer([]byte{})
|
||||
|
||||
var webRoot string
|
||||
if Tea.IsTesting() {
|
||||
webRoot = Tea.Root + "/../web/public/js/components/"
|
||||
} else {
|
||||
webRoot = Tea.Root + "/web/public/js/components/"
|
||||
}
|
||||
f := files.NewFile(webRoot)
|
||||
|
||||
f.Range(func(file *files.File) {
|
||||
if !file.IsFile() {
|
||||
return
|
||||
}
|
||||
if file.Ext() != ".js" {
|
||||
return
|
||||
}
|
||||
data, err := file.ReadAll()
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return
|
||||
}
|
||||
buffer.Write(data)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
})
|
||||
|
||||
// 条件组件
|
||||
typesJSON, err := json.Marshal(condutils.ReadAllAvailableCondTypes())
|
||||
if err != nil {
|
||||
logs.Println("ComponentsAction marshal request cond types failed: " + err.Error())
|
||||
} else {
|
||||
buffer.WriteString("window.REQUEST_COND_COMPONENTS = ")
|
||||
buffer.Write(typesJSON)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
// 条件操作符
|
||||
requestOperatorsJSON, err := json.Marshal(shared.AllRequestOperators())
|
||||
if err != nil {
|
||||
logs.Println("ComponentsAction marshal request operators failed: " + err.Error())
|
||||
} else {
|
||||
buffer.WriteString("window.REQUEST_COND_OPERATORS = ")
|
||||
buffer.Write(requestOperatorsJSON)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
// 请求变量
|
||||
requestVariablesJSON, err := json.Marshal(shared.DefaultRequestVariables())
|
||||
if err != nil {
|
||||
logs.Println("ComponentsAction marshal request variables failed: " + err.Error())
|
||||
} else {
|
||||
buffer.WriteString("window.REQUEST_VARIABLES = ")
|
||||
buffer.Write(requestVariablesJSON)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
// 指标
|
||||
metricHTTPKeysJSON, err := json.Marshal(serverconfigs.FindAllMetricKeyDefinitions(serverconfigs.MetricItemCategoryHTTP))
|
||||
if err != nil {
|
||||
logs.Println("ComponentsAction marshal metric http keys failed: " + err.Error())
|
||||
} else {
|
||||
buffer.WriteString("window.METRIC_HTTP_KEYS = ")
|
||||
buffer.Write(metricHTTPKeysJSON)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
// IP地址阈值项目
|
||||
ipAddrThresholdItemsJSON, err := json.Marshal(nodeconfigs.FindAllIPAddressThresholdItems())
|
||||
if err != nil {
|
||||
logs.Println("ComponentsAction marshal ip addr threshold items failed: " + err.Error())
|
||||
} else {
|
||||
buffer.WriteString("window.IP_ADDR_THRESHOLD_ITEMS = ")
|
||||
buffer.Write(ipAddrThresholdItemsJSON)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
// IP地址阈值动作
|
||||
ipAddrThresholdActionsJSON, err := json.Marshal(nodeconfigs.FindAllIPAddressThresholdActions())
|
||||
if err != nil {
|
||||
logs.Println("ComponentsAction marshal ip addr threshold actions failed: " + err.Error())
|
||||
} else {
|
||||
buffer.WriteString("window.IP_ADDR_THRESHOLD_ACTIONS = ")
|
||||
buffer.Write(ipAddrThresholdActionsJSON)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
fp, err := os.OpenFile(filepath.Clean(Tea.PublicFile("/js/components.js")), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.Copy(fp, buffer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
13
internal/gen/generate_test.go
Normal file
13
internal/gen/generate_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package gen
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGenerate(t *testing.T) {
|
||||
err := Generate()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("ok")
|
||||
}
|
||||
12
internal/goman/instance.go
Normal file
12
internal/goman/instance.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package goman
|
||||
|
||||
import "time"
|
||||
|
||||
type Instance struct {
|
||||
Id uint64
|
||||
CreatedTime time.Time
|
||||
File string
|
||||
Line int
|
||||
}
|
||||
81
internal/goman/lib.go
Normal file
81
internal/goman/lib.go
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package goman
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var locker = &sync.Mutex{}
|
||||
var instanceMap = map[uint64]*Instance{} // id => *Instance
|
||||
var instanceId = uint64(0)
|
||||
|
||||
// New 新创建goroutine
|
||||
func New(f func()) {
|
||||
_, file, line, _ := runtime.Caller(1)
|
||||
|
||||
go func() {
|
||||
locker.Lock()
|
||||
instanceId++
|
||||
|
||||
var instance = &Instance{
|
||||
Id: instanceId,
|
||||
CreatedTime: time.Now(),
|
||||
}
|
||||
|
||||
instance.File = file
|
||||
instance.Line = line
|
||||
|
||||
instanceMap[instanceId] = instance
|
||||
locker.Unlock()
|
||||
|
||||
// run function
|
||||
f()
|
||||
|
||||
locker.Lock()
|
||||
delete(instanceMap, instanceId)
|
||||
locker.Unlock()
|
||||
}()
|
||||
}
|
||||
|
||||
// NewWithArgs 创建带有参数的goroutine
|
||||
func NewWithArgs(f func(args ...interface{}), args ...interface{}) {
|
||||
_, file, line, _ := runtime.Caller(1)
|
||||
|
||||
go func() {
|
||||
locker.Lock()
|
||||
instanceId++
|
||||
|
||||
var instance = &Instance{
|
||||
Id: instanceId,
|
||||
CreatedTime: time.Now(),
|
||||
}
|
||||
|
||||
instance.File = file
|
||||
instance.Line = line
|
||||
|
||||
instanceMap[instanceId] = instance
|
||||
locker.Unlock()
|
||||
|
||||
// run function
|
||||
f(args...)
|
||||
|
||||
locker.Lock()
|
||||
delete(instanceMap, instanceId)
|
||||
locker.Unlock()
|
||||
}()
|
||||
}
|
||||
|
||||
// List 列出所有正在运行goroutine
|
||||
func List() []*Instance {
|
||||
locker.Lock()
|
||||
defer locker.Unlock()
|
||||
|
||||
var result = []*Instance{}
|
||||
for _, instance := range instanceMap {
|
||||
result = append(result, instance)
|
||||
}
|
||||
return result
|
||||
}
|
||||
28
internal/goman/lib_test.go
Normal file
28
internal/goman/lib_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package goman
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
New(func() {
|
||||
t.Log("Hello")
|
||||
|
||||
t.Log(List())
|
||||
})
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
t.Log(List())
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
func TestNewWithArgs(t *testing.T) {
|
||||
NewWithArgs(func(args ...interface{}) {
|
||||
t.Log(args[0], args[1])
|
||||
}, 1, 2)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
@@ -326,6 +326,16 @@ func (this *AdminNode) listenSock() error {
|
||||
case "demo":
|
||||
teaconst.IsDemoMode = !teaconst.IsDemoMode
|
||||
_ = cmd.ReplyOk()
|
||||
case "info":
|
||||
exePath, _ := os.Executable()
|
||||
_ = cmd.Reply(&gosock.Command{
|
||||
Code: "info",
|
||||
Params: map[string]interface{}{
|
||||
"pid": os.Getpid(),
|
||||
"version": teaconst.Version,
|
||||
"path": exePath,
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -27,11 +27,11 @@ type RPCClient struct {
|
||||
apiConfig *configs.APIConfig
|
||||
conns []*grpc.ClientConn
|
||||
|
||||
locker sync.Mutex
|
||||
locker sync.RWMutex
|
||||
}
|
||||
|
||||
// NewRPCClient 构造新的RPC客户端
|
||||
func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
|
||||
func NewRPCClient(apiConfig *configs.APIConfig, isPrimary bool) (*RPCClient, error) {
|
||||
if apiConfig == nil {
|
||||
return nil, errors.New("api config should not be nil")
|
||||
}
|
||||
@@ -46,7 +46,9 @@ func NewRPCClient(apiConfig *configs.APIConfig) (*RPCClient, error) {
|
||||
}
|
||||
|
||||
// 设置RPC
|
||||
dao.SetRPC(client)
|
||||
if isPrimary {
|
||||
dao.SetRPC(client)
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
@@ -103,6 +105,10 @@ func (this *RPCClient) NodeIPAddressLogRPC() pb.NodeIPAddressLogServiceClient {
|
||||
return pb.NewNodeIPAddressLogServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NodeIPAddressThresholdRPC() pb.NodeIPAddressThresholdServiceClient {
|
||||
return pb.NewNodeIPAddressThresholdServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NodeValueRPC() pb.NodeValueServiceClient {
|
||||
return pb.NewNodeValueServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -304,6 +310,10 @@ 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())
|
||||
}
|
||||
@@ -356,6 +366,14 @@ func (this *RPCClient) ACMETaskRPC() pb.ACMETaskServiceClient {
|
||||
return pb.NewACMETaskServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ACMEProviderRPC() pb.ACMEProviderServiceClient {
|
||||
return pb.NewACMEProviderServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ACMEProviderAccountRPC() pb.ACMEProviderAccountServiceClient {
|
||||
return pb.NewACMEProviderAccountServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) UserRPC() pb.UserServiceClient {
|
||||
return pb.NewUserServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -364,6 +382,18 @@ func (this *RPCClient) UserBillRPC() pb.UserBillServiceClient {
|
||||
return pb.NewUserBillServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) UserAccountRPC() pb.UserAccountServiceClient {
|
||||
return pb.NewUserAccountServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) UserAccountLogRPC() pb.UserAccountLogServiceClient {
|
||||
return pb.NewUserAccountLogServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) UserAccountDailyStatRPC() pb.UserAccountDailyStatServiceClient {
|
||||
return pb.NewUserAccountDailyStatServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) UserAccessKeyRPC() pb.UserAccessKeyServiceClient {
|
||||
return pb.NewUserAccessKeyServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -448,6 +478,14 @@ func (this *RPCClient) ServerStatBoardChartRPC() pb.ServerStatBoardChartServiceC
|
||||
return pb.NewServerStatBoardChartServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) PlanRPC() pb.PlanServiceClient {
|
||||
return pb.NewPlanServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) UserPlanRPC() pb.UserPlanServiceClient {
|
||||
return pb.NewUserPlanServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
// Context 构造Admin上下文
|
||||
func (this *RPCClient) Context(adminId int64) context.Context {
|
||||
ctx := context.Background()
|
||||
@@ -497,7 +535,11 @@ func (this *RPCClient) APIContext(apiNodeId int64) context.Context {
|
||||
// UpdateConfig 修改配置
|
||||
func (this *RPCClient) UpdateConfig(config *configs.APIConfig) error {
|
||||
this.apiConfig = config
|
||||
return this.init()
|
||||
|
||||
this.locker.Lock()
|
||||
err := this.init()
|
||||
this.locker.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
// 初始化
|
||||
@@ -575,3 +617,20 @@ func (this *RPCClient) pickConn() *grpc.ClientConn {
|
||||
|
||||
return this.conns[rands.Int(0, len(this.conns)-1)]
|
||||
}
|
||||
|
||||
// Close 关闭
|
||||
func (this *RPCClient) Close() error {
|
||||
this.locker.Lock()
|
||||
defer this.locker.Unlock()
|
||||
|
||||
var lastErr error
|
||||
for _, conn := range this.conns {
|
||||
var err = conn.Close()
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return lastErr
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ func TestRPCClient_NodeRPC(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rpc, err := NewRPCClient(config)
|
||||
rpc, err := NewRPCClient(config, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -41,7 +41,7 @@ func TestRPC_Dial_HTTP(t *testing.T) {
|
||||
},
|
||||
NodeId: "a7e55782dab39bce0901058a1e14a0e6",
|
||||
Secret: "lvyPobI3BszkJopz5nPTocOs0OLkEJ7y",
|
||||
})
|
||||
}, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -62,7 +62,7 @@ func TestRPC_Dial_HTTP_2(t *testing.T) {
|
||||
},
|
||||
NodeId: "a7e55782dab39bce0901058a1e14a0e6",
|
||||
Secret: "lvyPobI3BszkJopz5nPTocOs0OLkEJ7y",
|
||||
})
|
||||
}, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func TestRPC_Dial_HTTPS(t *testing.T) {
|
||||
},
|
||||
NodeId: "a7e55782dab39bce0901058a1e14a0e6",
|
||||
Secret: "lvyPobI3BszkJopz5nPTocOs0OLkEJ7y",
|
||||
})
|
||||
}, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func SharedRPC() (*RPCClient, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := NewRPCClient(config)
|
||||
client, err := NewRPCClient(config, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ package setup
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configs"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"os"
|
||||
)
|
||||
|
||||
var isConfigured bool
|
||||
@@ -16,3 +18,16 @@ func IsConfigured() bool {
|
||||
isConfigured = err == nil
|
||||
return isConfigured
|
||||
}
|
||||
|
||||
// IsNewInstalled IsNew 检查是否新安装
|
||||
func IsNewInstalled() bool {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
_, err = os.Stat(homeDir + "/." + teaconst.ProcessName + "/api.yaml")
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
104
internal/tasks/task_check_updates.go
Normal file
104
internal/tasks/task_check_updates.go
Normal file
@@ -0,0 +1,104 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/events"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/goman"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
events.On(events.EventStart, func() {
|
||||
var task = NewCheckUpdatesTask()
|
||||
goman.New(func() {
|
||||
task.Start()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
type CheckUpdatesTask struct {
|
||||
ticker *time.Ticker
|
||||
}
|
||||
|
||||
func NewCheckUpdatesTask() *CheckUpdatesTask {
|
||||
return &CheckUpdatesTask{}
|
||||
}
|
||||
|
||||
func (this *CheckUpdatesTask) Start() {
|
||||
this.ticker = time.NewTicker(12 * time.Hour)
|
||||
for range this.ticker.C {
|
||||
err := this.Loop()
|
||||
if err != nil {
|
||||
logs.Println("[TASK][CHECK_UPDATES_TASK]" + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (this *CheckUpdatesTask) Loop() error {
|
||||
type Response struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
// 目前支持Linux
|
||||
if runtime.GOOS != "linux" {
|
||||
return nil
|
||||
}
|
||||
|
||||
var apiURL = teaconst.UpdatesURL
|
||||
apiURL = strings.ReplaceAll(apiURL, "${os}", runtime.GOOS)
|
||||
apiURL = strings.ReplaceAll(apiURL, "${arch}", runtime.GOARCH)
|
||||
resp, err := http.Get(apiURL)
|
||||
if err != nil {
|
||||
return errors.New("read api failed: " + err.Error())
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.New("read api failed: " + err.Error())
|
||||
}
|
||||
|
||||
var apiResponse = &Response{}
|
||||
err = json.Unmarshal(data, apiResponse)
|
||||
if err != nil {
|
||||
return errors.New("decode version data failed: " + err.Error())
|
||||
}
|
||||
|
||||
if apiResponse.Code != 200 {
|
||||
return errors.New("invalid response: " + apiResponse.Message)
|
||||
}
|
||||
|
||||
var m = maps.NewMap(apiResponse.Data)
|
||||
var dlHost = m.GetString("host")
|
||||
var versions = m.GetSlice("versions")
|
||||
if len(versions) > 0 {
|
||||
for _, version := range versions {
|
||||
var vMap = maps.NewMap(version)
|
||||
if vMap.GetString("code") == "admin" {
|
||||
var latestVersion = vMap.GetString("version")
|
||||
if stringutil.VersionCompare(teaconst.Version, latestVersion) < 0 {
|
||||
teaconst.NewVersionCode = latestVersion
|
||||
teaconst.NewVersionDownloadURL = dlHost + vMap.GetString("url")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configs"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/events"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/setup"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -23,7 +24,9 @@ import (
|
||||
func init() {
|
||||
events.On(events.EventStart, func() {
|
||||
task := NewSyncAPINodesTask()
|
||||
go task.Start()
|
||||
goman.New(func() {
|
||||
task.Start()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -66,7 +69,7 @@ func (this *SyncAPINodesTask) Loop() error {
|
||||
}
|
||||
|
||||
newEndpoints := []string{}
|
||||
for _, node := range resp.Nodes {
|
||||
for _, node := range resp.ApiNodes {
|
||||
if !node.IsOn {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package tasks
|
||||
import (
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/events"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/goman"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/setup"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
|
||||
@@ -17,7 +18,9 @@ import (
|
||||
func init() {
|
||||
events.On(events.EventStart, func() {
|
||||
task := NewSyncClusterTask()
|
||||
go task.Start()
|
||||
goman.New(func() {
|
||||
task.Start()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -51,7 +54,7 @@ func (this *SyncClusterTask) loop() error {
|
||||
}
|
||||
ctx := rpcClient.Context(0)
|
||||
|
||||
tasksResp, err := rpcClient.NodeTaskRPC().FindNotifyingNodeTasks(ctx, &pb.FindNotifyingNodeTasksRequest{Size: 100})
|
||||
tasksResp, err := rpcClient.NodeTaskRPC().FindNotifyingNodeTasks(ctx, &pb.FindNotifyingNodeTasksRequest{Size: 500})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"math/big"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 将IP转换为整型
|
||||
// IP2Long 将IP转换为整型
|
||||
func IP2Long(ip string) uint64 {
|
||||
s := net.ParseIP(ip)
|
||||
if len(s) != 16 {
|
||||
@@ -23,7 +26,7 @@ func IP2Long(ip string) uint64 {
|
||||
return uint64(binary.BigEndian.Uint32(s.To4()))
|
||||
}
|
||||
|
||||
// 判断是否为IPv4
|
||||
// IsIPv4 判断是否为IPv4
|
||||
func IsIPv4(ip string) bool {
|
||||
if !regexp.MustCompile(`^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$`).MatchString(ip) {
|
||||
return false
|
||||
@@ -34,10 +37,100 @@ func IsIPv4(ip string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// 判断是否为IPv6
|
||||
// IsIPv6 判断是否为IPv6
|
||||
func IsIPv6(ip string) bool {
|
||||
if !strings.Contains(ip, ":") {
|
||||
return false
|
||||
}
|
||||
return len(net.ParseIP(ip)) == net.IPv6len
|
||||
}
|
||||
|
||||
// ExtractIP 分解IP
|
||||
// 只支持D段掩码的CIDR
|
||||
// 最多只记录255个值
|
||||
func ExtractIP(ipStrings string) ([]string, error) {
|
||||
ipStrings = strings.ReplaceAll(ipStrings, " ", "")
|
||||
|
||||
// CIDR
|
||||
if strings.Contains(ipStrings, "/") {
|
||||
_, cidrNet, err := net.ParseCIDR(ipStrings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var index = strings.Index(ipStrings, "/")
|
||||
var ipFrom = ipStrings[:index]
|
||||
var bits = types.Int(ipStrings[index+1:])
|
||||
if bits < 24 {
|
||||
return nil, errors.New("CIDR bits should be greater than 24")
|
||||
}
|
||||
|
||||
var ipv4 = net.ParseIP(ipFrom).To4()
|
||||
if len(ipv4) == 0 {
|
||||
return nil, errors.New("support IPv4 only")
|
||||
}
|
||||
|
||||
var result = []string{}
|
||||
ipv4[3] = 0 // 从0开始
|
||||
for i := 0; i <= 255; i++ {
|
||||
if cidrNet.Contains(ipv4) {
|
||||
result = append(result, ipv4.String())
|
||||
}
|
||||
ipv4 = NextIP(ipv4)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// IP Range
|
||||
if strings.Contains(ipStrings, "-") {
|
||||
var index = strings.Index(ipStrings, "-")
|
||||
var ipFromString = ipStrings[:index]
|
||||
var ipToString = ipStrings[index+1:]
|
||||
|
||||
var ipFrom = net.ParseIP(ipFromString).To4()
|
||||
if len(ipFrom) == 0 {
|
||||
return nil, errors.New("invalid ip '" + ipFromString + "'")
|
||||
}
|
||||
|
||||
var ipTo = net.ParseIP(ipToString).To4()
|
||||
if len(ipTo) == 0 {
|
||||
return nil, errors.New("invalid ip '" + ipToString + "'")
|
||||
}
|
||||
|
||||
if bytes.Compare(ipFrom, ipTo) > 0 {
|
||||
ipFrom, ipTo = ipTo, ipFrom
|
||||
}
|
||||
|
||||
var result = []string{}
|
||||
for i := 0; i < 255; i++ {
|
||||
if bytes.Compare(ipFrom, ipTo) > 0 {
|
||||
break
|
||||
}
|
||||
result = append(result, ipFrom.String())
|
||||
ipFrom = NextIP(ipFrom)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
return []string{ipStrings}, nil
|
||||
}
|
||||
|
||||
// NextIP IP增加1
|
||||
func NextIP(prevIP net.IP) net.IP {
|
||||
var ip = make(net.IP, len(prevIP))
|
||||
copy(ip, prevIP)
|
||||
var index = len(ip) - 1
|
||||
for {
|
||||
if ip[index] == 255 {
|
||||
ip[index] = 0
|
||||
index--
|
||||
if index < 0 {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
ip[index]++
|
||||
break
|
||||
}
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -83,3 +84,27 @@ func TestIsIPv6(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractIP(t *testing.T) {
|
||||
t.Log(ExtractIP("192.168.1.100"))
|
||||
}
|
||||
|
||||
func TestExtractIP_CIDR(t *testing.T) {
|
||||
t.Log(ExtractIP("192.168.2.100/24"))
|
||||
}
|
||||
|
||||
func TestExtractIP_Range(t *testing.T) {
|
||||
t.Log(ExtractIP("192.168.2.100 - 192.168.4.2"))
|
||||
}
|
||||
|
||||
func TestNextIP(t *testing.T) {
|
||||
for _, ip := range []string{"192.168.1.1", "0.0.0.0", "255.255.255.255", "192.168.2.255", "192.168.255.255"} {
|
||||
t.Log(ip+":", NextIP(net.ParseIP(ip).To4()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNextIP_Copy(t *testing.T) {
|
||||
var ip = net.ParseIP("192.168.1.100")
|
||||
var nextIP = NextIP(ip)
|
||||
t.Log(ip, nextIP)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
@@ -16,13 +17,19 @@ func LookupCNAME(host string) (string, error) {
|
||||
|
||||
m.SetQuestion(host+".", dns.TypeCNAME)
|
||||
m.RecursionDesired = true
|
||||
r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(r.Answer) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return r.Answer[0].(*dns.CNAME).Target, nil
|
||||
var lastErr error
|
||||
for _, serverAddr := range config.Servers {
|
||||
r, _, err := c.Exchange(m, configutils.QuoteIP(serverAddr)+":"+config.Port)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
if len(r.Answer) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
return r.Answer[0].(*dns.CNAME).Target, nil
|
||||
}
|
||||
return "", lastErr
|
||||
}
|
||||
|
||||
@@ -13,38 +13,30 @@ func FormatInt(value int) string {
|
||||
return strconv.Itoa(value)
|
||||
}
|
||||
|
||||
func FormatBytes(bytes int64) string {
|
||||
if bytes < 1024 {
|
||||
return FormatInt64(bytes) + "B"
|
||||
} else if bytes < 1024*1024 {
|
||||
return fmt.Sprintf("%.2fKB", float64(bytes)/1024)
|
||||
} else if bytes < 1024*1024*1024 {
|
||||
return fmt.Sprintf("%.2fMB", float64(bytes)/1024/1024)
|
||||
} else if bytes < 1024*1024*1024*1024 {
|
||||
return fmt.Sprintf("%.2fGB", float64(bytes)/1024/1024/1024)
|
||||
} else if bytes < 1024*1024*1024*1024*1024 {
|
||||
return fmt.Sprintf("%.2fTB", float64(bytes)/1024/1024/1024/1024)
|
||||
} else if bytes < 1024*1024*1024*1024*1024*1024 {
|
||||
return fmt.Sprintf("%.2fPB", float64(bytes)/1024/1024/1024/1024/1024)
|
||||
} else {
|
||||
return fmt.Sprintf("%.2fEB", float64(bytes)/1024/1024/1024/1024/1024/1024)
|
||||
func Pow1024(n int) int64 {
|
||||
if n <= 0 {
|
||||
return 1
|
||||
}
|
||||
if n == 1 {
|
||||
return 1024
|
||||
}
|
||||
return Pow1024(n-1) * 1024
|
||||
}
|
||||
|
||||
func FormatBits(bits int64) string {
|
||||
if bits < 1000 {
|
||||
return FormatInt64(bits) + "B"
|
||||
} else if bits < 1000*1000 {
|
||||
return fmt.Sprintf("%.2fKB", float64(bits)/1000)
|
||||
} else if bits < 1000*1000*1000 {
|
||||
return fmt.Sprintf("%.2fMB", float64(bits)/1000/1000)
|
||||
} else if bits < 1000*1000*1000*1000 {
|
||||
return fmt.Sprintf("%.2fGB", float64(bits)/1000/1000/1000)
|
||||
} else if bits < 1000*1000*1000*1000*1000 {
|
||||
return fmt.Sprintf("%.2fTB", float64(bits)/1000/1000/1000/1000)
|
||||
} else if bits < 1000*1000*1000*1000*1000*1000 {
|
||||
return fmt.Sprintf("%.2fPB", float64(bits)/1000/1000/1000/1000/1000)
|
||||
func FormatBytes(bytes int64) string {
|
||||
if bytes < Pow1024(1) {
|
||||
return FormatInt64(bytes) + "B"
|
||||
} else if bytes < Pow1024(2) {
|
||||
return fmt.Sprintf("%.2fKB", float64(bytes)/float64(Pow1024(1)))
|
||||
} else if bytes < Pow1024(3) {
|
||||
return fmt.Sprintf("%.2fMB", float64(bytes)/float64(Pow1024(2)))
|
||||
} else if bytes < Pow1024(4) {
|
||||
return fmt.Sprintf("%.2fGB", float64(bytes)/float64(Pow1024(3)))
|
||||
} else if bytes < Pow1024(5) {
|
||||
return fmt.Sprintf("%.2fTB", float64(bytes)/float64(Pow1024(4)))
|
||||
} else if bytes < Pow1024(6) {
|
||||
return fmt.Sprintf("%.2fPB", float64(bytes)/float64(Pow1024(5)))
|
||||
} else {
|
||||
return fmt.Sprintf("%.2fEB", float64(bits)/1000/1000/1000/1000/1000/1000)
|
||||
return fmt.Sprintf("%.2fEB", float64(bytes)/float64(Pow1024(6)))
|
||||
}
|
||||
}
|
||||
|
||||
16
internal/utils/numberutils/utils_test.go
Normal file
16
internal/utils/numberutils/utils_test.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package numberutils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestFormatBytes(t *testing.T) {
|
||||
t.Log(FormatBytes(1))
|
||||
t.Log(FormatBytes(1000))
|
||||
t.Log(FormatBytes(1_000_000))
|
||||
t.Log(FormatBytes(1_000_000_000))
|
||||
t.Log(FormatBytes(1_000_000_000_000))
|
||||
t.Log(FormatBytes(1_000_000_000_000_000))
|
||||
t.Log(FormatBytes(1_000_000_000_000_000_000))
|
||||
t.Log(FormatBytes(9_000_000_000_000_000_000))
|
||||
}
|
||||
@@ -19,6 +19,8 @@ type ParentAction struct {
|
||||
actions.ActionObject
|
||||
|
||||
rpcClient *rpc.RPCClient
|
||||
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// Parent 可以调用自身的一个简便方法
|
||||
@@ -117,6 +119,10 @@ func (this *ParentAction) RPC() *rpc.RPCClient {
|
||||
|
||||
// AdminContext 获取Context
|
||||
func (this *ParentAction) AdminContext() context.Context {
|
||||
if this.ctx != nil {
|
||||
return this.ctx
|
||||
}
|
||||
|
||||
if this.rpcClient == nil {
|
||||
rpcClient, err := rpc.SharedRPC()
|
||||
if err != nil {
|
||||
@@ -125,7 +131,8 @@ func (this *ParentAction) AdminContext() context.Context {
|
||||
}
|
||||
this.rpcClient = rpcClient
|
||||
}
|
||||
return this.rpcClient.Context(this.AdminId())
|
||||
this.ctx = this.rpcClient.Context(this.AdminId())
|
||||
return this.ctx
|
||||
}
|
||||
|
||||
// ViewData 视图里可以使用的数据
|
||||
|
||||
@@ -13,16 +13,35 @@ type DeleteAction struct {
|
||||
func (this *DeleteAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
// TODO 检查权限
|
||||
// 创建日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "删除API节点 %d", params.NodeId)
|
||||
|
||||
_, err := this.RPC().APINodeRPC().DeleteAPINode(this.AdminContext(), &pb.DeleteAPINodeRequest{NodeId: params.NodeId})
|
||||
// 检查是否是唯一的节点
|
||||
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ApiNodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var apiNode = nodeResp.ApiNode
|
||||
if apiNode == nil {
|
||||
this.Success()
|
||||
}
|
||||
if apiNode.IsOn {
|
||||
countResp, err := this.RPC().APINodeRPC().CountAllEnabledAndOnAPINodes(this.AdminContext(), &pb.CountAllEnabledAndOnAPINodesRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if countResp.Count == 1 {
|
||||
this.Fail("无法删除此节点:必须保留至少一个可用的API节点")
|
||||
}
|
||||
}
|
||||
|
||||
_, err = this.RPC().APINodeRPC().DeleteAPINode(this.AdminContext(), &pb.DeleteAPINodeRequest{ApiNodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 创建日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "删除API节点 %d", params.NodeId)
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
return
|
||||
}
|
||||
|
||||
for _, node := range nodesResp.Nodes {
|
||||
for _, node := range nodesResp.ApiNodes {
|
||||
// 状态
|
||||
status := &nodeconfigs.NodeStatus{}
|
||||
if len(node.StatusJSON) > 0 {
|
||||
|
||||
@@ -180,7 +180,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 创建日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "创建API节点 %d", createResp.NodeId)
|
||||
defer this.CreateLog(oplogs.LevelInfo, "创建API节点 %d", createResp.ApiNodeId)
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ func (this *IndexAction) Init() {
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
|
||||
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ApiNodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.Node
|
||||
node := nodeResp.ApiNode
|
||||
if node == nil {
|
||||
this.NotFound("apiNode", params.NodeId)
|
||||
return
|
||||
|
||||
@@ -21,12 +21,12 @@ func (this *InstallAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
// API节点信息
|
||||
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
|
||||
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ApiNodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.Node
|
||||
node := nodeResp.ApiNode
|
||||
if node == nil {
|
||||
this.NotFound("apiNode", params.NodeId)
|
||||
return
|
||||
|
||||
@@ -31,12 +31,12 @@ func (this *LogsAction) RunGet(params struct {
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["level"] = params.Level
|
||||
|
||||
apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{NodeId: params.NodeId})
|
||||
apiNodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{ApiNodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
apiNode := apiNodeResp.Node
|
||||
apiNode := apiNodeResp.ApiNode
|
||||
if apiNode == nil {
|
||||
this.NotFound("apiNode", params.NodeId)
|
||||
return
|
||||
|
||||
@@ -23,13 +23,13 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
nodeResp, err := this.RPC().APINodeRPC().FindEnabledAPINode(this.AdminContext(), &pb.FindEnabledAPINodeRequest{
|
||||
NodeId: params.NodeId,
|
||||
ApiNodeId: params.NodeId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.Node
|
||||
node := nodeResp.ApiNode
|
||||
if node == nil {
|
||||
this.WriteString("要操作的节点不存在")
|
||||
return
|
||||
@@ -281,7 +281,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
_, err = this.RPC().APINodeRPC().UpdateAPINode(this.AdminContext(), &pb.UpdateAPINodeRequest{
|
||||
NodeId: params.NodeId,
|
||||
ApiNodeId: params.NodeId,
|
||||
Name: params.Name,
|
||||
Description: params.Description,
|
||||
HttpJSON: httpJSON,
|
||||
|
||||
@@ -95,6 +95,7 @@ func (this *CreateBatchAction) RunPost(params struct {
|
||||
Name: "IP地址",
|
||||
Ip: ip,
|
||||
CanAccess: true,
|
||||
IsUp: true,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -3,6 +3,7 @@ package cluster
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
@@ -75,7 +76,7 @@ func (this *CreateNodeAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
apiNodes := apiNodesResp.Nodes
|
||||
apiNodes := apiNodesResp.ApiNodes
|
||||
apiEndpoints := []string{}
|
||||
for _, apiNode := range apiNodes {
|
||||
if !apiNode.IsOn {
|
||||
@@ -167,32 +168,86 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
nodeId := createResp.NodeId
|
||||
|
||||
// IP地址
|
||||
for _, address := range ipAddresses {
|
||||
addressId := address.GetInt64("id")
|
||||
if addressId > 0 {
|
||||
var resultIPAddresses = []string{}
|
||||
for _, addr := range ipAddresses {
|
||||
var resultAddrIds = []int64{}
|
||||
|
||||
addrId := addr.GetInt64("id")
|
||||
if addrId > 0 {
|
||||
resultAddrIds = append(resultAddrIds, addrId)
|
||||
_, err = this.RPC().NodeIPAddressRPC().UpdateNodeIPAddressNodeId(this.AdminContext(), &pb.UpdateNodeIPAddressNodeIdRequest{
|
||||
NodeIPAddressId: addressId,
|
||||
NodeIPAddressId: addrId,
|
||||
NodeId: nodeId,
|
||||
})
|
||||
} else {
|
||||
var thresholdsJSON = []byte{}
|
||||
var thresholds = address.GetSlice("thresholds")
|
||||
if len(thresholds) > 0 {
|
||||
thresholdsJSON, _ = json.Marshal(thresholds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Name: address.GetString("name"),
|
||||
Ip: address.GetString("ip"),
|
||||
CanAccess: address.GetBool("canAccess"),
|
||||
ThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
resultIPAddresses = append(resultIPAddresses, addr.GetString("ip"))
|
||||
} else {
|
||||
var ipStrings = addr.GetString("ip")
|
||||
result, err := utils.ExtractIP(ipStrings)
|
||||
if err != nil {
|
||||
this.Fail("节点创建成功,但是保存IP失败:" + err.Error())
|
||||
}
|
||||
|
||||
resultIPAddresses = append(resultIPAddresses, result...)
|
||||
|
||||
if len(result) == 1 {
|
||||
// 单个创建
|
||||
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: result[0],
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
addrId = createResp.NodeIPAddressId
|
||||
resultAddrIds = append(resultAddrIds, addrId)
|
||||
} else if len(result) > 1 {
|
||||
// 批量创建
|
||||
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddresses(this.AdminContext(), &pb.CreateNodeIPAddressesRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Name: addr.GetString("name"),
|
||||
IpList: result,
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
GroupValue: ipStrings,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
resultAddrIds = append(resultAddrIds, createResp.NodeIPAddressIds...)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
// 阈值
|
||||
var thresholds = addr.GetSlice("thresholds")
|
||||
if len(thresholds) > 0 {
|
||||
thresholdsJSON, err := json.Marshal(thresholds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, addrId := range resultAddrIds {
|
||||
_, err = this.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(this.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,11 +262,6 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
if nodeResp.Node != nil {
|
||||
var addresses = []string{}
|
||||
for _, addrMap := range ipAddresses {
|
||||
addresses = append(addresses, addrMap.GetString("ip"))
|
||||
}
|
||||
|
||||
var grantMap maps.Map = nil
|
||||
grantId := params.GrantId
|
||||
if grantId > 0 {
|
||||
@@ -236,7 +286,7 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
"name": nodeResp.Node.Name,
|
||||
"uniqueId": nodeResp.Node.UniqueId,
|
||||
"secret": nodeResp.Node.Secret,
|
||||
"addresses": addresses,
|
||||
"addresses": resultIPAddresses,
|
||||
"login": maps.Map{
|
||||
"id": 0,
|
||||
"name": "SSH",
|
||||
|
||||
@@ -4,7 +4,11 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/groups"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/thresholds"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/cache"
|
||||
"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"
|
||||
@@ -15,6 +19,7 @@ func init() {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
||||
Helper(clusters.NewClusterHelper()).
|
||||
Data("teaMenu", "clusters").
|
||||
Prefix("/clusters/cluster").
|
||||
Get("", new(IndexAction)).
|
||||
Get("/nodes", new(NodesAction)).
|
||||
@@ -42,10 +47,14 @@ func init() {
|
||||
Post("/start", new(node.StartAction)).
|
||||
Post("/stop", new(node.StopAction)).
|
||||
Post("/up", new(node.UpAction)).
|
||||
Get("/thresholds", new(thresholds.IndexAction)).
|
||||
Get("/detail", new(node.DetailAction)).
|
||||
GetPost("/updateDNSPopup", new(node.UpdateDNSPopupAction)).
|
||||
Post("/syncDomain", new(node.SyncDomainAction)).
|
||||
GetPost("/settings/cache", new(cache.IndexAction)).
|
||||
GetPost("/settings/dns", new(dns.IndexAction)).
|
||||
GetPost("/settings/system", new(system.IndexAction)).
|
||||
GetPost("/settings/ssh", new(ssh.IndexAction)).
|
||||
GetPost("/settings/thresholds", new(thresholds.IndexAction)).
|
||||
|
||||
// 分组相关
|
||||
Prefix("/clusters/cluster/groups").
|
||||
|
||||
@@ -49,7 +49,7 @@ func (this *InstallNodesAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, apiNode := range apiNodesResp.Nodes {
|
||||
for _, apiNode := range apiNodesResp.ApiNodes {
|
||||
if !apiNode.IsOn {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/ipAddresses/ipaddressutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
@@ -68,7 +69,7 @@ func (this *DetailAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
@@ -76,20 +77,25 @@ func (this *DetailAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var ipAddresses = ipAddressesResp.Addresses
|
||||
var ipAddresses = ipAddressesResp.NodeIPAddresses
|
||||
ipAddressMaps := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
var thresholds = []*nodeconfigs.NodeValueThresholdConfig{}
|
||||
if len(addr.ThresholdsJSON) > 0 {
|
||||
err = json.Unmarshal(addr.ThresholdsJSON, &thresholds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
thresholds, err := ipaddressutils.InitNodeIPAddressThresholds(this.Parent(), addr.Id)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 是否有备用IP
|
||||
var originIP = addr.Ip
|
||||
if len(addr.BackupIP) > 0 {
|
||||
addr.Ip = addr.BackupIP
|
||||
}
|
||||
|
||||
ipAddressMaps = append(ipAddressMaps, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
"originIP": originIP,
|
||||
"ip": addr.Ip,
|
||||
"canAccess": addr.CanAccess,
|
||||
"isOn": addr.IsOn,
|
||||
|
||||
@@ -20,7 +20,7 @@ func (this *IndexAction) Init() {
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
err := nodeutils.InitNodeInfo(this, params.NodeId)
|
||||
_, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -3,6 +3,7 @@ package node
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
@@ -25,16 +26,11 @@ func (this *InstallAction) RunGet(params struct {
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
|
||||
// 节点
|
||||
nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: params.NodeId})
|
||||
node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.Node
|
||||
if node == nil {
|
||||
this.WriteString("找不到要操作的节点")
|
||||
return
|
||||
}
|
||||
|
||||
// 安装信息
|
||||
if node.InstallStatus != nil {
|
||||
@@ -74,7 +70,7 @@ func (this *InstallAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
apiNodes := apiNodesResp.Nodes
|
||||
apiNodes := apiNodesResp.ApiNodes
|
||||
apiEndpoints := []string{}
|
||||
for _, apiNode := range apiNodes {
|
||||
if !apiNode.IsOn {
|
||||
@@ -84,15 +80,12 @@ func (this *InstallAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["apiEndpoints"] = "\"" + strings.Join(apiEndpoints, "\", \"") + "\""
|
||||
|
||||
this.Data["node"] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"installDir": node.InstallDir,
|
||||
"isInstalled": node.IsInstalled,
|
||||
"uniqueId": node.UniqueId,
|
||||
"secret": node.Secret,
|
||||
"cluster": clusterMap,
|
||||
}
|
||||
var nodeMap = this.Data["node"].(maps.Map)
|
||||
nodeMap["installDir"] = node.InstallDir
|
||||
nodeMap["isInstalled"] = node.IsInstalled
|
||||
nodeMap["uniqueId"] = node.UniqueId
|
||||
nodeMap["secret"] = node.Secret
|
||||
nodeMap["cluster"] = clusterMap
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ func (this *LogsAction) RunGet(params struct {
|
||||
Level string
|
||||
}) {
|
||||
// 初始化节点信息(用于菜单)
|
||||
err := nodeutils.InitNodeInfo(this, params.NodeId)
|
||||
_, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
@@ -69,6 +69,20 @@ func (this *LogsAction) RunGet(params struct {
|
||||
|
||||
logs := []maps.Map{}
|
||||
for _, log := range logsResp.NodeLogs {
|
||||
// 服务信息
|
||||
var serverMap = maps.Map{"id": 0}
|
||||
if log.ServerId > 0 {
|
||||
serverResp, err := this.RPC().ServerRPC().FindEnabledUserServerBasic(this.AdminContext(), &pb.FindEnabledUserServerBasicRequest{ServerId: log.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var server = serverResp.Server
|
||||
if server != nil {
|
||||
serverMap = maps.Map{"id": server.Id, "name": server.Name}
|
||||
}
|
||||
}
|
||||
|
||||
logs = append(logs, maps.Map{
|
||||
"tag": log.Tag,
|
||||
"description": log.Description,
|
||||
@@ -76,6 +90,7 @@ func (this *LogsAction) RunGet(params struct {
|
||||
"level": log.Level,
|
||||
"isToday": timeutil.FormatTime("Y-m-d", log.CreatedAt) == timeutil.Format("Y-m-d"),
|
||||
"count": log.Count,
|
||||
"server": serverMap,
|
||||
})
|
||||
}
|
||||
this.Data["logs"] = logs
|
||||
|
||||
@@ -4,31 +4,91 @@ package nodeutils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// InitNodeInfo 初始化节点信息
|
||||
func InitNodeInfo(action actionutils.ActionInterface, nodeId int64) error {
|
||||
func InitNodeInfo(parentAction *actionutils.ParentAction, nodeId int64) (*pb.Node, error) {
|
||||
// 节点信息(用于菜单)
|
||||
nodeResp, err := action.RPC().NodeRPC().FindEnabledNode(action.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: nodeId})
|
||||
nodeResp, err := parentAction.RPC().NodeRPC().FindEnabledNode(parentAction.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: nodeId})
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if nodeResp.Node == nil {
|
||||
return errors.New("node '" + strconv.FormatInt(nodeId, 10) + "' not found")
|
||||
return nil, errors.New("node '" + strconv.FormatInt(nodeId, 10) + "' not found")
|
||||
}
|
||||
var node = nodeResp.Node
|
||||
action.ViewData()["node"] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
|
||||
var groupMap maps.Map
|
||||
if node.NodeGroup != nil {
|
||||
groupMap = maps.Map{
|
||||
"id": node.NodeGroup.Id,
|
||||
"name": node.NodeGroup.Name,
|
||||
}
|
||||
}
|
||||
|
||||
parentAction.Data["node"] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
"group": groupMap,
|
||||
}
|
||||
var clusterId int64 = 0
|
||||
if node.NodeCluster != nil {
|
||||
action.ViewData()["clusterId"] = node.NodeCluster.Id
|
||||
parentAction.Data["clusterId"] = node.NodeCluster.Id
|
||||
clusterId = node.NodeCluster.Id
|
||||
}
|
||||
return nil
|
||||
|
||||
// 左侧菜单
|
||||
var prefix = "/clusters/cluster/node"
|
||||
var query = "clusterId=" + types.String(clusterId) + "&nodeId=" + types.String(nodeId)
|
||||
var menuItem = parentAction.Data.GetString("secondMenuItem")
|
||||
|
||||
var menuItems = []maps.Map{
|
||||
{
|
||||
"name": "基础设置",
|
||||
"url": prefix + "/update?" + query,
|
||||
"isActive": menuItem == "basic",
|
||||
},
|
||||
{
|
||||
"name": "DNS设置",
|
||||
"url": prefix + "/settings/dns?" + query,
|
||||
"isActive": menuItem == "dns",
|
||||
},
|
||||
{
|
||||
"name": "缓存设置",
|
||||
"url": prefix + "/settings/cache?" + query,
|
||||
"isActive": menuItem == "cache",
|
||||
},
|
||||
}
|
||||
if teaconst.IsPlus {
|
||||
menuItems = append(menuItems, []maps.Map{
|
||||
{
|
||||
"name": "阈值设置",
|
||||
"url": prefix + "/settings/thresholds?" + query,
|
||||
"isActive": menuItem == "threshold",
|
||||
},
|
||||
}...)
|
||||
}
|
||||
menuItems = append(menuItems, []maps.Map{
|
||||
{
|
||||
"name": "SSH设置",
|
||||
"url": prefix + "/settings/ssh?" + query,
|
||||
"isActive": menuItem == "ssh",
|
||||
},
|
||||
{
|
||||
"name": "系统设置",
|
||||
"url": prefix + "/settings/system?" + query,
|
||||
"isActive": menuItem == "system",
|
||||
},
|
||||
}...)
|
||||
parentAction.Data["leftMenuItems"] = menuItems
|
||||
|
||||
return nodeResp.Node, nil
|
||||
}
|
||||
|
||||
117
internal/web/actions/default/clusters/cluster/node/settings/cache/index.go
vendored
Normal file
117
internal/web/actions/default/clusters/cluster/node/settings/cache/index.go
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "update")
|
||||
this.SecondMenu("cache")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 缓存硬盘 & 内存容量
|
||||
var maxCacheDiskCapacity maps.Map = nil
|
||||
if node.MaxCacheDiskCapacity != nil {
|
||||
maxCacheDiskCapacity = maps.Map{
|
||||
"count": node.MaxCacheDiskCapacity.Count,
|
||||
"unit": node.MaxCacheDiskCapacity.Unit,
|
||||
}
|
||||
} else {
|
||||
maxCacheDiskCapacity = maps.Map{
|
||||
"count": 0,
|
||||
"unit": "gb",
|
||||
}
|
||||
}
|
||||
|
||||
var maxCacheMemoryCapacity maps.Map = nil
|
||||
if node.MaxCacheMemoryCapacity != nil {
|
||||
maxCacheMemoryCapacity = maps.Map{
|
||||
"count": node.MaxCacheMemoryCapacity.Count,
|
||||
"unit": node.MaxCacheMemoryCapacity.Unit,
|
||||
}
|
||||
} else {
|
||||
maxCacheMemoryCapacity = maps.Map{
|
||||
"count": 0,
|
||||
"unit": "gb",
|
||||
}
|
||||
}
|
||||
|
||||
var nodeMap = this.Data["node"].(maps.Map)
|
||||
nodeMap["maxCacheDiskCapacity"] = maxCacheDiskCapacity
|
||||
nodeMap["maxCacheMemoryCapacity"] = maxCacheMemoryCapacity
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
MaxCacheDiskCapacityJSON []byte
|
||||
MaxCacheMemoryCapacityJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改节点 %d 缓存设置", params.NodeId)
|
||||
|
||||
// 缓存硬盘 & 内存容量
|
||||
var pbMaxCacheDiskCapacity *pb.SizeCapacity
|
||||
if len(params.MaxCacheDiskCapacityJSON) > 0 {
|
||||
var sizeCapacity = &shared.SizeCapacity{}
|
||||
err := json.Unmarshal(params.MaxCacheDiskCapacityJSON, sizeCapacity)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbMaxCacheDiskCapacity = &pb.SizeCapacity{
|
||||
Count: sizeCapacity.Count,
|
||||
Unit: sizeCapacity.Unit,
|
||||
}
|
||||
}
|
||||
|
||||
var pbMaxCacheMemoryCapacity *pb.SizeCapacity
|
||||
if len(params.MaxCacheMemoryCapacityJSON) > 0 {
|
||||
var sizeCapacity = &shared.SizeCapacity{}
|
||||
err := json.Unmarshal(params.MaxCacheMemoryCapacityJSON, sizeCapacity)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbMaxCacheMemoryCapacity = &pb.SizeCapacity{
|
||||
Count: sizeCapacity.Count,
|
||||
Unit: sizeCapacity.Unit,
|
||||
}
|
||||
}
|
||||
|
||||
_, err := this.RPC().NodeRPC().UpdateNodeCache(this.AdminContext(), &pb.UpdateNodeCacheRequest{
|
||||
NodeId: params.NodeId,
|
||||
MaxCacheDiskCapacity: pbMaxCacheDiskCapacity,
|
||||
MaxCacheMemoryCapacity: pbMaxCacheMemoryCapacity,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "update")
|
||||
this.SecondMenu("dns")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// DNS相关
|
||||
var clusters = []*pb.NodeCluster{node.NodeCluster}
|
||||
clusters = append(clusters, node.SecondaryNodeClusters...)
|
||||
var allDNSRouteMaps = map[int64][]maps.Map{} // domain id => routes
|
||||
var routeMaps = map[int64][]maps.Map{} // domain id => routes
|
||||
for _, cluster := range clusters {
|
||||
dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
NodeClusterId: cluster.Id,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var dnsInfo = dnsInfoResp.Node
|
||||
if dnsInfo.DnsDomainId <= 0 || len(dnsInfo.DnsDomainName) == 0 {
|
||||
continue
|
||||
}
|
||||
var domainId = dnsInfo.DnsDomainId
|
||||
var domainName = dnsInfo.DnsDomainName
|
||||
if len(dnsInfo.Routes) > 0 {
|
||||
for _, route := range dnsInfo.Routes {
|
||||
routeMaps[domainId] = append(routeMaps[domainId], maps.Map{
|
||||
"domainId": domainId,
|
||||
"domainName": domainName,
|
||||
"code": route.Code,
|
||||
"name": route.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 所有线路选项
|
||||
routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfoResp.Node.DnsDomainId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, route := range routesResp.Routes {
|
||||
allDNSRouteMaps[domainId] = append(allDNSRouteMaps[domainId], maps.Map{
|
||||
"domainId": domainId,
|
||||
"domainName": domainName,
|
||||
"name": route.Name,
|
||||
"code": route.Code,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var domainRoutes = []maps.Map{}
|
||||
for _, m := range routeMaps {
|
||||
domainRoutes = append(domainRoutes, m...)
|
||||
}
|
||||
this.Data["dnsRoutes"] = domainRoutes
|
||||
|
||||
var allDomainRoutes = []maps.Map{}
|
||||
for _, m := range allDNSRouteMaps {
|
||||
allDomainRoutes = append(allDomainRoutes, m...)
|
||||
}
|
||||
this.Data["allDNSRoutes"] = allDomainRoutes
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
DnsDomainId int64
|
||||
DnsRoutesJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改节点 %d DNS设置", params.NodeId)
|
||||
|
||||
dnsRouteCodes := []string{}
|
||||
if len(params.DnsRoutesJSON) > 0 {
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &dnsRouteCodes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_, err := this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
IpAddr: "",
|
||||
DnsDomainId: 0,
|
||||
Routes: dnsRouteCodes,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
|
||||
"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("", "", "update")
|
||||
this.SecondMenu("ssh")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 登录信息
|
||||
var loginMap maps.Map = nil
|
||||
if node.NodeLogin != nil {
|
||||
loginParams := maps.Map{}
|
||||
if len(node.NodeLogin.Params) > 0 {
|
||||
err = json.Unmarshal(node.NodeLogin.Params, &loginParams)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
grantMap := maps.Map{}
|
||||
grantId := loginParams.GetInt64("grantId")
|
||||
if grantId > 0 {
|
||||
grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if grantResp.NodeGrant != nil {
|
||||
grantMap = maps.Map{
|
||||
"id": grantResp.NodeGrant.Id,
|
||||
"name": grantResp.NodeGrant.Name,
|
||||
"method": grantResp.NodeGrant.Method,
|
||||
"methodName": grantutils.FindGrantMethodName(grantResp.NodeGrant.Method),
|
||||
"username": grantResp.NodeGrant.Username,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loginMap = maps.Map{
|
||||
"id": node.NodeLogin.Id,
|
||||
"name": node.NodeLogin.Name,
|
||||
"type": node.NodeLogin.Type,
|
||||
"params": loginParams,
|
||||
"grant": grantMap,
|
||||
}
|
||||
}
|
||||
|
||||
var nodeMap = this.Data["node"].(maps.Map)
|
||||
nodeMap["login"] = loginMap
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
|
||||
LoginId int64
|
||||
GrantId int64
|
||||
SshHost string
|
||||
SshPort int
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改节点 %d SSH登录信息", params.NodeId)
|
||||
|
||||
// TODO 检查登录授权
|
||||
loginInfo := &pb.NodeLogin{
|
||||
Id: params.LoginId,
|
||||
Name: "SSH",
|
||||
Type: "ssh",
|
||||
Params: maps.Map{
|
||||
"grantId": params.GrantId,
|
||||
"host": params.SshHost,
|
||||
"port": params.SshPort,
|
||||
}.AsJSON(),
|
||||
}
|
||||
|
||||
_, err := this.RPC().NodeRPC().UpdateNodeLogin(this.AdminContext(), &pb.UpdateNodeLoginRequest{
|
||||
NodeId: params.NodeId,
|
||||
NodeLogin: loginInfo,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package system
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "update")
|
||||
this.SecondMenu("system")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取节点信息
|
||||
var nodeMap = this.Data["node"].(maps.Map)
|
||||
nodeMap["maxCPU"] = node.MaxCPU
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
MaxCPU int32
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改节点 %d 系统信息", params.NodeId)
|
||||
|
||||
if params.MaxCPU < 0 {
|
||||
this.Fail("CPU线程数不能小于0")
|
||||
}
|
||||
|
||||
_, err := this.RPC().NodeRPC().UpdateNodeSystem(this.AdminContext(), &pb.UpdateNodeSystemRequest{
|
||||
NodeId: params.NodeId,
|
||||
MaxCPU: params.MaxCPU,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -15,22 +15,22 @@ type IndexAction struct {
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "node", "threshold")
|
||||
this.Nav("", "", "update")
|
||||
this.SecondMenu("threshold")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
}) {
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
|
||||
// 初始化节点信息(用于菜单)
|
||||
err := nodeutils.InitNodeInfo(this, params.NodeId)
|
||||
_, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
|
||||
// 列出所有阈值
|
||||
thresholdsResp, err := this.RPC().NodeThresholdRPC().FindAllEnabledNodeThresholds(this.AdminContext(), &pb.FindAllEnabledNodeThresholdsRequest{
|
||||
Role: "node",
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// 节点状态
|
||||
// StatusAction 节点状态
|
||||
type StatusAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
@@ -4,11 +4,10 @@ import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/ipAddresses/ipaddressutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
@@ -19,12 +18,18 @@ type UpdateAction struct {
|
||||
|
||||
func (this *UpdateAction) Init() {
|
||||
this.Nav("", "node", "update")
|
||||
this.SecondMenu("nodes")
|
||||
this.SecondMenu("basic")
|
||||
}
|
||||
|
||||
func (this *UpdateAction) RunGet(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
_, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
|
||||
nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: params.NodeId})
|
||||
@@ -47,7 +52,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
@@ -56,14 +61,11 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
ipAddressMaps := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
var thresholds = []*nodeconfigs.NodeValueThresholdConfig{}
|
||||
if len(addr.ThresholdsJSON) > 0 {
|
||||
err = json.Unmarshal(addr.ThresholdsJSON, &thresholds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
thresholds, err := ipaddressutils.InitNodeIPAddressThresholds(this.Parent(), addr.Id)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
ipAddressMaps = append(ipAddressMaps, maps.Map{
|
||||
@@ -77,105 +79,6 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
})
|
||||
}
|
||||
|
||||
// DNS相关
|
||||
var clusters = []*pb.NodeCluster{node.NodeCluster}
|
||||
clusters = append(clusters, node.SecondaryNodeClusters...)
|
||||
var allDNSRouteMaps = map[int64][]maps.Map{} // domain id => routes
|
||||
var routeMaps = map[int64][]maps.Map{} // domain id => routes
|
||||
for _, cluster := range clusters {
|
||||
dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
NodeClusterId: cluster.Id,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var dnsInfo = dnsInfoResp.Node
|
||||
if dnsInfo.DnsDomainId <= 0 || len(dnsInfo.DnsDomainName) == 0 {
|
||||
continue
|
||||
}
|
||||
var domainId = dnsInfo.DnsDomainId
|
||||
var domainName = dnsInfo.DnsDomainName
|
||||
if len(dnsInfo.Routes) > 0 {
|
||||
for _, route := range dnsInfo.Routes {
|
||||
routeMaps[domainId] = append(routeMaps[domainId], maps.Map{
|
||||
"domainId": domainId,
|
||||
"domainName": domainName,
|
||||
"code": route.Code,
|
||||
"name": route.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 所有线路选项
|
||||
routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfoResp.Node.DnsDomainId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, route := range routesResp.Routes {
|
||||
allDNSRouteMaps[domainId] = append(allDNSRouteMaps[domainId], maps.Map{
|
||||
"domainId": domainId,
|
||||
"domainName": domainName,
|
||||
"name": route.Name,
|
||||
"code": route.Code,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var domainRoutes = []maps.Map{}
|
||||
for _, m := range routeMaps {
|
||||
domainRoutes = append(domainRoutes, m...)
|
||||
}
|
||||
this.Data["dnsRoutes"] = domainRoutes
|
||||
|
||||
var allDomainRoutes = []maps.Map{}
|
||||
for _, m := range allDNSRouteMaps {
|
||||
allDomainRoutes = append(allDomainRoutes, m...)
|
||||
}
|
||||
this.Data["allDNSRoutes"] = allDomainRoutes
|
||||
|
||||
// 登录信息
|
||||
var loginMap maps.Map = nil
|
||||
if node.NodeLogin != nil {
|
||||
loginParams := maps.Map{}
|
||||
if len(node.NodeLogin.Params) > 0 {
|
||||
err = json.Unmarshal(node.NodeLogin.Params, &loginParams)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
grantMap := maps.Map{}
|
||||
grantId := loginParams.GetInt64("grantId")
|
||||
if grantId > 0 {
|
||||
grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if grantResp.NodeGrant != nil {
|
||||
grantMap = maps.Map{
|
||||
"id": grantResp.NodeGrant.Id,
|
||||
"name": grantResp.NodeGrant.Name,
|
||||
"method": grantResp.NodeGrant.Method,
|
||||
"methodName": grantutils.FindGrantMethodName(grantResp.NodeGrant.Method),
|
||||
"username": grantResp.NodeGrant.Username,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loginMap = maps.Map{
|
||||
"id": node.NodeLogin.Id,
|
||||
"name": node.NodeLogin.Name,
|
||||
"type": node.NodeLogin.Type,
|
||||
"params": loginParams,
|
||||
"grant": grantMap,
|
||||
}
|
||||
}
|
||||
|
||||
// 分组
|
||||
var groupMap maps.Map = nil
|
||||
if node.NodeGroup != nil {
|
||||
@@ -194,45 +97,14 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存硬盘 & 内存容量
|
||||
var maxCacheDiskCapacity maps.Map = nil
|
||||
if node.MaxCacheDiskCapacity != nil {
|
||||
maxCacheDiskCapacity = maps.Map{
|
||||
"count": node.MaxCacheDiskCapacity.Count,
|
||||
"unit": node.MaxCacheDiskCapacity.Unit,
|
||||
}
|
||||
} else {
|
||||
maxCacheDiskCapacity = maps.Map{
|
||||
"count": 0,
|
||||
"unit": "gb",
|
||||
}
|
||||
}
|
||||
|
||||
var maxCacheMemoryCapacity maps.Map = nil
|
||||
if node.MaxCacheMemoryCapacity != nil {
|
||||
maxCacheMemoryCapacity = maps.Map{
|
||||
"count": node.MaxCacheMemoryCapacity.Count,
|
||||
"unit": node.MaxCacheMemoryCapacity.Unit,
|
||||
}
|
||||
} else {
|
||||
maxCacheMemoryCapacity = maps.Map{
|
||||
"count": 0,
|
||||
"unit": "gb",
|
||||
}
|
||||
}
|
||||
|
||||
var m = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"ipAddresses": ipAddressMaps,
|
||||
"cluster": clusterMap,
|
||||
"login": loginMap,
|
||||
"maxCPU": node.MaxCPU,
|
||||
"isOn": node.IsOn,
|
||||
"group": groupMap,
|
||||
"region": regionMap,
|
||||
"maxCacheDiskCapacity": maxCacheDiskCapacity,
|
||||
"maxCacheMemoryCapacity": maxCacheMemoryCapacity,
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"ipAddresses": ipAddressMaps,
|
||||
"cluster": clusterMap,
|
||||
"isOn": node.IsOn,
|
||||
"group": groupMap,
|
||||
"region": regionMap,
|
||||
}
|
||||
|
||||
if node.NodeCluster != nil {
|
||||
@@ -263,24 +135,15 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
func (this *UpdateAction) RunPost(params struct {
|
||||
LoginId int64
|
||||
NodeId int64
|
||||
GroupId int64
|
||||
RegionId int64
|
||||
Name string
|
||||
IPAddressesJSON []byte `alias:"ipAddressesJSON"`
|
||||
PrimaryClusterId int64
|
||||
SecondaryClusterIds []byte
|
||||
GrantId int64
|
||||
SshHost string
|
||||
SshPort int
|
||||
MaxCPU int32
|
||||
IsOn bool
|
||||
MaxCacheDiskCapacityJSON []byte
|
||||
MaxCacheMemoryCapacityJSON []byte
|
||||
|
||||
DnsDomainId int64
|
||||
DnsRoutesJSON []byte
|
||||
LoginId int64
|
||||
NodeId int64
|
||||
GroupId int64
|
||||
RegionId int64
|
||||
Name string
|
||||
IPAddressesJSON []byte `alias:"ipAddressesJSON"`
|
||||
PrimaryClusterId int64
|
||||
SecondaryClusterIds []byte
|
||||
IsOn bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -322,56 +185,6 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
this.Fail("请至少输入一个IP地址")
|
||||
}
|
||||
|
||||
dnsRouteCodes := []string{}
|
||||
if len(params.DnsRoutesJSON) > 0 {
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &dnsRouteCodes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// TODO 检查登录授权
|
||||
loginInfo := &pb.NodeLogin{
|
||||
Id: params.LoginId,
|
||||
Name: "SSH",
|
||||
Type: "ssh",
|
||||
Params: maps.Map{
|
||||
"grantId": params.GrantId,
|
||||
"host": params.SshHost,
|
||||
"port": params.SshPort,
|
||||
}.AsJSON(),
|
||||
}
|
||||
|
||||
// 缓存硬盘 & 内存容量
|
||||
var pbMaxCacheDiskCapacity *pb.SizeCapacity
|
||||
if len(params.MaxCacheDiskCapacityJSON) > 0 {
|
||||
var sizeCapacity = &shared.SizeCapacity{}
|
||||
err := json.Unmarshal(params.MaxCacheDiskCapacityJSON, sizeCapacity)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbMaxCacheDiskCapacity = &pb.SizeCapacity{
|
||||
Count: sizeCapacity.Count,
|
||||
Unit: sizeCapacity.Unit,
|
||||
}
|
||||
}
|
||||
|
||||
var pbMaxCacheMemoryCapacity *pb.SizeCapacity
|
||||
if len(params.MaxCacheMemoryCapacityJSON) > 0 {
|
||||
var sizeCapacity = &shared.SizeCapacity{}
|
||||
err := json.Unmarshal(params.MaxCacheMemoryCapacityJSON, sizeCapacity)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
pbMaxCacheMemoryCapacity = &pb.SizeCapacity{
|
||||
Count: sizeCapacity.Count,
|
||||
Unit: sizeCapacity.Unit,
|
||||
}
|
||||
}
|
||||
|
||||
// 保存
|
||||
_, err := this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{
|
||||
NodeId: params.NodeId,
|
||||
@@ -380,13 +193,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
Name: params.Name,
|
||||
NodeClusterId: params.PrimaryClusterId,
|
||||
SecondaryNodeClusterIds: secondaryClusterIds,
|
||||
NodeLogin: loginInfo,
|
||||
MaxCPU: params.MaxCPU,
|
||||
IsOn: params.IsOn,
|
||||
DnsDomainId: params.DnsDomainId,
|
||||
DnsRoutes: dnsRouteCodes,
|
||||
MaxCacheDiskCapacity: pbMaxCacheDiskCapacity,
|
||||
MaxCacheMemoryCapacity: pbMaxCacheMemoryCapacity,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -394,7 +201,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 禁用老的IP地址
|
||||
_, err = this.RPC().NodeIPAddressRPC().DisableAllIPAddressesWithNodeId(this.AdminContext(), &pb.DisableAllIPAddressesWithNodeIdRequest{
|
||||
_, err = this.RPC().NodeIPAddressRPC().DisableAllNodeIPAddressesWithNodeId(this.AdminContext(), &pb.DisableAllNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
|
||||
@@ -85,10 +85,12 @@ func (this *UpdateDNSPopupAction) RunPost(params struct {
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改节点 %d 的DNS设置", params.NodeId)
|
||||
|
||||
routes := []string{}
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
if len(params.DnsRoutesJSON) > 0 {
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
params.Must.
|
||||
@@ -100,7 +102,7 @@ func (this *UpdateDNSPopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 执行修改
|
||||
_, err = this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
_, err := this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
IpAddr: params.IpAddr,
|
||||
DnsDomainId: params.DomainId,
|
||||
|
||||
@@ -123,7 +123,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
@@ -132,7 +132,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
ipAddresses := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddresses = append(ipAddresses, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
|
||||
@@ -46,6 +46,13 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["domainName"] = dnsInfoResp.Domain.Name
|
||||
}
|
||||
|
||||
if len(dnsInfoResp.CnameRecords) == 0 {
|
||||
this.Data["cnameRecords"] = []string{}
|
||||
} else {
|
||||
this.Data["cnameRecords"] = dnsInfoResp.CnameRecords
|
||||
}
|
||||
this.Data["ttl"] = dnsInfoResp.Ttl
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -56,6 +63,8 @@ func (this *IndexAction) RunPost(params struct {
|
||||
DnsName string
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
CnameRecords []string
|
||||
Ttl int32
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -97,6 +106,8 @@ func (this *IndexAction) RunPost(params struct {
|
||||
DnsDomainId: params.DnsDomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
CnameRecords: params.CnameRecords,
|
||||
Ttl: params.Ttl,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -4,9 +4,11 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -21,6 +23,7 @@ func (this *IndexAction) Init() {
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
}) {
|
||||
// 基本信息
|
||||
clusterResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeCluster(this.AdminContext(), &pb.FindEnabledNodeClusterRequest{NodeClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -53,21 +56,42 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["grant"] = grantMap
|
||||
|
||||
this.Data["cluster"] = maps.Map{
|
||||
"id": cluster.Id,
|
||||
"name": cluster.Name,
|
||||
"installDir": cluster.InstallDir,
|
||||
// 时区
|
||||
this.Data["timeZoneGroups"] = nodeconfigs.FindAllTimeZoneGroups()
|
||||
this.Data["timeZoneLocations"] = nodeconfigs.FindAllTimeZoneLocations()
|
||||
|
||||
if len(cluster.TimeZone) == 0 {
|
||||
cluster.TimeZone = nodeconfigs.DefaultTimeZoneLocation
|
||||
}
|
||||
this.Data["timeZoneLocation"] = nodeconfigs.FindTimeZoneLocation(cluster.TimeZone)
|
||||
|
||||
this.Data["cluster"] = maps.Map{
|
||||
"id": cluster.Id,
|
||||
"name": cluster.Name,
|
||||
"installDir": cluster.InstallDir,
|
||||
"timeZone": cluster.TimeZone,
|
||||
"nodeMaxThreads": cluster.NodeMaxThreads,
|
||||
"nodeTCPMaxConnections": cluster.NodeTCPMaxConnections,
|
||||
}
|
||||
|
||||
// 默认值
|
||||
this.Data["defaultNodeMaxThreads"] = nodeconfigs.DefaultMaxThreads
|
||||
this.Data["defaultNodeMaxThreadsMin"] = nodeconfigs.DefaultMaxThreadsMin
|
||||
this.Data["defaultNodeMaxThreadsMax"] = nodeconfigs.DefaultMaxThreadsMax
|
||||
this.Data["defaultNodeTCPMaxConnections"] = nodeconfigs.DefaultTCPMaxConnections
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
// RunPost 保存设置
|
||||
func (this *IndexAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
Name string
|
||||
GrantId int64
|
||||
InstallDir string
|
||||
ClusterId int64
|
||||
Name string
|
||||
GrantId int64
|
||||
InstallDir string
|
||||
TimeZone string
|
||||
NodeMaxThreads int32
|
||||
NodeTCPMaxConnections int32
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -78,11 +102,21 @@ func (this *IndexAction) RunPost(params struct {
|
||||
Field("name", params.Name).
|
||||
Require("请输入集群名称")
|
||||
|
||||
if params.NodeMaxThreads > 0 {
|
||||
params.Must.
|
||||
Field("nodeMaxThreads", params.NodeMaxThreads).
|
||||
Gte(int64(nodeconfigs.DefaultMaxThreadsMin), "单节点最大线程数最小值不能小于"+types.String(nodeconfigs.DefaultMaxThreadsMin)).
|
||||
Lte(int64(nodeconfigs.DefaultMaxThreadsMax), "单节点最大线程数最大值不能大于"+types.String(nodeconfigs.DefaultMaxThreadsMax))
|
||||
}
|
||||
|
||||
_, err := this.RPC().NodeClusterRPC().UpdateNodeCluster(this.AdminContext(), &pb.UpdateNodeClusterRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
Name: params.Name,
|
||||
NodeGrantId: params.GrantId,
|
||||
InstallDir: params.InstallDir,
|
||||
NodeClusterId: params.ClusterId,
|
||||
Name: params.Name,
|
||||
NodeGrantId: params.GrantId,
|
||||
InstallDir: params.InstallDir,
|
||||
TimeZone: params.TimeZone,
|
||||
NodeMaxThreads: params.NodeMaxThreads,
|
||||
NodeTCPMaxConnections: params.NodeTCPMaxConnections,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -45,6 +45,7 @@ func (this *ClusterHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNext
|
||||
action.WriteString("can not find cluster")
|
||||
return
|
||||
}
|
||||
action.Data["currentClusterName"] = cluster.Name
|
||||
|
||||
clusterInfo, err := dao.SharedNodeClusterDAO.FindEnabledNodeClusterConfigInfo(ctx, clusterId)
|
||||
if err != nil {
|
||||
|
||||
@@ -12,7 +12,8 @@ func NewClustersHelper() *ClustersHelper {
|
||||
return &ClustersHelper{}
|
||||
}
|
||||
|
||||
func (this *ClustersHelper) BeforeAction(action *actions.ActionObject) {
|
||||
func (this *ClustersHelper) BeforeAction(actionPtr actions.ActionWrapper) {
|
||||
var action = actionPtr.Object()
|
||||
if action.Request.Method != http.MethodGet {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ func (this *CreateAction) RunPost(params struct {
|
||||
Username string
|
||||
Password string
|
||||
PrivateKey string
|
||||
Passphrase string
|
||||
Description string
|
||||
Su bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -58,7 +60,9 @@ func (this *CreateAction) RunPost(params struct {
|
||||
Username: params.Username,
|
||||
Password: params.Password,
|
||||
PrivateKey: params.PrivateKey,
|
||||
Passphrase: params.Passphrase,
|
||||
Description: params.Description,
|
||||
Su: params.Su,
|
||||
NodeId: 0,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -29,7 +29,9 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
Username string
|
||||
Password string
|
||||
PrivateKey string
|
||||
Passphrase string
|
||||
Description string
|
||||
Su bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -59,7 +61,9 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
Username: params.Username,
|
||||
Password: params.Password,
|
||||
PrivateKey: params.PrivateKey,
|
||||
Passphrase: params.Passphrase,
|
||||
Description: params.Description,
|
||||
Su: params.Su,
|
||||
NodeId: 0,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -72,6 +76,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
"name": params.Name,
|
||||
"method": params.Method,
|
||||
"methodName": grantutils.FindGrantMethodName(params.Method),
|
||||
"username": params.Username,
|
||||
}
|
||||
|
||||
// 创建日志
|
||||
|
||||
@@ -40,6 +40,7 @@ func (this *GrantAction) RunGet(params struct {
|
||||
"username": grant.Username,
|
||||
"password": strings.Repeat("*", len(grant.Password)),
|
||||
"privateKey": grant.PrivateKey,
|
||||
"passphrase": strings.Repeat("*", len(grant.Passphrase)),
|
||||
"description": grant.Description,
|
||||
"su": grant.Su,
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ func init() {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
||||
Helper(clusterutils.NewClustersHelper()).
|
||||
Data("teaMenu", "clusters").
|
||||
Data("teaSubMenu", "grant").
|
||||
Prefix("/clusters/grants").
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
"username": grant.Username,
|
||||
"password": grant.Password,
|
||||
"privateKey": grant.PrivateKey,
|
||||
"passphrase": grant.Passphrase,
|
||||
"description": grant.Description,
|
||||
"su": grant.Su,
|
||||
}
|
||||
@@ -57,7 +58,9 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
Username string
|
||||
Password string
|
||||
PrivateKey string
|
||||
Passphrase string
|
||||
Description string
|
||||
Su bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -93,7 +96,9 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
Username: params.Username,
|
||||
Password: params.Password,
|
||||
PrivateKey: params.PrivateKey,
|
||||
Passphrase: params.Passphrase,
|
||||
Description: params.Description,
|
||||
Su: params.Su,
|
||||
NodeId: 0,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -43,6 +43,8 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
||||
"password": grant.Password,
|
||||
"description": grant.Description,
|
||||
"privateKey": grant.PrivateKey,
|
||||
"passphrase": grant.Passphrase,
|
||||
"su": grant.Su,
|
||||
}
|
||||
|
||||
this.Show()
|
||||
@@ -56,7 +58,9 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Username string
|
||||
Password string
|
||||
PrivateKey string
|
||||
Passphrase string
|
||||
Description string
|
||||
Su bool
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
@@ -91,8 +95,10 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Username: params.Username,
|
||||
Password: params.Password,
|
||||
PrivateKey: params.PrivateKey,
|
||||
Passphrase: params.Passphrase,
|
||||
Description: params.Description,
|
||||
NodeId: params.NodeId,
|
||||
Su: params.Su,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -105,6 +111,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
"name": params.Name,
|
||||
"method": params.Method,
|
||||
"methodName": grantutils.FindGrantMethodName(params.Method),
|
||||
"username": params.Username,
|
||||
}
|
||||
|
||||
this.Success()
|
||||
|
||||
@@ -121,6 +121,10 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
}
|
||||
|
||||
if cluster.TimeZone == nodeconfigs.DefaultTimeZoneLocation {
|
||||
cluster.TimeZone = ""
|
||||
}
|
||||
|
||||
clusterMaps = append(clusterMaps, maps.Map{
|
||||
"id": cluster.Id,
|
||||
"name": cluster.Name,
|
||||
@@ -132,6 +136,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"dnsName": cluster.DnsName,
|
||||
"dnsDomainName": dnsDomainName,
|
||||
"countServers": countServersResp.Count,
|
||||
"timeZone": cluster.TimeZone,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -193,7 +198,7 @@ func (this *IndexAction) searchNodes(keyword string) {
|
||||
}
|
||||
|
||||
// IP
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
@@ -202,7 +207,7 @@ func (this *IndexAction) searchNodes(keyword string) {
|
||||
return
|
||||
}
|
||||
ipAddresses := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddresses = append(ipAddresses, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
|
||||
@@ -12,6 +12,7 @@ func init() {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNode)).
|
||||
Helper(clusterutils.NewClustersHelper()).
|
||||
Data("teaMenu", "clusters").
|
||||
Prefix("/clusters").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/create", new(CreateAction)).
|
||||
|
||||
@@ -2,6 +2,7 @@ package logs
|
||||
|
||||
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"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
@@ -12,6 +13,11 @@ type IndexAction struct {
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
if this.ParamString("type") == "unread" {
|
||||
this.FirstMenu("unread")
|
||||
} else {
|
||||
this.FirstMenu("index")
|
||||
}
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
@@ -19,19 +25,34 @@ func (this *IndexAction) RunGet(params struct {
|
||||
DayTo string
|
||||
Keyword string
|
||||
Level string
|
||||
Type string
|
||||
}) {
|
||||
this.Data["dayFrom"] = params.DayFrom
|
||||
this.Data["dayTo"] = params.DayTo
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["level"] = params.Level
|
||||
this.Data["type"] = params.Type
|
||||
|
||||
// 未读数量
|
||||
countUnreadResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
IsUnread: true,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["countUnreadLogs"] = countUnreadResp.Count
|
||||
|
||||
// 日志数量
|
||||
countResp, err := this.RPC().NodeLogRPC().CountNodeLogs(this.AdminContext(), &pb.CountNodeLogsRequest{
|
||||
NodeId: 0,
|
||||
Role: "node",
|
||||
DayFrom: params.DayFrom,
|
||||
DayTo: params.DayTo,
|
||||
Keyword: params.Keyword,
|
||||
Level: params.Level,
|
||||
NodeId: 0,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
DayFrom: params.DayFrom,
|
||||
DayTo: params.DayTo,
|
||||
Keyword: params.Keyword,
|
||||
Level: params.Level,
|
||||
IsUnread: params.Type == "unread",
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -42,14 +63,15 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
logsResp, err := this.RPC().NodeLogRPC().ListNodeLogs(this.AdminContext(), &pb.ListNodeLogsRequest{
|
||||
NodeId: 0,
|
||||
Role: "node",
|
||||
DayFrom: params.DayFrom,
|
||||
DayTo: params.DayTo,
|
||||
Keyword: params.Keyword,
|
||||
Level: params.Level,
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
NodeId: 0,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
DayFrom: params.DayFrom,
|
||||
DayTo: params.DayTo,
|
||||
Keyword: params.Keyword,
|
||||
Level: params.Level,
|
||||
IsUnread: params.Type == "unread",
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -68,13 +90,29 @@ func (this *IndexAction) RunGet(params struct {
|
||||
continue
|
||||
}
|
||||
|
||||
// 服务信息
|
||||
var serverMap = maps.Map{"id": 0}
|
||||
if log.ServerId > 0 {
|
||||
serverResp, err := this.RPC().ServerRPC().FindEnabledUserServerBasic(this.AdminContext(), &pb.FindEnabledUserServerBasicRequest{ServerId: log.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var server = serverResp.Server
|
||||
if server != nil {
|
||||
serverMap = maps.Map{"id": server.Id, "name": server.Name}
|
||||
}
|
||||
}
|
||||
|
||||
logs = append(logs, maps.Map{
|
||||
"id": log.Id,
|
||||
"tag": log.Tag,
|
||||
"description": log.Description,
|
||||
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", log.CreatedAt),
|
||||
"level": log.Level,
|
||||
"isToday": timeutil.FormatTime("Y-m-d", log.CreatedAt) == timeutil.Format("Y-m-d"),
|
||||
"count": log.Count,
|
||||
"isRead": log.IsRead,
|
||||
"node": maps.Map{
|
||||
"id": node.Id,
|
||||
"cluster": maps.Map{
|
||||
@@ -83,6 +121,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
},
|
||||
"name": node.Name,
|
||||
},
|
||||
"server": serverMap,
|
||||
})
|
||||
}
|
||||
this.Data["logs"] = logs
|
||||
|
||||
@@ -14,6 +14,8 @@ func init() {
|
||||
Data("teaSubMenu", "log").
|
||||
Prefix("/clusters/logs").
|
||||
Get("", new(IndexAction)).
|
||||
Post("/readLogs", new(ReadLogsAction)).
|
||||
Post("/readAllLogs", new(ReadAllLogsAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
24
internal/web/actions/default/clusters/logs/readAllLogs.go
Normal file
24
internal/web/actions/default/clusters/logs/readAllLogs.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type ReadAllLogsAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *ReadAllLogsAction) RunPost(params struct {
|
||||
LogIds []int64
|
||||
}) {
|
||||
_, err := this.RPC().NodeLogRPC().UpdateAllNodeLogsRead(this.AdminContext(), &pb.UpdateAllNodeLogsReadRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
26
internal/web/actions/default/clusters/logs/readLogs.go
Normal file
26
internal/web/actions/default/clusters/logs/readLogs.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type ReadLogsAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *ReadLogsAction) RunPost(params struct {
|
||||
LogIds []int64
|
||||
}) {
|
||||
_, err := this.RPC().NodeLogRPC().UpdateNodeLogsRead(this.AdminContext(), &pb.UpdateNodeLogsReadRequest{
|
||||
NodeLogIds: params.LogIds,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package groups
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type OptionsAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *OptionsAction) RunPost(params struct{}) {
|
||||
resp, err := this.RPC().ReportNodeGroupRPC().FindAllEnabledReportNodeGroups(this.AdminContext(), &pb.FindAllEnabledReportNodeGroupsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
var groupMaps = []maps.Map{}
|
||||
for _, group := range resp.ReportNodeGroups {
|
||||
groupMaps = append(groupMaps, maps.Map{
|
||||
"id": group.Id,
|
||||
"name": group.Name,
|
||||
})
|
||||
}
|
||||
this.Data["groups"] = groupMaps
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -21,6 +21,7 @@ func (this *SelectPopupAction) Init() {
|
||||
func (this *SelectPopupAction) RunGet(params struct {
|
||||
SelectedClusterIds string
|
||||
Keyword string
|
||||
PageSize int64
|
||||
}) {
|
||||
this.Data["keyword"] = params.Keyword
|
||||
|
||||
@@ -36,6 +37,9 @@ func (this *SelectPopupAction) RunGet(params struct {
|
||||
var count = countResp.Count
|
||||
var page = this.NewPage(count)
|
||||
page.Size = 6
|
||||
if params.PageSize > 0 {
|
||||
page.Size = params.PageSize
|
||||
}
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
clustersResp, err := this.RPC().NodeClusterRPC().ListEnabledNodeClusters(this.AdminContext(), &pb.ListEnabledNodeClustersRequest{
|
||||
|
||||
@@ -10,7 +10,9 @@ type CheckAction struct {
|
||||
}
|
||||
|
||||
func (this *CheckAction) RunPost(params struct{}) {
|
||||
resp, err := this.RPC().NodeTaskRPC().ExistsNodeTasks(this.AdminContext(), &pb.ExistsNodeTasksRequest{})
|
||||
resp, err := this.RPC().NodeTaskRPC().ExistsNodeTasks(this.AdminContext(), &pb.ExistsNodeTasksRequest{
|
||||
ExcludeTypes: []string{"ipItemChanged"},
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -40,6 +40,15 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// 版本更新
|
||||
this.Data["currentVersionCode"] = teaconst.Version
|
||||
this.Data["newVersionCode"] = teaconst.NewVersionCode
|
||||
this.Data["newVersionDownloadURL"] = teaconst.NewVersionDownloadURL
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct{}) {
|
||||
// 读取看板数据
|
||||
resp, err := this.RPC().AdminRPC().ComposeAdminDashboard(this.AdminContext(), &pb.ComposeAdminDashboardRequest{
|
||||
ApiVersion: teaconst.APINodeVersion,
|
||||
@@ -50,14 +59,17 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
this.Data["dashboard"] = maps.Map{
|
||||
"defaultClusterId": resp.DefaultNodeClusterId,
|
||||
|
||||
"countServers": resp.CountServers,
|
||||
"countNodeClusters": resp.CountNodeClusters,
|
||||
"countNodes": resp.CountNodes,
|
||||
"countUsers": resp.CountUsers,
|
||||
"countAPINodes": resp.CountAPINodes,
|
||||
"countDBNodes": resp.CountDBNodes,
|
||||
"countUserNodes": resp.CountUserNodes,
|
||||
|
||||
"countServers": resp.CountServers,
|
||||
"countNodeClusters": resp.CountNodeClusters,
|
||||
"countNodes": resp.CountNodes,
|
||||
"countOfflineNodes": resp.CountOfflineNodes,
|
||||
"countUsers": resp.CountUsers,
|
||||
"countAPINodes": resp.CountAPINodes,
|
||||
"countOfflineAPINodes": resp.CountOfflineAPINodes,
|
||||
"countDBNodes": resp.CountDBNodes,
|
||||
"countUserNodes": resp.CountUserNodes,
|
||||
"countOfflineUserNodes": resp.CountOfflineUserNodes,
|
||||
|
||||
"canGoServers": configloaders.AllowModule(this.AdminId(), configloaders.AdminModuleCodeServer),
|
||||
"canGoNodes": configloaders.AllowModule(this.AdminId(), configloaders.AdminModuleCodeNode),
|
||||
@@ -85,8 +97,14 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
statMaps := []maps.Map{}
|
||||
for _, stat := range resp.HourlyTrafficStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"bytes": stat.Bytes,
|
||||
"hour": stat.Hour[8:],
|
||||
"bytes": stat.Bytes,
|
||||
"cachedBytes": stat.CachedBytes,
|
||||
"countRequests": stat.CountRequests,
|
||||
"countCachedRequests": stat.CountCachedRequests,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"attackBytes": stat.AttackBytes,
|
||||
"day": stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
|
||||
"hour": stat.Hour[8:],
|
||||
})
|
||||
}
|
||||
this.Data["hourlyTrafficStats"] = statMaps
|
||||
@@ -97,8 +115,13 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
statMaps := []maps.Map{}
|
||||
for _, stat := range resp.DailyTrafficStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"bytes": stat.Bytes,
|
||||
"day": stat.Day[4:6] + "月" + stat.Day[6:] + "日",
|
||||
"bytes": stat.Bytes,
|
||||
"cachedBytes": stat.CachedBytes,
|
||||
"countRequests": stat.CountRequests,
|
||||
"countCachedRequests": stat.CountCachedRequests,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"attackBytes": stat.AttackBytes,
|
||||
"day": stat.Day[4:6] + "月" + stat.Day[6:] + "日",
|
||||
})
|
||||
}
|
||||
this.Data["dailyTrafficStats"] = statMaps
|
||||
@@ -172,6 +195,20 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// 域名排行
|
||||
{
|
||||
var statMaps = []maps.Map{}
|
||||
for _, stat := range resp.TopDomainStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"serverId": stat.ServerId,
|
||||
"domain": stat.Domain,
|
||||
"countRequests": stat.CountRequests,
|
||||
"bytes": stat.Bytes,
|
||||
})
|
||||
}
|
||||
this.Data["topDomainStats"] = statMaps
|
||||
}
|
||||
|
||||
// 指标
|
||||
{
|
||||
var chartMaps = []maps.Map{}
|
||||
@@ -210,5 +247,5 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
this.Data["metricCharts"] = chartMaps
|
||||
}
|
||||
|
||||
this.Show()
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
)
|
||||
|
||||
type ClusterAction struct {
|
||||
@@ -61,6 +62,12 @@ func (this *ClusterAction) RunGet(params struct {
|
||||
dnsMap["providerTypeName"] = dnsResp.Provider.TypeName
|
||||
}
|
||||
|
||||
if len(dnsResp.CnameRecords) > 0 {
|
||||
dnsMap["cnameRecords"] = dnsResp.CnameRecords
|
||||
} else {
|
||||
dnsMap["cnameRecords"] = []string{}
|
||||
}
|
||||
|
||||
this.Data["dnsInfo"] = dnsMap
|
||||
|
||||
// 节点DNS解析记录
|
||||
@@ -203,5 +210,60 @@ func (this *ClusterAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["issues"] = issueMaps
|
||||
|
||||
// 当前正在执行的任务
|
||||
resp, err := this.RPC().DNSTaskRPC().FindAllDoingDNSTasks(this.AdminContext(), &pb.FindAllDoingDNSTasksRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
taskMaps := []maps.Map{}
|
||||
for _, task := range resp.DnsTasks {
|
||||
var clusterMap maps.Map = nil
|
||||
var nodeMap maps.Map = nil
|
||||
var serverMap maps.Map = nil
|
||||
var domainMap maps.Map = nil
|
||||
|
||||
if task.NodeCluster != nil {
|
||||
clusterMap = maps.Map{
|
||||
"id": task.NodeCluster.Id,
|
||||
"name": task.NodeCluster.Name,
|
||||
}
|
||||
}
|
||||
if task.Node != nil {
|
||||
nodeMap = maps.Map{
|
||||
"id": task.Node.Id,
|
||||
"name": task.Node.Name,
|
||||
}
|
||||
}
|
||||
if task.Server != nil {
|
||||
serverMap = maps.Map{
|
||||
"id": task.Server.Id,
|
||||
"name": task.Server.Name,
|
||||
}
|
||||
}
|
||||
if task.DnsDomain != nil {
|
||||
domainMap = maps.Map{
|
||||
"id": task.DnsDomain.Id,
|
||||
"name": task.DnsDomain.Name,
|
||||
}
|
||||
}
|
||||
|
||||
taskMaps = append(taskMaps, maps.Map{
|
||||
"id": task.Id,
|
||||
"type": task.Type,
|
||||
"isDone": task.IsDone,
|
||||
"isOk": task.IsOk,
|
||||
"error": task.Error,
|
||||
"updatedTime": timeutil.FormatTime("Y-m-d H:i:s", task.UpdatedAt),
|
||||
"cluster": clusterMap,
|
||||
"node": nodeMap,
|
||||
"server": serverMap,
|
||||
"domain": domainMap,
|
||||
})
|
||||
}
|
||||
this.Data["tasks"] = taskMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// 域名列表选项
|
||||
// DomainOptionsAction 域名列表选项
|
||||
type DomainOptionsAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -23,8 +23,8 @@ func (this *DomainOptionsAction) RunPost(params struct {
|
||||
}
|
||||
domainMaps := []maps.Map{}
|
||||
for _, domain := range domainsResp.DnsDomains {
|
||||
// 未开启的先跳过
|
||||
if !domain.IsOn {
|
||||
// 未开启或者已删除的先跳过
|
||||
if !domain.IsOn || domain.IsDeleted {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ func ValidateRecordName(name string) bool {
|
||||
strings.HasSuffix(piece, "-") ||
|
||||
strings.Contains(piece, "--") ||
|
||||
len(piece) > 63 ||
|
||||
!regexp.MustCompile(`^[a-z0-9-]+$`).MatchString(piece) {
|
||||
!regexp.MustCompile(`^[_a-z0-9-]+$`).MatchString(piece) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
27
internal/web/actions/default/dns/domains/recover.go
Normal file
27
internal/web/actions/default/dns/domains/recover.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package domains
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type RecoverAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *RecoverAction) RunPost(params struct {
|
||||
DomainId int64
|
||||
}) {
|
||||
// 记录日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "从DNS服务商中恢复域名 %d", params.DomainId)
|
||||
|
||||
// 执行恢复
|
||||
_, err := this.RPC().DNSDomainRPC().RecoverDNSDomain(this.AdminContext(), &pb.RecoverDNSDomainRequest{DnsDomainId: params.DomainId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -52,7 +52,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
// TODO 检查DomainId
|
||||
|
||||
// 记录日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改管理域名到DNS服务商 %d", params.DomainId)
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改DNS服务商域名 %d", params.DomainId)
|
||||
|
||||
params.Must.
|
||||
Field("name", params.Name).
|
||||
|
||||
@@ -43,6 +43,7 @@ func init() {
|
||||
GetPost("/createPopup", new(domains.CreatePopupAction)).
|
||||
GetPost("/updatePopup", new(domains.UpdatePopupAction)).
|
||||
Post("/delete", new(domains.DeleteAction)).
|
||||
Post("/recover", new(domains.RecoverAction)).
|
||||
Post("/sync", new(domains.SyncAction)).
|
||||
Get("/routesPopup", new(domains.RoutesPopupAction)).
|
||||
GetPost("/selectPopup", new(domains.SelectPopupAction)).
|
||||
|
||||
@@ -85,10 +85,12 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改节点 %d 的DNS设置", params.NodeId)
|
||||
|
||||
routes := []string{}
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
if len(params.DnsRoutesJSON) > 0 {
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
params.Must.
|
||||
@@ -100,7 +102,7 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 执行修改
|
||||
_, err = this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
_, err := this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
IpAddr: params.IpAddr,
|
||||
DnsDomainId: params.DomainId,
|
||||
|
||||
@@ -83,6 +83,7 @@ func (this *ProviderAction) RunGet(params struct {
|
||||
"name": domain.Name,
|
||||
"isOn": domain.IsOn,
|
||||
"isUp": domain.IsUp,
|
||||
"isDeleted": domain.IsDeleted,
|
||||
"dataUpdatedTime": dataUpdatedTime,
|
||||
"countRoutes": len(domain.Routes),
|
||||
"countServerRecords": domain.CountServerRecords,
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// 修改集群的DNS设置
|
||||
// UpdateClusterPopupAction 修改集群的DNS设置
|
||||
type UpdateClusterPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -46,6 +46,14 @@ func (this *UpdateClusterPopupAction) RunGet(params struct {
|
||||
this.Data["providerId"] = 0
|
||||
}
|
||||
|
||||
if len(dnsResp.CnameRecords) == 0 {
|
||||
this.Data["cnameRecords"] = []string{}
|
||||
} else {
|
||||
this.Data["cnameRecords"] = dnsResp.CnameRecords
|
||||
}
|
||||
|
||||
this.Data["ttl"] = dnsResp.Ttl
|
||||
|
||||
// 所有服务商
|
||||
providerTypesResp, err := this.RPC().DNSProviderRPC().FindAllDNSProviderTypes(this.AdminContext(), &pb.FindAllDNSProviderTypesRequest{})
|
||||
if err != nil {
|
||||
@@ -70,6 +78,8 @@ func (this *UpdateClusterPopupAction) RunPost(params struct {
|
||||
DomainId int64
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
CnameRecords []string
|
||||
Ttl int32
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -103,6 +113,8 @@ func (this *UpdateClusterPopupAction) RunPost(params struct {
|
||||
DnsDomainId: params.DomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
CnameRecords: params.CnameRecords,
|
||||
Ttl: params.Ttl,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package bills
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"time"
|
||||
)
|
||||
|
||||
type GenerateAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *GenerateAction) Init() {
|
||||
this.Nav("", "", "generate")
|
||||
}
|
||||
|
||||
func (this *GenerateAction) RunGet(params struct{}) {
|
||||
this.Data["month"] = timeutil.Format("Ym", time.Now().AddDate(0, -1, 0))
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *GenerateAction) RunPost(params struct {
|
||||
Month string
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
defer this.CreateLogInfo("手动生成上个月(" + params.Month + ")账单")
|
||||
|
||||
_, err := this.RPC().UserBillRPC().GenerateAllUserBills(this.AdminContext(), &pb.GenerateAllUserBillsRequest{Month: params.Month})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package bills
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "index")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
PaidFlag int32 `default:"-1"`
|
||||
UserId int64
|
||||
Month string
|
||||
}) {
|
||||
countResp, err := this.RPC().UserBillRPC().CountAllUserBills(this.AdminContext(), &pb.CountAllUserBillsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
page := this.NewPage(countResp.Count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
billsResp, err := this.RPC().UserBillRPC().ListUserBills(this.AdminContext(), &pb.ListUserBillsRequest{
|
||||
PaidFlag: params.PaidFlag,
|
||||
UserId: params.UserId,
|
||||
Month: params.Month,
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
billMaps := []maps.Map{}
|
||||
for _, bill := range billsResp.UserBills {
|
||||
var userMap maps.Map = nil
|
||||
if bill.User != nil {
|
||||
userMap = maps.Map{
|
||||
"id": bill.User.Id,
|
||||
"fullname": bill.User.Fullname,
|
||||
}
|
||||
}
|
||||
billMaps = append(billMaps, maps.Map{
|
||||
"id": bill.Id,
|
||||
"isPaid": bill.IsPaid,
|
||||
"month": bill.Month,
|
||||
"amount": fmt.Sprintf("%.2f", bill.Amount),
|
||||
"typeName": bill.TypeName,
|
||||
"user": userMap,
|
||||
"description": bill.Description,
|
||||
})
|
||||
}
|
||||
this.Data["bills"] = billMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package bills
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeFinance)).
|
||||
Data("teaMenu", "finance").
|
||||
|
||||
// 财务管理
|
||||
Prefix("/finance/bills").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/generate", new(GenerateAction)).
|
||||
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -43,6 +43,12 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
//// 是否新安装
|
||||
if setup.IsNewInstalled() {
|
||||
this.RedirectURL("/setup/confirm")
|
||||
return
|
||||
}
|
||||
|
||||
// 已登录跳转到dashboard
|
||||
if params.Auth.IsUser() {
|
||||
this.RedirectURL("/dashboard")
|
||||
|
||||
@@ -3,6 +3,7 @@ package ipAddresses
|
||||
import (
|
||||
"encoding/json"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
@@ -30,20 +31,28 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
IP string `alias:"ip"`
|
||||
CanAccess bool
|
||||
Name string
|
||||
IsUp bool
|
||||
ThresholdsJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
ip := net.ParseIP(params.IP)
|
||||
if len(ip) == 0 {
|
||||
this.Fail("请输入正确的IP")
|
||||
}
|
||||
|
||||
params.Must.
|
||||
Field("ip", params.IP).
|
||||
Require("请输入IP地址")
|
||||
|
||||
var thresholds = []*nodeconfigs.NodeValueThresholdConfig{}
|
||||
result, err := utils.ExtractIP(params.IP)
|
||||
if err != nil {
|
||||
this.Fail("IP格式错误'" + params.IP + "'")
|
||||
}
|
||||
|
||||
for _, ip := range result {
|
||||
if len(net.ParseIP(ip)) == 0 {
|
||||
this.FailField("ip", "请输入正确的IP")
|
||||
}
|
||||
}
|
||||
|
||||
// 阈值设置
|
||||
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}
|
||||
if teaconst.IsPlus && len(params.ThresholdsJSON) > 0 {
|
||||
_ = json.Unmarshal(params.ThresholdsJSON, &thresholds)
|
||||
}
|
||||
@@ -54,7 +63,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
"ip": params.IP,
|
||||
"id": 0,
|
||||
"isOn": true,
|
||||
"isUp": true,
|
||||
"isUp": params.IsUp,
|
||||
"thresholds": thresholds,
|
||||
}
|
||||
this.Success()
|
||||
|
||||
@@ -2,6 +2,7 @@ package ipaddressutils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -16,14 +17,11 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
|
||||
return err
|
||||
}
|
||||
for _, addr := range addresses {
|
||||
var thresholdsJSON = []byte{}
|
||||
var thresholds = addr.GetSlice("thresholds")
|
||||
if len(thresholds) > 0 {
|
||||
thresholdsJSON, _ = json.Marshal(thresholds)
|
||||
}
|
||||
|
||||
var resultAddrIds = []int64{}
|
||||
addrId := addr.GetInt64("id")
|
||||
if addrId > 0 {
|
||||
resultAddrIds = append(resultAddrIds, addrId)
|
||||
|
||||
var isOn = false
|
||||
if !addr.Has("isOn") { // 兼容老版本
|
||||
isOn = true
|
||||
@@ -37,24 +35,108 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
|
||||
Name: addr.GetString("name"),
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsOn: isOn,
|
||||
ThresholdsJSON: thresholdsJSON,
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
_, err = parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: role,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: addr.GetString("ip"),
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
ThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
var ipStrings = addr.GetString("ip")
|
||||
result, _ := utils.ExtractIP(ipStrings)
|
||||
|
||||
if len(result) == 1 {
|
||||
// 单个创建
|
||||
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: role,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: result[0],
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addrId = createResp.NodeIPAddressId
|
||||
resultAddrIds = append(resultAddrIds, addrId)
|
||||
} else if len(result) > 1 {
|
||||
// 批量创建
|
||||
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddresses(parentAction.AdminContext(), &pb.CreateNodeIPAddressesRequest{
|
||||
NodeId: nodeId,
|
||||
Role: role,
|
||||
Name: addr.GetString("name"),
|
||||
IpList: result,
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
GroupValue: ipStrings,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resultAddrIds = append(resultAddrIds, createResp.NodeIPAddressIds...)
|
||||
}
|
||||
}
|
||||
|
||||
// 保存阈值
|
||||
var thresholds = addr.GetSlice("thresholds")
|
||||
if len(thresholds) > 0 {
|
||||
thresholdsJSON, err := json.Marshal(thresholds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, addrId := range resultAddrIds {
|
||||
_, err = parentAction.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(parentAction.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, addrId := range resultAddrIds {
|
||||
_, err = parentAction.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(parentAction.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: []byte("[]"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitNodeIPAddressThresholds 初始化IP阈值
|
||||
func InitNodeIPAddressThresholds(parentAction *actionutils.ParentAction, addrId int64) ([]*nodeconfigs.IPAddressThresholdConfig, error) {
|
||||
thresholdsResp, err := parentAction.RPC().NodeIPAddressThresholdRPC().FindAllEnabledNodeIPAddressThresholds(parentAction.AdminContext(), &pb.FindAllEnabledNodeIPAddressThresholdsRequest{NodeIPAddressId: addrId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}
|
||||
if len(thresholdsResp.NodeIPAddressThresholds) > 0 {
|
||||
for _, pbThreshold := range thresholdsResp.NodeIPAddressThresholds {
|
||||
var threshold = &nodeconfigs.IPAddressThresholdConfig{
|
||||
Id: pbThreshold.Id,
|
||||
Items: []*nodeconfigs.IPAddressThresholdItemConfig{},
|
||||
Actions: []*nodeconfigs.IPAddressThresholdActionConfig{},
|
||||
}
|
||||
if len(pbThreshold.ItemsJSON) > 0 {
|
||||
err = json.Unmarshal(pbThreshold.ItemsJSON, &threshold.Items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(pbThreshold.ActionsJSON) > 0 {
|
||||
err = json.Unmarshal(pbThreshold.ActionsJSON, &threshold.Actions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
thresholds = append(thresholds, threshold)
|
||||
}
|
||||
}
|
||||
return thresholds, nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package ipAddresses
|
||||
import (
|
||||
"encoding/json"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -34,6 +35,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Name string
|
||||
CanAccess bool
|
||||
IsOn bool
|
||||
IsUp bool
|
||||
ThresholdsJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
@@ -43,7 +45,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Require("请输入IP地址")
|
||||
|
||||
// 获取IP地址信息
|
||||
var isUp = true
|
||||
var isUp = params.IsUp
|
||||
if params.AddressId > 0 {
|
||||
addressResp, err := this.RPC().NodeIPAddressRPC().FindEnabledNodeIPAddress(this.AdminContext(), &pb.FindEnabledNodeIPAddressRequest{NodeIPAddressId: params.AddressId})
|
||||
if err != nil {
|
||||
@@ -54,15 +56,27 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
if address == nil {
|
||||
this.Fail("找不到要修改的地址")
|
||||
}
|
||||
isUp = address.IsUp
|
||||
}
|
||||
|
||||
ip := net.ParseIP(params.IP)
|
||||
if len(ip) == 0 {
|
||||
this.Fail("请输入正确的IP")
|
||||
if params.AddressId > 0 {
|
||||
ip := net.ParseIP(params.IP)
|
||||
if len(ip) == 0 {
|
||||
this.Fail("请输入正确的IP")
|
||||
}
|
||||
} else {
|
||||
result, err := utils.ExtractIP(params.IP)
|
||||
if err != nil {
|
||||
this.Fail("IP格式错误'" + params.IP + "'")
|
||||
}
|
||||
|
||||
for _, ip := range result {
|
||||
if len(net.ParseIP(ip)) == 0 {
|
||||
this.FailField("ip", "请输入正确的IP")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var thresholds = []*nodeconfigs.NodeValueThresholdConfig{}
|
||||
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}
|
||||
if teaconst.IsPlus && len(params.ThresholdsJSON) > 0 {
|
||||
_ = json.Unmarshal(params.ThresholdsJSON, &thresholds)
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(len(nodes))
|
||||
|
||||
for _, node := range nodes {
|
||||
// TODO 检查是否在线
|
||||
|
||||
@@ -68,7 +69,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
|
||||
apiNodeId := node.ConnectedAPINodeIds[0]
|
||||
rpcClient, ok := rpcMap[apiNodeId]
|
||||
if !ok {
|
||||
apiNodeResp, err := defaultRPCClient.APINodeRPC().FindEnabledAPINode(ctx, &pb.FindEnabledAPINodeRequest{NodeId: apiNodeId})
|
||||
apiNodeResp, err := defaultRPCClient.APINodeRPC().FindEnabledAPINode(ctx, &pb.FindEnabledAPINodeRequest{ApiNodeId: apiNodeId})
|
||||
if err != nil {
|
||||
locker.Lock()
|
||||
results = append(results, &MessageResult{
|
||||
@@ -82,7 +83,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
|
||||
continue
|
||||
}
|
||||
|
||||
if apiNodeResp.Node == nil {
|
||||
if apiNodeResp.ApiNode == nil {
|
||||
locker.Lock()
|
||||
results = append(results, &MessageResult{
|
||||
NodeId: node.Id,
|
||||
@@ -94,7 +95,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
|
||||
wg.Done()
|
||||
continue
|
||||
}
|
||||
apiNode := apiNodeResp.Node
|
||||
apiNode := apiNodeResp.ApiNode
|
||||
|
||||
apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
@@ -104,7 +105,7 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
|
||||
},
|
||||
NodeId: apiNode.UniqueId,
|
||||
Secret: apiNode.Secret,
|
||||
})
|
||||
}, false)
|
||||
if err != nil {
|
||||
locker.Lock()
|
||||
results = append(results, &MessageResult{
|
||||
@@ -162,6 +163,11 @@ func SendMessageToCluster(ctx context.Context, clusterId int64, code string, msg
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭RPC
|
||||
for _, rpcClient := range rpcMap {
|
||||
_ = rpcClient.Close()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -243,7 +249,7 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
|
||||
apiNodeId := node.ConnectedAPINodeIds[0]
|
||||
rpcClient, ok := rpcMap[apiNodeId]
|
||||
if !ok {
|
||||
apiNodeResp, err := defaultRPCClient.APINodeRPC().FindEnabledAPINode(ctx, &pb.FindEnabledAPINodeRequest{NodeId: apiNodeId})
|
||||
apiNodeResp, err := defaultRPCClient.APINodeRPC().FindEnabledAPINode(ctx, &pb.FindEnabledAPINodeRequest{ApiNodeId: apiNodeId})
|
||||
if err != nil {
|
||||
locker.Lock()
|
||||
results = append(results, &MessageResult{
|
||||
@@ -257,7 +263,7 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
|
||||
continue
|
||||
}
|
||||
|
||||
if apiNodeResp.Node == nil {
|
||||
if apiNodeResp.ApiNode == nil {
|
||||
locker.Lock()
|
||||
results = append(results, &MessageResult{
|
||||
NodeId: node.Id,
|
||||
@@ -269,7 +275,7 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
|
||||
wg.Done()
|
||||
continue
|
||||
}
|
||||
apiNode := apiNodeResp.Node
|
||||
apiNode := apiNodeResp.ApiNode
|
||||
|
||||
apiRPCClient, err := rpc.NewRPCClient(&configs.APIConfig{
|
||||
RPC: struct {
|
||||
@@ -279,7 +285,7 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
|
||||
},
|
||||
NodeId: apiNode.UniqueId,
|
||||
Secret: apiNode.Secret,
|
||||
})
|
||||
}, false)
|
||||
if err != nil {
|
||||
locker.Lock()
|
||||
results = append(results, &MessageResult{
|
||||
@@ -337,5 +343,10 @@ func SendMessageToNodeIds(ctx context.Context, nodeIds []int64, code string, msg
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭RPC
|
||||
for _, rpcClient := range rpcMap {
|
||||
_ = rpcClient.Close()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/lists"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
RequestId string
|
||||
Keyword string
|
||||
Day string
|
||||
}) {
|
||||
day := strings.ReplaceAll(params.Day, "-", "")
|
||||
if !regexp.MustCompile(`^\d{8}$`).MatchString(day) {
|
||||
day = timeutil.Format("Ymd")
|
||||
}
|
||||
|
||||
this.Data["keyword"] = params.Keyword
|
||||
this.Data["day"] = day[:4] + "-" + day[4:6] + "-" + day[6:]
|
||||
this.Data["path"] = this.Request.URL.Path
|
||||
|
||||
var size = int64(10)
|
||||
|
||||
resp, err := this.RPC().NSAccessLogRPC().ListNSAccessLogs(this.AdminContext(), &pb.ListNSAccessLogsRequest{
|
||||
RequestId: params.RequestId,
|
||||
NsNodeId: 0,
|
||||
NsDomainId: 0,
|
||||
NsRecordId: 0,
|
||||
Size: size,
|
||||
Day: day,
|
||||
Keyword: params.Keyword,
|
||||
Reverse: false,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
ipList := []string{}
|
||||
nodeIds := []int64{}
|
||||
domainIds := []int64{}
|
||||
if len(resp.NsAccessLogs) == 0 {
|
||||
this.Data["accessLogs"] = []interface{}{}
|
||||
} else {
|
||||
this.Data["accessLogs"] = resp.NsAccessLogs
|
||||
for _, accessLog := range resp.NsAccessLogs {
|
||||
// IP
|
||||
if len(accessLog.RemoteAddr) > 0 {
|
||||
// 去掉端口
|
||||
ip, _, err := net.SplitHostPort(accessLog.RemoteAddr)
|
||||
if err == nil {
|
||||
accessLog.RemoteAddr = ip
|
||||
if !lists.ContainsString(ipList, ip) {
|
||||
ipList = append(ipList, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 节点
|
||||
if !lists.ContainsInt64(nodeIds, accessLog.NsNodeId) {
|
||||
nodeIds = append(nodeIds, accessLog.NsNodeId)
|
||||
}
|
||||
|
||||
// 域名
|
||||
if !lists.ContainsInt64(domainIds, accessLog.NsDomainId) {
|
||||
domainIds = append(domainIds, accessLog.NsDomainId)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["hasMore"] = resp.HasMore
|
||||
this.Data["nextRequestId"] = resp.RequestId
|
||||
|
||||
// 上一个requestId
|
||||
this.Data["hasPrev"] = false
|
||||
this.Data["lastRequestId"] = ""
|
||||
if len(params.RequestId) > 0 {
|
||||
this.Data["hasPrev"] = true
|
||||
prevResp, err := this.RPC().NSAccessLogRPC().ListNSAccessLogs(this.AdminContext(), &pb.ListNSAccessLogsRequest{
|
||||
RequestId: params.RequestId,
|
||||
NsNodeId: 0,
|
||||
NsDomainId: 0,
|
||||
NsRecordId: 0,
|
||||
Day: day,
|
||||
Keyword: params.Keyword,
|
||||
Size: size,
|
||||
Reverse: true,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if int64(len(prevResp.NsAccessLogs)) == size {
|
||||
this.Data["lastRequestId"] = prevResp.RequestId
|
||||
}
|
||||
}
|
||||
|
||||
// 根据IP查询区域
|
||||
regionMap := map[string]string{} // ip => region
|
||||
if len(ipList) > 0 {
|
||||
resp, err := this.RPC().IPLibraryRPC().LookupIPRegions(this.AdminContext(), &pb.LookupIPRegionsRequest{IpList: ipList})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if resp.IpRegionMap != nil {
|
||||
for ip, region := range resp.IpRegionMap {
|
||||
if len(region.Isp) > 0 {
|
||||
region.Summary += " | " + region.Isp
|
||||
}
|
||||
regionMap[ip] = region.Summary
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["regions"] = regionMap
|
||||
|
||||
// 节点信息
|
||||
nodeMap := map[int64]interface{}{} // node id => { ... }
|
||||
for _, nodeId := range nodeIds {
|
||||
nodeResp, err := this.RPC().NSNodeRPC().FindEnabledNSNode(this.AdminContext(), &pb.FindEnabledNSNodeRequest{NsNodeId: nodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.NsNode
|
||||
if node != nil {
|
||||
nodeMap[node.Id] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"cluster": maps.Map{
|
||||
"id": node.NsCluster.Id,
|
||||
"name": node.NsCluster.Name,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["nodes"] = nodeMap
|
||||
|
||||
// 域名信息
|
||||
domainMap := map[int64]interface{}{} // domain id => { ... }
|
||||
for _, domainId := range domainIds {
|
||||
domainResp, err := this.RPC().NSDomainRPC().FindEnabledNSDomain(this.AdminContext(), &pb.FindEnabledNSDomainRequest{NsDomainId: domainId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
domain := domainResp.NsDomain
|
||||
if domain != nil {
|
||||
domainMap[domain.Id] = maps.Map{
|
||||
"id": domain.Id,
|
||||
"name": domain.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["domains"] = domainMap
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNS)).
|
||||
Data("teaMenu", "ns").
|
||||
Data("teaSubMenu", "accessLog").
|
||||
Prefix("/ns/clusters/accessLogs").
|
||||
Get("", new(IndexAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"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"
|
||||
)
|
||||
|
||||
// CreateNodeAction 创建节点
|
||||
type CreateNodeAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *CreateNodeAction) Init() {
|
||||
this.Nav("", "node", "create")
|
||||
this.SecondMenu("nodes")
|
||||
}
|
||||
|
||||
func (this *CreateNodeAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
}) {
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *CreateNodeAction) RunPost(params struct {
|
||||
Name string
|
||||
IpAddressesJSON []byte
|
||||
ClusterId int64
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
params.Must.
|
||||
Field("name", params.Name).
|
||||
Require("请输入节点名称")
|
||||
|
||||
if len(params.IpAddressesJSON) == 0 {
|
||||
this.Fail("请至少添加一个IP地址")
|
||||
}
|
||||
|
||||
// 检查cluster
|
||||
if params.ClusterId <= 0 {
|
||||
this.Fail("请选择所在集群")
|
||||
}
|
||||
clusterResp, err := this.RPC().NSClusterRPC().FindEnabledNSCluster(this.AdminContext(), &pb.FindEnabledNSClusterRequest{NsClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if clusterResp.NsCluster == nil {
|
||||
this.Fail("选择的集群不存在")
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddresses := []maps.Map{}
|
||||
if len(params.IpAddressesJSON) > 0 {
|
||||
err := json.Unmarshal(params.IpAddressesJSON, &ipAddresses)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(ipAddresses) == 0 {
|
||||
this.Fail("请至少输入一个IP地址")
|
||||
}
|
||||
|
||||
// 保存
|
||||
createResp, err := this.RPC().NSNodeRPC().CreateNSNode(this.AdminContext(), &pb.CreateNSNodeRequest{
|
||||
Name: params.Name,
|
||||
NodeClusterId: params.ClusterId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
nodeId := createResp.NsNodeId
|
||||
|
||||
// IP地址
|
||||
for _, address := range ipAddresses {
|
||||
addressId := address.GetInt64("id")
|
||||
if addressId > 0 {
|
||||
_, err = this.RPC().NodeIPAddressRPC().UpdateNodeIPAddressNodeId(this.AdminContext(), &pb.UpdateNodeIPAddressNodeIdRequest{
|
||||
NodeIPAddressId: addressId,
|
||||
NodeId: nodeId,
|
||||
})
|
||||
} else {
|
||||
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
Name: address.GetString("name"),
|
||||
Ip: address.GetString("ip"),
|
||||
CanAccess: address.GetBool("canAccess"),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 创建日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "创建域名服务节点 %d", nodeId)
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type DeleteAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *DeleteAction) Init() {
|
||||
this.Nav("", "delete", "index")
|
||||
this.SecondMenu("nodes")
|
||||
}
|
||||
|
||||
func (this *DeleteAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *DeleteAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
}) {
|
||||
// 创建日志
|
||||
defer this.CreateLog(oplogs.LevelInfo, "删除域名服务集群 %d", params.ClusterId)
|
||||
|
||||
// TODO 如果有用户在使用此集群,就不能删除
|
||||
|
||||
// 删除
|
||||
_, err := this.RPC().NSClusterRPC().DeleteNSCluster(this.AdminContext(), &pb.DeleteNSCluster{NsClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
type DeleteNodeAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *DeleteNodeAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
defer this.CreateLogInfo("删除域名服务节点 %d", params.NodeId)
|
||||
|
||||
_, err := this.RPC().NSNodeRPC().DeleteNSNode(this.AdminContext(), &pb.DeleteNSNodeRequest{NsNodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "node", "index")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
InstalledState int
|
||||
ActiveState int
|
||||
Keyword string
|
||||
}) {
|
||||
this.Data["installState"] = params.InstalledState
|
||||
this.Data["activeState"] = params.ActiveState
|
||||
this.Data["keyword"] = params.Keyword
|
||||
|
||||
countAllResp, err := this.RPC().NSNodeRPC().CountAllEnabledNSNodesMatch(this.AdminContext(), &pb.CountAllEnabledNSNodesMatchRequest{
|
||||
NsClusterId: params.ClusterId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["countAll"] = countAllResp.Count
|
||||
|
||||
countResp, err := this.RPC().NSNodeRPC().CountAllEnabledNSNodesMatch(this.AdminContext(), &pb.CountAllEnabledNSNodesMatchRequest{
|
||||
NsClusterId: params.ClusterId,
|
||||
InstallState: types.Int32(params.InstalledState),
|
||||
ActiveState: types.Int32(params.ActiveState),
|
||||
Keyword: params.Keyword,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
page := this.NewPage(countResp.Count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
nodesResp, err := this.RPC().NSNodeRPC().ListEnabledNSNodesMatch(this.AdminContext(), &pb.ListEnabledNSNodesMatchRequest{
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
NsClusterId: params.ClusterId,
|
||||
InstallState: types.Int32(params.InstalledState),
|
||||
ActiveState: types.Int32(params.ActiveState),
|
||||
Keyword: params.Keyword,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
nodeMaps := []maps.Map{}
|
||||
for _, node := range nodesResp.NsNodes {
|
||||
// 状态
|
||||
status := &nodeconfigs.NodeStatus{}
|
||||
if len(node.StatusJSON) > 0 {
|
||||
err = json.Unmarshal(node.StatusJSON, &status)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
continue
|
||||
}
|
||||
status.IsActive = status.IsActive && time.Now().Unix()-status.UpdatedAt <= 60 // N秒之内认为活跃
|
||||
}
|
||||
|
||||
// IP
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
ipAddresses := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
ipAddresses = append(ipAddresses, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
"ip": addr.Ip,
|
||||
"canAccess": addr.CanAccess,
|
||||
"isOn": addr.IsOn,
|
||||
"isUp": addr.IsUp,
|
||||
})
|
||||
}
|
||||
|
||||
nodeMaps = append(nodeMaps, maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"isInstalled": node.IsInstalled,
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
"installStatus": maps.Map{
|
||||
"isRunning": node.InstallStatus.IsRunning,
|
||||
"isFinished": node.InstallStatus.IsFinished,
|
||||
"isOk": node.InstallStatus.IsOk,
|
||||
"error": node.InstallStatus.Error,
|
||||
},
|
||||
"status": maps.Map{
|
||||
"isActive": node.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),
|
||||
},
|
||||
"ipAddresses": ipAddresses,
|
||||
})
|
||||
}
|
||||
this.Data["nodes"] = nodeMaps
|
||||
|
||||
// 记录最近访问
|
||||
_, err = this.RPC().LatestItemRPC().IncreaseLatestItem(this.AdminContext(), &pb.IncreaseLatestItemRequest{
|
||||
ItemType: "nsCluster",
|
||||
ItemId: params.ClusterId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package cluster
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters/cluster/node"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/ns/clusters/clusterutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeNS)).
|
||||
Helper(new(clusterutils.ClusterHelper)).
|
||||
Data("teaMenu", "ns").
|
||||
Data("teaSubMenu", "cluster").
|
||||
Prefix("/ns/clusters/cluster").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/delete", new(DeleteAction)).
|
||||
GetPost("/createNode", new(CreateNodeAction)).
|
||||
Post("/deleteNode", new(DeleteNodeAction)).
|
||||
Get("/upgradeRemote", new(UpgradeRemoteAction)).
|
||||
GetPost("/updateNodeSSH", new(UpdateNodeSSHAction)).
|
||||
|
||||
// 节点相关
|
||||
Prefix("/ns/clusters/cluster/node").
|
||||
Get("", new(node.IndexAction)).
|
||||
Get("/logs", new(node.LogsAction)).
|
||||
GetPost("/update", new(node.UpdateAction)).
|
||||
GetPost("/install", new(node.InstallAction)).
|
||||
Post("/status", new(node.StatusAction)).
|
||||
Post("/updateInstallStatus", new(node.UpdateInstallStatusAction)).
|
||||
Post("/start", new(node.StartAction)).
|
||||
Post("/stop", new(node.StopAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
})
|
||||
@@ -65,7 +65,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
ipAddressMaps := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddressMaps = append(ipAddressMaps, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user