Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f4c6f4c57d | ||
|
|
4df60c6955 | ||
|
|
0501e120f6 | ||
|
|
cfa425bb33 | ||
|
|
0613b0022d | ||
|
|
740d15bf79 | ||
|
|
7ace5d04fa | ||
|
|
a38d7bb51d | ||
|
|
61e16f96c5 | ||
|
|
61127b3435 | ||
|
|
8805dffe85 | ||
|
|
aeb7c52565 | ||
|
|
877b4cd666 | ||
|
|
f75847d3d7 | ||
|
|
eee3225f3a | ||
|
|
aa9eb533ad | ||
|
|
cf9bbb5ff4 | ||
|
|
65dee23137 | ||
|
|
feb4659cab | ||
|
|
bc7791efd2 | ||
|
|
6e6ec3256f | ||
|
|
ce66f72cf9 | ||
|
|
0ed7436176 | ||
|
|
2aabe1bd61 | ||
|
|
db5e94d0de | ||
|
|
3eecdc2b3f | ||
|
|
b2740e5f3c | ||
|
|
c3fa4cbbee | ||
|
|
a9da084711 | ||
|
|
f30969e946 | ||
|
|
e0e2b8c3c2 | ||
|
|
3782c0dcaf | ||
|
|
0331db2c12 | ||
|
|
1749247aeb | ||
|
|
eaba7abd35 | ||
|
|
f5ca66d924 | ||
|
|
d5e7b22fc6 | ||
|
|
5122d48dd8 | ||
|
|
3614ef381e | ||
|
|
8475674eb7 | ||
|
|
25e7f8a912 | ||
|
|
5c7652f047 | ||
|
|
890616f52a | ||
|
|
c92ec996e0 | ||
|
|
7fcd4398ea | ||
|
|
7faba40a1c | ||
|
|
66b4c88c24 | ||
|
|
f3c90bbf59 | ||
|
|
8ef5dfb8f8 | ||
|
|
d38f611d66 | ||
|
|
d9a7002906 | ||
|
|
d9188f5228 | ||
|
|
eb3e2883e2 | ||
|
|
83ba5ebc8a | ||
|
|
6d7d3c5e85 | ||
|
|
194f3290bc | ||
|
|
dc5c79711d | ||
|
|
d88989fb85 | ||
|
|
0373d03fb2 | ||
|
|
140f9809a0 | ||
|
|
f647a5f8e6 | ||
|
|
506c87dbd8 | ||
|
|
8b5d513c6a | ||
|
|
6c718c4f38 | ||
|
|
5a2ab8a7ee | ||
|
|
0ea0c9ad8c | ||
|
|
7d4d8c46b8 | ||
|
|
a4636ed774 | ||
|
|
bb48e0912d | ||
|
|
a575d1a6e0 | ||
|
|
420d1ca8ff | ||
|
|
29554ec7ec | ||
|
|
9a8c0e7118 | ||
|
|
800af7ce4e | ||
|
|
78134a0e8b | ||
|
|
bad910b686 | ||
|
|
a7d1bd7487 | ||
|
|
20a10ac6b8 | ||
|
|
3a395e66c0 | ||
|
|
4e5cc0b642 | ||
|
|
fe2872bbb3 |
@@ -22,14 +22,15 @@ jobs:
|
|||||||
uses: crazy-max/ghaction-xgo@v2
|
uses: crazy-max/ghaction-xgo@v2
|
||||||
with:
|
with:
|
||||||
xgo_version: latest
|
xgo_version: latest
|
||||||
go_version: 1.21
|
go_version: 1.20.x
|
||||||
dest: dist
|
dest: dist
|
||||||
pkg: cmd/dashboard
|
pkg: cmd/dashboard
|
||||||
prefix: dashboard
|
prefix: dashboard
|
||||||
targets: linux/amd64,linux/arm64,linux/arm-7,linux/s390x,linux/riscv64 # linux/386,
|
targets: linux/amd64,linux/arm64,linux/arm-7,linux/s390x,linux/riscv64,windows/amd64,windows/386,windows/arm64 # linux/386,
|
||||||
v: true
|
v: true
|
||||||
x: false
|
x: false
|
||||||
race: false
|
race: false
|
||||||
|
tags: timetzdata
|
||||||
ldflags: -s -w --extldflags '-static -fpic' -X github.com/naiba/nezha/service/singleton.Version=${{ steps.extract_branch.outputs.tag }}
|
ldflags: -s -w --extldflags '-static -fpic' -X github.com/naiba/nezha/service/singleton.Version=${{ steps.extract_branch.outputs.tag }}
|
||||||
buildmode: default
|
buildmode: default
|
||||||
|
|
||||||
|
|||||||
@@ -25,14 +25,15 @@ jobs:
|
|||||||
uses: crazy-max/ghaction-xgo@v2
|
uses: crazy-max/ghaction-xgo@v2
|
||||||
with:
|
with:
|
||||||
xgo_version: latest
|
xgo_version: latest
|
||||||
go_version: 1.21
|
go_version: 1.20.x
|
||||||
dest: dist
|
dest: dist
|
||||||
pkg: cmd/dashboard
|
pkg: cmd/dashboard
|
||||||
prefix: dashboard
|
prefix: dashboard
|
||||||
targets: linux/amd64,linux/arm64,linux/arm-7,linux/s390x,linux/riscv64 # linux/386,
|
targets: linux/amd64,linux/arm64,linux/arm-7,linux/s390x,linux/riscv64,windows/amd64,windows/386,windows/arm64 # linux/386,
|
||||||
v: true
|
v: true
|
||||||
x: false
|
x: false
|
||||||
race: false
|
race: false
|
||||||
|
tags: timetzdata
|
||||||
ldflags: -s -w --extldflags '-static -fpic' -X github.com/naiba/nezha/service/singleton.Version=test
|
ldflags: -s -w --extldflags '-static -fpic' -X github.com/naiba/nezha/service/singleton.Version=test
|
||||||
buildmode: default
|
buildmode: default
|
||||||
|
|
||||||
|
|||||||
@@ -32,13 +32,14 @@ jobs:
|
|||||||
uses: crazy-max/ghaction-xgo@v2
|
uses: crazy-max/ghaction-xgo@v2
|
||||||
with:
|
with:
|
||||||
xgo_version: latest
|
xgo_version: latest
|
||||||
go_version: 1.21
|
go_version: 1.20.x
|
||||||
dest: dist
|
dest: dist
|
||||||
pkg: cmd/dashboard
|
pkg: cmd/dashboard
|
||||||
prefix: dashboard
|
prefix: dashboard
|
||||||
targets: linux/amd64,linux/arm64,linux/arm-7,linux/s390x,linux/riscv64 # linux/386,
|
targets: linux/amd64,linux/arm64,linux/arm-7,linux/s390x,linux/riscv64,windows/amd64,windows/386,windows/arm64 # linux/386,
|
||||||
v: true
|
v: true
|
||||||
x: false
|
x: false
|
||||||
race: false
|
race: false
|
||||||
|
tags: timetzdata
|
||||||
ldflags: -s -w --extldflags '-static -fpic' -X github.com/naiba/nezha/service/singleton.Version=test
|
ldflags: -s -w --extldflags '-static -fpic' -X github.com/naiba/nezha/service/singleton.Version=test
|
||||||
buildmode: default
|
buildmode: default
|
||||||
|
|||||||
@@ -4,13 +4,15 @@
|
|||||||
<br>
|
<br>
|
||||||
<small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small>
|
<small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small>
|
||||||
<br><br>
|
<br><br>
|
||||||
<img alt="GitHub release (with filter)" src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&style=for-the-badge&logo=github&label=Dashboard"> <img src="https://img.shields.io/github/v/release/nezhahq/agent?color=brightgreen&label=Agent&style=for-the-badge&logo=github"> <img src="https://img.shields.io/github/actions/workflow/status/nezhahq/agent/agent.yml?label=Agent%20CI&logo=github&style=for-the-badge"> <img src="https://img.shields.io/badge/Installer-v0.15.9-brightgreen?style=for-the-badge&logo=linux">
|
<img alt="GitHub release (with filter)" src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&style=for-the-badge&logo=github&label=Dashboard"> <img src="https://img.shields.io/github/v/release/nezhahq/agent?color=brightgreen&label=Agent&style=for-the-badge&logo=github"> <img src="https://img.shields.io/github/actions/workflow/status/nezhahq/agent/agent.yml?label=Agent%20CI&logo=github&style=for-the-badge"> <img src="https://img.shields.io/badge/Installer-v0.17.0-brightgreen?style=for-the-badge&logo=linux">
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<p>:trollface: <b>Nezha Monitoring: Self-hostable, lightweight, servers and websites monitoring and O&M tool.</b></p>
|
<p>:trollface: <b>Nezha Monitoring: Self-hostable, lightweight, servers and websites monitoring and O&M tool.</b></p>
|
||||||
<p>Supports <b>monitoring</b> system status, HTTP (SSL certificate change, upcoming expiration, expired), TCP, Ping and supports <b>push alerts</b>, run scheduled tasks and <b>web terminal</b>.</p>
|
<p>Supports <b>monitoring</b> system status, HTTP (SSL certificate change, upcoming expiration, expired), TCP, Ping and supports <b>push alerts</b>, run scheduled tasks and <b>web terminal</b>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
\>> Telegram Channel: [哪吒监控(中文通知频道)](https://t.me/nezhanews)
|
||||||
|
|
||||||
\>> Telegram Group: [Nezha Monitoring Global (English Only)](https://t.me/nezhamonitoring_global), [哪吒监控(中文群组)](https://t.me/nezhamonitoring)
|
\>> Telegram Group: [Nezha Monitoring Global (English Only)](https://t.me/nezhamonitoring_global), [哪吒监控(中文群组)](https://t.me/nezhamonitoring)
|
||||||
|
|
||||||
\>> [Use Cases | 我们的用户](https://www.google.com/search?q=%22powered+by+Nezha+Monitoring%22+OR+%22powered+by+%E5%93%AA%E5%90%92%E7%9B%91%E6%8E%A7%22) (Google)
|
\>> [Use Cases | 我们的用户](https://www.google.com/search?q=%22powered+by+Nezha+Monitoring%22+OR+%22powered+by+%E5%93%AA%E5%90%92%E7%9B%91%E6%8E%A7%22) (Google)
|
||||||
@@ -42,15 +44,16 @@ You can change the dashboard language in the settings page (`/setting`) after th
|
|||||||
<a href="https://github.com/AkkiaS7" title="Akkia"><img src="https://avatars.githubusercontent.com/u/68485070?v=4" width="50;" alt="Akkia"/></a>
|
<a href="https://github.com/AkkiaS7" title="Akkia"><img src="https://avatars.githubusercontent.com/u/68485070?v=4" width="50;" alt="Akkia"/></a>
|
||||||
<a href="https://github.com/Erope" title="卖女孩的小火柴"><img src="https://avatars.githubusercontent.com/u/44471469?v=4" width="50;" alt="卖女孩的小火柴"/></a>
|
<a href="https://github.com/Erope" title="卖女孩的小火柴"><img src="https://avatars.githubusercontent.com/u/44471469?v=4" width="50;" alt="卖女孩的小火柴"/></a>
|
||||||
<a href="https://github.com/dysf888" title="黑歌"><img src="https://avatars.githubusercontent.com/u/47450409?v=4" width="50;" alt="黑歌"/></a>
|
<a href="https://github.com/dysf888" title="黑歌"><img src="https://avatars.githubusercontent.com/u/47450409?v=4" width="50;" alt="黑歌"/></a>
|
||||||
|
<a href="https://github.com/uubulb" title="UUBulb"><img src="https://avatars.githubusercontent.com/u/35923940?v=4" width="50;" alt="UUBulb"/></a>
|
||||||
|
<a href="https://github.com/xykt" title="xykt"><img src="https://avatars.githubusercontent.com/u/152045469?v=4" width="50;" alt="xykt"/></a>
|
||||||
|
<a href="https://github.com/nap0o" title="nap0o"><img src="https://avatars.githubusercontent.com/u/144927971?v=4" width="50;" alt="nap0o"/></a>
|
||||||
<a href="https://github.com/MikoyChinese" title="MikoyChinese"><img src="https://avatars.githubusercontent.com/u/22676744?v=4" width="50;" alt="MikoyChinese"/></a>
|
<a href="https://github.com/MikoyChinese" title="MikoyChinese"><img src="https://avatars.githubusercontent.com/u/22676744?v=4" width="50;" alt="MikoyChinese"/></a>
|
||||||
<a href="https://github.com/JackieSung4ev" title="JackieSung4ev"><img src="https://avatars.githubusercontent.com/u/24974735?v=4" width="50;" alt="JackieSung4ev"/></a>
|
<a href="https://github.com/JackieSung4ev" title="JackieSung4ev"><img src="https://avatars.githubusercontent.com/u/24974735?v=4" width="50;" alt="JackieSung4ev"/></a>
|
||||||
<a href="https://github.com/lemoeo" title="Lemoe"><img src="https://avatars.githubusercontent.com/u/18618627?v=4" width="50;" alt="Lemoe"/></a>
|
|
||||||
<a href="https://github.com/cantoblanco" title="Kris"><img src="https://avatars.githubusercontent.com/u/116849421?v=4" width="50;" alt="Kris"/></a>
|
<a href="https://github.com/cantoblanco" title="Kris"><img src="https://avatars.githubusercontent.com/u/116849421?v=4" width="50;" alt="Kris"/></a>
|
||||||
<a href="https://github.com/nap0o" title="nap0o"><img src="https://avatars.githubusercontent.com/u/144927971?v=4" width="50;" alt="nap0o"/></a>
|
<a href="https://github.com/lemoeo" title="Lemoe"><img src="https://avatars.githubusercontent.com/u/18618627?v=4" width="50;" alt="Lemoe"/></a>
|
||||||
<a href="https://github.com/spiritLHLS" title="spiritlhl"><img src="https://avatars.githubusercontent.com/u/103393591?v=4" width="50;" alt="spiritlhl"/></a>
|
<a href="https://github.com/spiritLHLS" title="spiritlhl"><img src="https://avatars.githubusercontent.com/u/103393591?v=4" width="50;" alt="spiritlhl"/></a>
|
||||||
<a href="https://github.com/liuyanxi975" title="刘颜溪"><img src="https://avatars.githubusercontent.com/u/24417037?v=4" width="50;" alt="刘颜溪"/></a>
|
<a href="https://github.com/liuyanxi975" title="刘颜溪"><img src="https://avatars.githubusercontent.com/u/24417037?v=4" width="50;" alt="刘颜溪"/></a>
|
||||||
<a href="https://github.com/CosmosZ-code" title="CosmosZ-code"><img src="https://avatars.githubusercontent.com/u/81398224?v=4" width="50;" alt="CosmosZ-code"/></a>
|
<a href="https://github.com/CosmosZ-code" title="CosmosZ-code"><img src="https://avatars.githubusercontent.com/u/81398224?v=4" width="50;" alt="CosmosZ-code"/></a>
|
||||||
<a href="https://github.com/uubulb" title="UUBulb"><img src="https://avatars.githubusercontent.com/u/35923940?v=4" width="50;" alt="UUBulb"/></a>
|
|
||||||
<a href="https://github.com/lvgj-stack" title="Ko no dio"><img src="https://avatars.githubusercontent.com/u/38449861?v=4" width="50;" alt="Ko no dio"/></a>
|
<a href="https://github.com/lvgj-stack" title="Ko no dio"><img src="https://avatars.githubusercontent.com/u/38449861?v=4" width="50;" alt="Ko no dio"/></a>
|
||||||
<a href="https://github.com/hhhkkk520" title="Kris"><img src="https://avatars.githubusercontent.com/u/52115472?v=4" width="50;" alt="Kris"/></a>
|
<a href="https://github.com/hhhkkk520" title="Kris"><img src="https://avatars.githubusercontent.com/u/52115472?v=4" width="50;" alt="Kris"/></a>
|
||||||
<a href="https://github.com/1ridic" title="1ridic"><img src="https://avatars.githubusercontent.com/u/88495501?v=4" width="50;" alt="1ridic"/></a>
|
<a href="https://github.com/1ridic" title="1ridic"><img src="https://avatars.githubusercontent.com/u/88495501?v=4" width="50;" alt="1ridic"/></a>
|
||||||
@@ -59,27 +62,32 @@ You can change the dashboard language in the settings page (`/setting`) after th
|
|||||||
<a href="https://github.com/iilemon" title="Sean"><img src="https://avatars.githubusercontent.com/u/33201711?v=4" width="50;" alt="Sean"/></a>
|
<a href="https://github.com/iilemon" title="Sean"><img src="https://avatars.githubusercontent.com/u/33201711?v=4" width="50;" alt="Sean"/></a>
|
||||||
<a href="https://github.com/fscarmen" title="fscarmen"><img src="https://avatars.githubusercontent.com/u/62703343?v=4" width="50;" alt="fscarmen"/></a>
|
<a href="https://github.com/fscarmen" title="fscarmen"><img src="https://avatars.githubusercontent.com/u/62703343?v=4" width="50;" alt="fscarmen"/></a>
|
||||||
<a href="https://github.com/ch8o" title="no-name-now"><img src="https://avatars.githubusercontent.com/u/9103372?v=4" width="50;" alt="no-name-now"/></a>
|
<a href="https://github.com/ch8o" title="no-name-now"><img src="https://avatars.githubusercontent.com/u/9103372?v=4" width="50;" alt="no-name-now"/></a>
|
||||||
|
<a href="https://github.com/HsukqiLee" title="HsukqiLee"><img src="https://avatars.githubusercontent.com/u/79034142?v=4" width="50;" alt="HsukqiLee"/></a>
|
||||||
<a href="https://github.com/DarcJC" title="Darc Z."><img src="https://avatars.githubusercontent.com/u/53445798?v=4" width="50;" alt="Darc Z."/></a>
|
<a href="https://github.com/DarcJC" title="Darc Z."><img src="https://avatars.githubusercontent.com/u/53445798?v=4" width="50;" alt="Darc Z."/></a>
|
||||||
<a href="https://github.com/Creling" title="Creling"><img src="https://avatars.githubusercontent.com/u/43109504?v=4" width="50;" alt="Creling"/></a>
|
<a href="https://github.com/Creling" title="Creling"><img src="https://avatars.githubusercontent.com/u/43109504?v=4" width="50;" alt="Creling"/></a>
|
||||||
<a href="https://github.com/coreff" title="Core F"><img src="https://avatars.githubusercontent.com/u/38347122?v=4" width="50;" alt="Core F"/></a>
|
<a href="https://github.com/coreff" title="Core F"><img src="https://avatars.githubusercontent.com/u/38347122?v=4" width="50;" alt="Core F"/></a>
|
||||||
<a href="https://github.com/colour93" title="玖叁"><img src="https://avatars.githubusercontent.com/u/64313711?v=4" width="50;" alt="玖叁"/></a>
|
<a href="https://github.com/colour93" title="玖叁"><img src="https://avatars.githubusercontent.com/u/64313711?v=4" width="50;" alt="玖叁"/></a>
|
||||||
<a href="https://github.com/arkylin" title="凌"><img src="https://avatars.githubusercontent.com/u/35104502?v=4" width="50;" alt="凌"/></a>
|
<a href="https://github.com/arkylin" title="凌"><img src="https://avatars.githubusercontent.com/u/35104502?v=4" width="50;" alt="凌"/></a>
|
||||||
|
<a href="https://github.com/zhucaidan" title="zhucaidan"><img src="https://avatars.githubusercontent.com/u/47970938?v=4" width="50;" alt="zhucaidan"/></a>
|
||||||
<a href="https://github.com/ysicing" title="缘生"><img src="https://avatars.githubusercontent.com/u/8605565?v=4" width="50;" alt="缘生"/></a>
|
<a href="https://github.com/ysicing" title="缘生"><img src="https://avatars.githubusercontent.com/u/8605565?v=4" width="50;" alt="缘生"/></a>
|
||||||
<a href="https://github.com/xykt" title="xykt"><img src="https://avatars.githubusercontent.com/u/152045469?v=4" width="50;" alt="xykt"/></a>
|
|
||||||
<a href="https://github.com/unclezs" title="unclezs"><img src="https://avatars.githubusercontent.com/u/42318775?v=4" width="50;" alt="unclezs"/></a>
|
<a href="https://github.com/unclezs" title="unclezs"><img src="https://avatars.githubusercontent.com/u/42318775?v=4" width="50;" alt="unclezs"/></a>
|
||||||
|
<a href="https://github.com/lvyaoting" title="lvyaoting"><img src="https://avatars.githubusercontent.com/u/166296299?v=4" width="50;" alt="lvyaoting"/></a>
|
||||||
<a href="https://github.com/yuanweize" title="I"><img src="https://avatars.githubusercontent.com/u/30067203?v=4" width="50;" alt="I"/></a>
|
<a href="https://github.com/yuanweize" title="I"><img src="https://avatars.githubusercontent.com/u/30067203?v=4" width="50;" alt="I"/></a>
|
||||||
<a href="https://github.com/guoyongchang" title="guoyongchang"><img src="https://avatars.githubusercontent.com/u/10484506?v=4" width="50;" alt="guoyongchang"/></a>
|
<a href="https://github.com/guoyongchang" title="guoyongchang"><img src="https://avatars.githubusercontent.com/u/10484506?v=4" width="50;" alt="guoyongchang"/></a>
|
||||||
|
<a href="https://github.com/eya46" title="eya46"><img src="https://avatars.githubusercontent.com/u/61458340?v=4" width="50;" alt="eya46"/></a>
|
||||||
<a href="https://github.com/acgpiano" title="Acgpiano"><img src="https://avatars.githubusercontent.com/u/15900800?v=4" width="50;" alt="Acgpiano"/></a>
|
<a href="https://github.com/acgpiano" title="Acgpiano"><img src="https://avatars.githubusercontent.com/u/15900800?v=4" width="50;" alt="Acgpiano"/></a>
|
||||||
<a href="https://github.com/adminsama" title="adminsama"><img src="https://avatars.githubusercontent.com/u/60880076?v=4" width="50;" alt="adminsama"/></a>
|
<a href="https://github.com/adminsama" title="adminsama"><img src="https://avatars.githubusercontent.com/u/60880076?v=4" width="50;" alt="adminsama"/></a>
|
||||||
<a href="https://github.com/hmsjy2017" title="Tony"><img src="https://avatars.githubusercontent.com/u/42692274?v=4" width="50;" alt="Tony"/></a>
|
<a href="https://github.com/hmsjy2017" title="Tony"><img src="https://avatars.githubusercontent.com/u/42692274?v=4" width="50;" alt="Tony"/></a>
|
||||||
<a href="https://github.com/nickfox-taterli" title="Tater Li"><img src="https://avatars.githubusercontent.com/u/19658596?v=4" width="50;" alt="Tater Li"/></a>
|
<a href="https://github.com/nickfox-taterli" title="Tater Li"><img src="https://avatars.githubusercontent.com/u/19658596?v=4" width="50;" alt="Tater Li"/></a>
|
||||||
|
<a href="https://github.com/dreamingsleeping" title="Nanjing Hopefun Network Technology Co. Ltd."><img src="https://avatars.githubusercontent.com/u/13828658?v=4" width="50;" alt="Nanjing Hopefun Network Technology Co. Ltd."/></a>
|
||||||
<a href="https://github.com/MartijnLindeman" title="Martijn Lindeman"><img src="https://avatars.githubusercontent.com/u/78365708?v=4" width="50;" alt="Martijn Lindeman"/></a>
|
<a href="https://github.com/MartijnLindeman" title="Martijn Lindeman"><img src="https://avatars.githubusercontent.com/u/78365708?v=4" width="50;" alt="Martijn Lindeman"/></a>
|
||||||
|
<a href="https://github.com/funnyzak" title="Leon"><img src="https://avatars.githubusercontent.com/u/2562087?v=4" width="50;" alt="Leon"/></a>
|
||||||
<a href="https://github.com/KorenKrita" title="KorenKrita"><img src="https://avatars.githubusercontent.com/u/22239339?v=4" width="50;" alt="KorenKrita"/></a>
|
<a href="https://github.com/KorenKrita" title="KorenKrita"><img src="https://avatars.githubusercontent.com/u/22239339?v=4" width="50;" alt="KorenKrita"/></a>
|
||||||
<a href="https://github.com/techotaku" title="Ian Li"><img src="https://avatars.githubusercontent.com/u/1948179?v=4" width="50;" alt="Ian Li"/></a>
|
<a href="https://github.com/techotaku" title="Ian Li"><img src="https://avatars.githubusercontent.com/u/1948179?v=4" width="50;" alt="Ian Li"/></a>
|
||||||
<a href="https://github.com/HsukqiLee" title="HsukqiLee"><img src="https://avatars.githubusercontent.com/u/79034142?v=4" width="50;" alt="HsukqiLee"/></a>
|
|
||||||
<a href="https://github.com/GreenTeodoro839" title="GreenTeodoro839"><img src="https://avatars.githubusercontent.com/u/77104800?v=4" width="50;" alt="GreenTeodoro839"/></a>
|
<a href="https://github.com/GreenTeodoro839" title="GreenTeodoro839"><img src="https://avatars.githubusercontent.com/u/77104800?v=4" width="50;" alt="GreenTeodoro839"/></a>
|
||||||
<a href="https://github.com/Es-dese" title="Esdese"><img src="https://avatars.githubusercontent.com/u/71542548?v=4" width="50;" alt="Esdese"/></a>
|
<a href="https://github.com/Es-dese" title="Esdese"><img src="https://avatars.githubusercontent.com/u/71542548?v=4" width="50;" alt="Esdese"/></a>
|
||||||
<a href="https://github.com/wwng2333" title="Crazy"><img src="https://avatars.githubusercontent.com/u/17147265?v=4" width="50;" alt="Crazy"/></a><!--GAMFC_DELIMITER_END-->
|
<a href="https://github.com/wwng2333" title="Crazy"><img src="https://avatars.githubusercontent.com/u/17147265?v=4" width="50;" alt="Crazy"/></a>
|
||||||
|
<a href="https://github.com/wellcoming" title="Coming"><img src="https://avatars.githubusercontent.com/u/74850890?v=4" width="50;" alt="Coming"/></a><!--GAMFC_DELIMITER_END-->
|
||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -223,19 +224,25 @@ func (cp *commonPage) network(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cp *commonPage) getServerStat(c *gin.Context) ([]byte, error) {
|
func (cp *commonPage) getServerStat(c *gin.Context) ([]byte, error) {
|
||||||
v, err, _ := cp.requestGroup.Do("serverStats", func() (any, error) {
|
_, isMember := c.Get(model.CtxKeyAuthorizedUser)
|
||||||
|
_, isViewPasswordVerfied := c.Get(model.CtxKeyViewPasswordVerified)
|
||||||
|
authorized := isMember || isViewPasswordVerfied
|
||||||
|
v, err, _ := cp.requestGroup.Do(fmt.Sprintf("serverStats::%t", authorized), func() (interface{}, error) {
|
||||||
singleton.SortedServerLock.RLock()
|
singleton.SortedServerLock.RLock()
|
||||||
defer singleton.SortedServerLock.RUnlock()
|
defer singleton.SortedServerLock.RUnlock()
|
||||||
|
|
||||||
_, isMember := c.Get(model.CtxKeyAuthorizedUser)
|
|
||||||
_, isViewPasswordVerfied := c.Get(model.CtxKeyViewPasswordVerified)
|
|
||||||
|
|
||||||
var servers []*model.Server
|
var servers []*model.Server
|
||||||
|
|
||||||
if isMember || isViewPasswordVerfied {
|
if authorized {
|
||||||
servers = singleton.SortedServerList
|
servers = singleton.SortedServerList
|
||||||
} else {
|
} else {
|
||||||
servers = singleton.SortedServerListForGuest
|
filteredServers := make([]*model.Server, len(singleton.SortedServerListForGuest))
|
||||||
|
for i, server := range singleton.SortedServerListForGuest {
|
||||||
|
filteredServer := *server
|
||||||
|
filteredServer.DDNSDomain = "redacted"
|
||||||
|
filteredServers[i] = &filteredServer
|
||||||
|
}
|
||||||
|
servers = filteredServers
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.Json.Marshal(Data{
|
return utils.Json.Marshal(Data{
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ func (gp *guestPage) login(c *gin.Context) {
|
|||||||
} else if singleton.Conf.Oauth2.Type == model.ConfigTypeGitea {
|
} else if singleton.Conf.Oauth2.Type == model.ConfigTypeGitea {
|
||||||
LoginType = "Gitea"
|
LoginType = "Gitea"
|
||||||
RegistrationLink = fmt.Sprintf("%s/user/sign_up", singleton.Conf.Oauth2.Endpoint)
|
RegistrationLink = fmt.Sprintf("%s/user/sign_up", singleton.Conf.Oauth2.Endpoint)
|
||||||
|
} else if singleton.Conf.Oauth2.Type == model.ConfigTypeCloudflare {
|
||||||
|
LoginType = "Cloudflare"
|
||||||
|
RegistrationLink = "https://dash.cloudflare.com/sign-up/teams"
|
||||||
}
|
}
|
||||||
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/login", mygin.CommonEnvironment(c, gin.H{
|
c.HTML(http.StatusOK, "dashboard-"+singleton.Conf.Site.DashboardTheme+"/login", mygin.CommonEnvironment(c, gin.H{
|
||||||
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
"Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}),
|
||||||
|
|||||||
@@ -301,7 +301,10 @@ type serverForm struct {
|
|||||||
Note string
|
Note string
|
||||||
HideForGuest string
|
HideForGuest string
|
||||||
EnableDDNS string
|
EnableDDNS string
|
||||||
|
EnableIPv4 string
|
||||||
|
EnableIpv6 string
|
||||||
DDNSDomain string
|
DDNSDomain string
|
||||||
|
DDNSProfile string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ma *memberAPI) addOrEditServer(c *gin.Context) {
|
func (ma *memberAPI) addOrEditServer(c *gin.Context) {
|
||||||
@@ -318,7 +321,10 @@ func (ma *memberAPI) addOrEditServer(c *gin.Context) {
|
|||||||
s.Note = sf.Note
|
s.Note = sf.Note
|
||||||
s.HideForGuest = sf.HideForGuest == "on"
|
s.HideForGuest = sf.HideForGuest == "on"
|
||||||
s.EnableDDNS = sf.EnableDDNS == "on"
|
s.EnableDDNS = sf.EnableDDNS == "on"
|
||||||
|
s.EnableIPv4 = sf.EnableIPv4 == "on"
|
||||||
|
s.EnableIpv6 = sf.EnableIpv6 == "on"
|
||||||
s.DDNSDomain = sf.DDNSDomain
|
s.DDNSDomain = sf.DDNSDomain
|
||||||
|
s.DDNSProfile = sf.DDNSProfile
|
||||||
if s.ID == 0 {
|
if s.ID == 0 {
|
||||||
s.Secret, err = utils.GenerateRandomString(18)
|
s.Secret, err = utils.GenerateRandomString(18)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -431,25 +437,23 @@ func (ma *memberAPI) addOrEditMonitor(c *gin.Context) {
|
|||||||
if m.NotificationTag == "" {
|
if m.NotificationTag == "" {
|
||||||
m.NotificationTag = "default"
|
m.NotificationTag = "default"
|
||||||
}
|
}
|
||||||
if err == nil {
|
err = utils.Json.Unmarshal([]byte(mf.FailTriggerTasksRaw), &m.FailTriggerTasks)
|
||||||
err = utils.Json.Unmarshal([]byte(mf.FailTriggerTasksRaw), &m.FailTriggerTasks)
|
}
|
||||||
|
if err == nil {
|
||||||
|
err = utils.Json.Unmarshal([]byte(mf.RecoverTriggerTasksRaw), &m.RecoverTriggerTasks)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
if m.ID == 0 {
|
||||||
|
err = singleton.DB.Create(&m).Error
|
||||||
|
} else {
|
||||||
|
err = singleton.DB.Save(&m).Error
|
||||||
}
|
}
|
||||||
if err == nil {
|
}
|
||||||
err = utils.Json.Unmarshal([]byte(mf.RecoverTriggerTasksRaw), &m.RecoverTriggerTasks)
|
if err == nil {
|
||||||
}
|
if m.Cover == 0 {
|
||||||
if err == nil {
|
err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id in (?)", m.ID, strings.Split(m.SkipServersRaw[1:len(m.SkipServersRaw)-1], ",")).Error
|
||||||
if m.ID == 0 {
|
} else {
|
||||||
err = singleton.DB.Create(&m).Error
|
err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id not in (?)", m.ID, strings.Split(m.SkipServersRaw[1:len(m.SkipServersRaw)-1], ",")).Error
|
||||||
} else {
|
|
||||||
err = singleton.DB.Save(&m).Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if m.Cover == 0 {
|
|
||||||
err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id in (?)", m.ID, strings.Split(m.SkipServersRaw[1:len(m.SkipServersRaw)-1], ",")).Error
|
|
||||||
} else {
|
|
||||||
err = singleton.DB.Unscoped().Delete(&model.MonitorHistory{}, "monitor_id = ? and server_id not in (?)", m.ID, strings.Split(m.SkipServersRaw[1:len(m.SkipServersRaw)-1], ",")).Error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -9,6 +10,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/naiba/nezha/pkg/oidc/cloudflare"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
GitHubAPI "github.com/google/go-github/v47/github"
|
GitHubAPI "github.com/google/go-github/v47/github"
|
||||||
@@ -74,6 +77,17 @@ func (oa *oauth2controller) getCommonOauth2Config(c *gin.Context) *oauth2.Config
|
|||||||
},
|
},
|
||||||
RedirectURL: oa.getRedirectURL(c),
|
RedirectURL: oa.getRedirectURL(c),
|
||||||
}
|
}
|
||||||
|
} else if singleton.Conf.Oauth2.Type == model.ConfigTypeCloudflare {
|
||||||
|
return &oauth2.Config{
|
||||||
|
ClientID: singleton.Conf.Oauth2.ClientID,
|
||||||
|
ClientSecret: singleton.Conf.Oauth2.ClientSecret,
|
||||||
|
Scopes: []string{"openid", "email", "profile", "groups"},
|
||||||
|
Endpoint: oauth2.Endpoint{
|
||||||
|
AuthURL: fmt.Sprintf("%s/cdn-cgi/access/sso/oidc/%s/authorization", singleton.Conf.Oauth2.Endpoint, singleton.Conf.Oauth2.ClientID),
|
||||||
|
TokenURL: fmt.Sprintf("%s/cdn-cgi/access/sso/oidc/%s/token", singleton.Conf.Oauth2.Endpoint, singleton.Conf.Oauth2.ClientID),
|
||||||
|
},
|
||||||
|
RedirectURL: oa.getRedirectURL(c),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return &oauth2.Config{
|
return &oauth2.Config{
|
||||||
ClientID: singleton.Conf.Oauth2.ClientID,
|
ClientID: singleton.Conf.Oauth2.ClientID,
|
||||||
@@ -155,6 +169,17 @@ func (oa *oauth2controller) callback(c *gin.Context) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
user = model.NewUserFromGitea(u)
|
user = model.NewUserFromGitea(u)
|
||||||
}
|
}
|
||||||
|
} else if singleton.Conf.Oauth2.Type == model.ConfigTypeCloudflare {
|
||||||
|
client := oauth2Config.Client(context.Background(), otk)
|
||||||
|
resp, err := client.Get(fmt.Sprintf("%s/cdn-cgi/access/sso/oidc/%s/userinfo", singleton.Conf.Oauth2.Endpoint, singleton.Conf.Oauth2.ClientID))
|
||||||
|
if err == nil {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
var cloudflareUserInfo *cloudflare.UserInfo
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&cloudflareUserInfo); err == nil {
|
||||||
|
user = cloudflareUserInfo.MapToNezhaUser()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
var client *GitHubAPI.Client
|
var client *GitHubAPI.Client
|
||||||
oc := oauth2Config.Client(ctx, otk)
|
oc := oauth2Config.Client(ctx, otk)
|
||||||
@@ -168,15 +193,12 @@ func (oa *oauth2controller) callback(c *gin.Context) {
|
|||||||
client = GitHubAPI.NewClient(oc)
|
client = GitHubAPI.NewClient(oc)
|
||||||
}
|
}
|
||||||
var gu *GitHubAPI.User
|
var gu *GitHubAPI.User
|
||||||
if err == nil {
|
gu, _, err = client.Users.Get(ctx, "")
|
||||||
gu, _, err = client.Users.Get(ctx, "")
|
|
||||||
}
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
user = model.NewUserFromGitHub(gu)
|
user = model.NewUserFromGitHub(gu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil && user.Login == "" {
|
if err == nil && user.Login == "" {
|
||||||
err = errors.New("获取用户信息失败")
|
err = errors.New("获取用户信息失败")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
module github.com/naiba/nezha
|
module github.com/naiba/nezha
|
||||||
|
|
||||||
go 1.21
|
go 1.20
|
||||||
|
|
||||||
toolchain go1.21.3
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
code.cloudfoundry.org/bytefmt v0.0.0-20240322144145-4816192cb114
|
code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea
|
||||||
code.gitea.io/sdk/gitea v0.17.1
|
code.gitea.io/sdk/gitea v0.18.0
|
||||||
github.com/BurntSushi/toml v1.3.2
|
github.com/BurntSushi/toml v1.3.2
|
||||||
github.com/gin-contrib/pprof v1.4.0
|
github.com/gin-contrib/pprof v1.4.0
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
@@ -22,15 +20,16 @@ require (
|
|||||||
github.com/samber/lo v1.39.0
|
github.com/samber/lo v1.39.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/spf13/viper v1.18.2
|
github.com/spf13/viper v1.18.2
|
||||||
github.com/xanzy/go-gitlab v0.100.0
|
github.com/xanzy/go-gitlab v0.103.0
|
||||||
golang.org/x/crypto v0.21.0
|
golang.org/x/crypto v0.22.0
|
||||||
golang.org/x/oauth2 v0.18.0
|
golang.org/x/net v0.24.0
|
||||||
golang.org/x/sync v0.6.0
|
golang.org/x/oauth2 v0.19.0
|
||||||
|
golang.org/x/sync v0.7.0
|
||||||
golang.org/x/text v0.14.0
|
golang.org/x/text v0.14.0
|
||||||
google.golang.org/grpc v1.62.1
|
google.golang.org/grpc v1.63.0
|
||||||
google.golang.org/protobuf v1.33.0
|
google.golang.org/protobuf v1.33.0
|
||||||
gorm.io/driver/sqlite v1.5.5
|
gorm.io/driver/sqlite v1.5.5
|
||||||
gorm.io/gorm v1.25.8
|
gorm.io/gorm v1.25.10
|
||||||
sigs.k8s.io/yaml v1.4.0
|
sigs.k8s.io/yaml v1.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,10 +45,9 @@ require (
|
|||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
github.com/golang/protobuf v1.5.3 // indirect
|
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
|
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
@@ -57,7 +55,7 @@ require (
|
|||||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||||
github.com/leodido/go-urn v1.2.4 // indirect
|
github.com/leodido/go-urn v1.2.4 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
github.com/magiconair/properties v1.8.7 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
@@ -76,11 +74,9 @@ require (
|
|||||||
go.uber.org/multierr v1.9.0 // indirect
|
go.uber.org/multierr v1.9.0 // indirect
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||||
golang.org/x/net v0.22.0 // indirect
|
golang.org/x/sys v0.20.0 // indirect
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
code.cloudfoundry.org/bytefmt v0.0.0-20240322144145-4816192cb114 h1:7KJsK0gPah7XfO46ARJA2TUXHZaJEnPI80mzxQLre68=
|
code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea h1:1tgMNDgo8PjpsHhlaxdibj28C0WyLeOW2SPJ7GGdc9A=
|
||||||
code.cloudfoundry.org/bytefmt v0.0.0-20240322144145-4816192cb114/go.mod h1:TNAH6xe5WOszc47+zM7NnpaJWBR8oYt12BUf4WLIZ98=
|
code.cloudfoundry.org/bytefmt v0.0.0-20240425163905-bcdc1ad063ea/go.mod h1:3+xXJBOD8PsGHDqHedtCLalbaVJ+yi1OW+mXx9IcNxI=
|
||||||
code.gitea.io/sdk/gitea v0.17.1 h1:3jCPOG2ojbl8AcfaUCRYLT5MUcBMFwS0OSK2mA5Zok8=
|
code.gitea.io/sdk/gitea v0.18.0 h1:+zZrwVmujIrgobt6wVBWCqITz6bn1aBjnCUHmpZrerI=
|
||||||
code.gitea.io/sdk/gitea v0.17.1/go.mod h1:aCnBqhHpoEWA180gMbaCtdX9Pl6BWBAuuP2miadoTNM=
|
code.gitea.io/sdk/gitea v0.18.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI=
|
||||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||||
@@ -14,13 +14,10 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
|
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
|
||||||
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
|
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
|
||||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
|
||||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||||
@@ -35,10 +32,8 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU
|
|||||||
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
|
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
|
||||||
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
|
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
|
||||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
|
||||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
@@ -49,35 +44,27 @@ github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXS
|
|||||||
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
|
||||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
|
||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/go-github/v47 v47.1.0 h1:Cacm/WxQBOa9lF0FT0EMjZ2BWMetQ1TQfyurn4yF1z8=
|
github.com/google/go-github/v47 v47.1.0 h1:Cacm/WxQBOa9lF0FT0EMjZ2BWMetQ1TQfyurn4yF1z8=
|
||||||
github.com/google/go-github/v47 v47.1.0/go.mod h1:VPZBXNbFSJGjyjFRUKo9vZGawTajnWzC/YjGw/oFKi0=
|
github.com/google/go-github/v47 v47.1.0/go.mod h1:VPZBXNbFSJGjyjFRUKo9vZGawTajnWzC/YjGw/oFKi0=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07 h1:57oOH2Mu5Nw16KnZAVLdlUjmPH/TSYCKTJgG0OVfX0Y=
|
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
|
||||||
github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
|
||||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||||
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
|
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
||||||
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
|
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||||
@@ -99,7 +86,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
|||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
@@ -110,10 +96,9 @@ github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNa
|
|||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
|
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
|
||||||
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
@@ -125,10 +110,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
|||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
|
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
|
||||||
github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI=
|
github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
|
||||||
github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE=
|
||||||
github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
|
|
||||||
github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
|
|
||||||
github.com/ory/graceful v0.1.3 h1:FaeXcHZh168WzS+bqruqWEw/HgXWLdNv2nJ+fbhxbhc=
|
github.com/ory/graceful v0.1.3 h1:FaeXcHZh168WzS+bqruqWEw/HgXWLdNv2nJ+fbhxbhc=
|
||||||
github.com/ory/graceful v0.1.3/go.mod h1:4zFz687IAF7oNHHiB586U4iL+/4aV09o/PYLE34t2bA=
|
github.com/ory/graceful v0.1.3/go.mod h1:4zFz687IAF7oNHHiB586U4iL+/4aV09o/PYLE34t2bA=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
@@ -141,13 +124,11 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
|
||||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||||
@@ -167,7 +148,6 @@ github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMV
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
@@ -186,9 +166,8 @@ github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6
|
|||||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
github.com/xanzy/go-gitlab v0.100.0 h1:jaOtYj5nWI19+9oVVmgy233pax2oYqucwetogYU46ks=
|
github.com/xanzy/go-gitlab v0.103.0 h1:J9pTQoq0GsEFqzd6srCM1QfdfKAxSNz6mT6ntrpNF2w=
|
||||||
github.com/xanzy/go-gitlab v0.100.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
|
github.com/xanzy/go-gitlab v0.103.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
|
||||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||||
@@ -200,78 +179,45 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
|
||||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
||||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
|
||||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
|
||||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
|
||||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
|
||||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
|
||||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
|
||||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
|
google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
|
google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||||
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
|
|
||||||
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
|
||||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
@@ -291,8 +237,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
|
gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
|
||||||
gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
|
gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
|
||||||
gorm.io/gorm v1.25.8 h1:WAGEZ/aEcznN4D03laj8DKnehe1e9gYQAjW8xyPRdeo=
|
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
|
||||||
gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||||
|
|||||||
+20
-14
@@ -22,7 +22,7 @@ var Themes = map[string]string{
|
|||||||
"mdui": "Neko Mdui",
|
"mdui": "Neko Mdui",
|
||||||
"hotaru": "Hotaru",
|
"hotaru": "Hotaru",
|
||||||
"angel-kanade": "AngelKanade",
|
"angel-kanade": "AngelKanade",
|
||||||
"server-status": "SeverStatus",
|
"server-status": "ServerStatus",
|
||||||
"custom": "Custom(local)",
|
"custom": "Custom(local)",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,11 +32,12 @@ var DashboardThemes = map[string]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ConfigTypeGitHub = "github"
|
ConfigTypeGitHub = "github"
|
||||||
ConfigTypeGitee = "gitee"
|
ConfigTypeGitee = "gitee"
|
||||||
ConfigTypeGitlab = "gitlab"
|
ConfigTypeGitlab = "gitlab"
|
||||||
ConfigTypeJihulab = "jihulab"
|
ConfigTypeJihulab = "jihulab"
|
||||||
ConfigTypeGitea = "gitea"
|
ConfigTypeGitea = "gitea"
|
||||||
|
ConfigTypeCloudflare = "cloudflare"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -70,7 +71,7 @@ func (c *AgentConfig) Save() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.WriteFile(c.v.ConfigFileUsed(), data, os.ModePerm)
|
return os.WriteFile(c.v.ConfigFileUsed(), data, 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config 站点配置
|
// Config 站点配置
|
||||||
@@ -125,9 +126,20 @@ type Config struct {
|
|||||||
WebhookRequestBody string
|
WebhookRequestBody string
|
||||||
WebhookHeaders string
|
WebhookHeaders string
|
||||||
MaxRetries uint32
|
MaxRetries uint32
|
||||||
|
Profiles map[string]DDNSProfile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DDNSProfile struct {
|
||||||
|
Provider string
|
||||||
|
AccessID string
|
||||||
|
AccessSecret string
|
||||||
|
WebhookURL string
|
||||||
|
WebhookMethod string
|
||||||
|
WebhookRequestBody string
|
||||||
|
WebhookHeaders string
|
||||||
|
}
|
||||||
|
|
||||||
// Read 读取配置文件并应用
|
// Read 读取配置文件并应用
|
||||||
func (c *Config) Read(path string) error {
|
func (c *Config) Read(path string) error {
|
||||||
c.v = viper.New()
|
c.v = viper.New()
|
||||||
@@ -166,12 +178,6 @@ func (c *Config) Read(path string) error {
|
|||||||
if c.AvgPingCount == 0 {
|
if c.AvgPingCount == 0 {
|
||||||
c.AvgPingCount = 2
|
c.AvgPingCount = 2
|
||||||
}
|
}
|
||||||
if c.DDNS.Provider == "" {
|
|
||||||
c.DDNS.Provider = "webhook"
|
|
||||||
}
|
|
||||||
if c.DDNS.WebhookMethod == "" {
|
|
||||||
c.DDNS.WebhookMethod = "POST"
|
|
||||||
}
|
|
||||||
if c.DDNS.MaxRetries == 0 {
|
if c.DDNS.MaxRetries == 0 {
|
||||||
c.DDNS.MaxRetries = 3
|
c.DDNS.MaxRetries = 3
|
||||||
}
|
}
|
||||||
@@ -199,5 +205,5 @@ func (c *Config) Save() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.WriteFile(c.v.ConfigFileUsed(), data, os.ModePerm)
|
return os.WriteFile(c.v.ConfigFileUsed(), data, 0600)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ const (
|
|||||||
MTReportHostState
|
MTReportHostState
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type SensorTemperature struct {
|
||||||
|
Name string
|
||||||
|
Temperature float64
|
||||||
|
}
|
||||||
|
|
||||||
type HostState struct {
|
type HostState struct {
|
||||||
CPU float64
|
CPU float64
|
||||||
MemUsed uint64
|
MemUsed uint64
|
||||||
@@ -26,9 +31,19 @@ type HostState struct {
|
|||||||
TcpConnCount uint64
|
TcpConnCount uint64
|
||||||
UdpConnCount uint64
|
UdpConnCount uint64
|
||||||
ProcessCount uint64
|
ProcessCount uint64
|
||||||
|
Temperatures []SensorTemperature
|
||||||
|
GPU float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HostState) PB() *pb.State {
|
func (s *HostState) PB() *pb.State {
|
||||||
|
var ts []*pb.State_SensorTemperature
|
||||||
|
for _, t := range s.Temperatures {
|
||||||
|
ts = append(ts, &pb.State_SensorTemperature{
|
||||||
|
Name: t.Name,
|
||||||
|
Temperature: t.Temperature,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return &pb.State{
|
return &pb.State{
|
||||||
Cpu: s.CPU,
|
Cpu: s.CPU,
|
||||||
MemUsed: s.MemUsed,
|
MemUsed: s.MemUsed,
|
||||||
@@ -45,10 +60,20 @@ func (s *HostState) PB() *pb.State {
|
|||||||
TcpConnCount: s.TcpConnCount,
|
TcpConnCount: s.TcpConnCount,
|
||||||
UdpConnCount: s.UdpConnCount,
|
UdpConnCount: s.UdpConnCount,
|
||||||
ProcessCount: s.ProcessCount,
|
ProcessCount: s.ProcessCount,
|
||||||
|
Temperatures: ts,
|
||||||
|
Gpu: s.GPU,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PB2State(s *pb.State) HostState {
|
func PB2State(s *pb.State) HostState {
|
||||||
|
var ts []SensorTemperature
|
||||||
|
for _, t := range s.GetTemperatures() {
|
||||||
|
ts = append(ts, SensorTemperature{
|
||||||
|
Name: t.GetName(),
|
||||||
|
Temperature: t.GetTemperature(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return HostState{
|
return HostState{
|
||||||
CPU: s.GetCpu(),
|
CPU: s.GetCpu(),
|
||||||
MemUsed: s.GetMemUsed(),
|
MemUsed: s.GetMemUsed(),
|
||||||
@@ -65,6 +90,8 @@ func PB2State(s *pb.State) HostState {
|
|||||||
TcpConnCount: s.GetTcpConnCount(),
|
TcpConnCount: s.GetTcpConnCount(),
|
||||||
UdpConnCount: s.GetUdpConnCount(),
|
UdpConnCount: s.GetUdpConnCount(),
|
||||||
ProcessCount: s.GetProcessCount(),
|
ProcessCount: s.GetProcessCount(),
|
||||||
|
Temperatures: ts,
|
||||||
|
GPU: s.GetGpu(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +108,7 @@ type Host struct {
|
|||||||
IP string `json:"-"`
|
IP string `json:"-"`
|
||||||
CountryCode string
|
CountryCode string
|
||||||
Version string
|
Version string
|
||||||
|
GPU []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Host) PB() *pb.Host {
|
func (h *Host) PB() *pb.Host {
|
||||||
@@ -97,6 +125,7 @@ func (h *Host) PB() *pb.Host {
|
|||||||
Ip: h.IP,
|
Ip: h.IP,
|
||||||
CountryCode: h.CountryCode,
|
CountryCode: h.CountryCode,
|
||||||
Version: h.Version,
|
Version: h.Version,
|
||||||
|
Gpu: h.GPU,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,5 +143,6 @@ func PB2Host(h *pb.Host) Host {
|
|||||||
IP: h.GetIp(),
|
IP: h.GetIp(),
|
||||||
CountryCode: h.GetCountryCode(),
|
CountryCode: h.GetCountryCode(),
|
||||||
Version: h.GetVersion(),
|
Version: h.GetVersion(),
|
||||||
|
GPU: h.GetGpu(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,3 @@ type MonitorHistory struct {
|
|||||||
Down uint64 // 检查状态异常计数
|
Down uint64 // 检查状态异常计数
|
||||||
Data string
|
Data string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+28
-3
@@ -42,6 +42,19 @@ func percentage(used, total uint64) float64 {
|
|||||||
return float64(used) * 100 / float64(total)
|
return float64(used) * 100 / float64(total)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func maxSliceValue(slice []float64) float64 {
|
||||||
|
if len(slice) != 0 {
|
||||||
|
max := slice[0]
|
||||||
|
for _, val := range slice {
|
||||||
|
if max < val {
|
||||||
|
max = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// Snapshot 未通过规则返回 struct{}{}, 通过返回 nil
|
// Snapshot 未通过规则返回 struct{}{}, 通过返回 nil
|
||||||
func (u *Rule) Snapshot(cycleTransferStats *CycleTransferStats, server *Server, db *gorm.DB) interface{} {
|
func (u *Rule) Snapshot(cycleTransferStats *CycleTransferStats, server *Server, db *gorm.DB) interface{} {
|
||||||
// 监控全部但是排除了此服务器
|
// 监控全部但是排除了此服务器
|
||||||
@@ -63,6 +76,8 @@ func (u *Rule) Snapshot(cycleTransferStats *CycleTransferStats, server *Server,
|
|||||||
switch u.Type {
|
switch u.Type {
|
||||||
case "cpu":
|
case "cpu":
|
||||||
src = float64(server.State.CPU)
|
src = float64(server.State.CPU)
|
||||||
|
case "gpu":
|
||||||
|
src = float64(server.State.GPU)
|
||||||
case "memory":
|
case "memory":
|
||||||
src = percentage(server.State.MemUsed, server.Host.MemTotal)
|
src = percentage(server.State.MemUsed, server.Host.MemTotal)
|
||||||
case "swap":
|
case "swap":
|
||||||
@@ -91,21 +106,21 @@ func (u *Rule) Snapshot(cycleTransferStats *CycleTransferStats, server *Server,
|
|||||||
src = float64(server.State.NetInTransfer - uint64(server.PrevHourlyTransferIn))
|
src = float64(server.State.NetInTransfer - uint64(server.PrevHourlyTransferIn))
|
||||||
if u.CycleInterval != 0 {
|
if u.CycleInterval != 0 {
|
||||||
var res NResult
|
var res NResult
|
||||||
db.Model(&Transfer{}).Select("SUM(`in`) AS n").Where("created_at > ? AND server_id = ?", u.GetTransferDurationStart(), server.ID).Scan(&res)
|
db.Model(&Transfer{}).Select("SUM(`in`) AS n").Where("datetime(`created_at`) >= datetime(?) AND server_id = ?", u.GetTransferDurationStart().UTC(), server.ID).Scan(&res)
|
||||||
src += float64(res.N)
|
src += float64(res.N)
|
||||||
}
|
}
|
||||||
case "transfer_out_cycle":
|
case "transfer_out_cycle":
|
||||||
src = float64(server.State.NetOutTransfer - uint64(server.PrevHourlyTransferOut))
|
src = float64(server.State.NetOutTransfer - uint64(server.PrevHourlyTransferOut))
|
||||||
if u.CycleInterval != 0 {
|
if u.CycleInterval != 0 {
|
||||||
var res NResult
|
var res NResult
|
||||||
db.Model(&Transfer{}).Select("SUM(`out`) AS n").Where("created_at > ? AND server_id = ?", u.GetTransferDurationStart(), server.ID).Scan(&res)
|
db.Model(&Transfer{}).Select("SUM(`out`) AS n").Where("datetime(`created_at`) >= datetime(?) AND server_id = ?", u.GetTransferDurationStart().UTC(), server.ID).Scan(&res)
|
||||||
src += float64(res.N)
|
src += float64(res.N)
|
||||||
}
|
}
|
||||||
case "transfer_all_cycle":
|
case "transfer_all_cycle":
|
||||||
src = float64(server.State.NetOutTransfer - uint64(server.PrevHourlyTransferOut) + server.State.NetInTransfer - uint64(server.PrevHourlyTransferIn))
|
src = float64(server.State.NetOutTransfer - uint64(server.PrevHourlyTransferOut) + server.State.NetInTransfer - uint64(server.PrevHourlyTransferIn))
|
||||||
if u.CycleInterval != 0 {
|
if u.CycleInterval != 0 {
|
||||||
var res NResult
|
var res NResult
|
||||||
db.Model(&Transfer{}).Select("SUM(`in`+`out`) AS n").Where("created_at > ? AND server_id = ?", u.GetTransferDurationStart(), server.ID).Scan(&res)
|
db.Model(&Transfer{}).Select("SUM(`in`+`out`) AS n").Where("datetime(`created_at`) >= datetime(?) AND server_id = ?", u.GetTransferDurationStart().UTC(), server.ID).Scan(&res)
|
||||||
src += float64(res.N)
|
src += float64(res.N)
|
||||||
}
|
}
|
||||||
case "load1":
|
case "load1":
|
||||||
@@ -120,6 +135,16 @@ func (u *Rule) Snapshot(cycleTransferStats *CycleTransferStats, server *Server,
|
|||||||
src = float64(server.State.UdpConnCount)
|
src = float64(server.State.UdpConnCount)
|
||||||
case "process_count":
|
case "process_count":
|
||||||
src = float64(server.State.ProcessCount)
|
src = float64(server.State.ProcessCount)
|
||||||
|
case "temperature_max":
|
||||||
|
var temp []float64
|
||||||
|
if server.State.Temperatures != nil {
|
||||||
|
for _, tempStat := range server.State.Temperatures {
|
||||||
|
if tempStat.Temperature != 0 {
|
||||||
|
temp = append(temp, tempStat.Temperature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src = maxSliceValue(temp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 循环区间流量检测 · 更新下次需要检测时间
|
// 循环区间流量检测 · 更新下次需要检测时间
|
||||||
|
|||||||
+5
-1
@@ -18,7 +18,10 @@ type Server struct {
|
|||||||
DisplayIndex int // 展示排序,越大越靠前
|
DisplayIndex int // 展示排序,越大越靠前
|
||||||
HideForGuest bool // 对游客隐藏
|
HideForGuest bool // 对游客隐藏
|
||||||
EnableDDNS bool // 是否启用DDNS 未在配置文件中启用DDNS 或 DDNS检查时间为0时此项无效
|
EnableDDNS bool // 是否启用DDNS 未在配置文件中启用DDNS 或 DDNS检查时间为0时此项无效
|
||||||
|
EnableIPv4 bool // 是否启用DDNS IPv4
|
||||||
|
EnableIpv6 bool // 是否启用DDNS IPv6
|
||||||
DDNSDomain string // DDNS中的前缀 如基础域名为abc.oracle DDNSName为mjj 就会把mjj.abc.oracle解析服务器IP 为空则停用
|
DDNSDomain string // DDNS中的前缀 如基础域名为abc.oracle DDNSName为mjj 就会把mjj.abc.oracle解析服务器IP 为空则停用
|
||||||
|
DDNSProfile string // DDNS配置
|
||||||
|
|
||||||
Host *Host `gorm:"-"`
|
Host *Host `gorm:"-"`
|
||||||
State *HostState `gorm:"-"`
|
State *HostState `gorm:"-"`
|
||||||
@@ -54,5 +57,6 @@ func (s Server) Marshal() template.JS {
|
|||||||
note, _ := utils.Json.Marshal(s.Note)
|
note, _ := utils.Json.Marshal(s.Note)
|
||||||
secret, _ := utils.Json.Marshal(s.Secret)
|
secret, _ := utils.Json.Marshal(s.Secret)
|
||||||
ddnsDomain, _ := utils.Json.Marshal(s.DDNSDomain)
|
ddnsDomain, _ := utils.Json.Marshal(s.DDNSDomain)
|
||||||
return template.JS(fmt.Sprintf(`{"ID":%d,"Name":%s,"Secret":%s,"DisplayIndex":%d,"Tag":%s,"Note":%s,"HideForGuest": %s,"EnableDDNS": %s,"DDNSDomain": %s}`, s.ID, name, secret, s.DisplayIndex, tag, note, boolToString(s.HideForGuest), boolToString(s.EnableDDNS), ddnsDomain)) // #nosec
|
ddnsProfile, _ := utils.Json.Marshal(s.DDNSProfile)
|
||||||
|
return template.JS(fmt.Sprintf(`{"ID":%d,"Name":%s,"Secret":%s,"DisplayIndex":%d,"Tag":%s,"Note":%s,"HideForGuest": %s,"EnableDDNS": %s,"EnableIPv4": %s,"EnableIpv6": %s,"DDNSDomain": %s,"DDNSProfile": %s}`, s.ID, name, secret, s.DisplayIndex, tag, note, boolToString(s.HideForGuest), boolToString(s.EnableDDNS), boolToString(s.EnableIPv4), boolToString(s.EnableIpv6), ddnsDomain, ddnsProfile)) // #nosec
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ type ProviderCloudflare struct {
|
|||||||
Secret string
|
Secret string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider ProviderCloudflare) UpdateDomain(domainConfig *DomainConfig) bool {
|
func (provider *ProviderCloudflare) UpdateDomain(domainConfig *DomainConfig) bool {
|
||||||
if domainConfig == nil {
|
if domainConfig == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@ func (provider ProviderCloudflare) UpdateDomain(domainConfig *DomainConfig) bool
|
|||||||
return resultV4 && resultV6
|
return resultV4 && resultV6
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider ProviderCloudflare) addDomainRecord(zoneID string, domainConfig *DomainConfig, isIpv4 bool) bool {
|
func (provider *ProviderCloudflare) addDomainRecord(zoneID string, domainConfig *DomainConfig, isIpv4 bool) bool {
|
||||||
record, err := provider.findDNSRecord(zoneID, domainConfig.FullDomain, isIpv4)
|
record, err := provider.findDNSRecord(zoneID, domainConfig.FullDomain, isIpv4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("查找 DNS 记录时出错: %s\n", err)
|
log.Printf("查找 DNS 记录时出错: %s\n", err)
|
||||||
@@ -58,7 +58,7 @@ func (provider ProviderCloudflare) addDomainRecord(zoneID string, domainConfig *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider ProviderCloudflare) getZoneID(domain string) (string, error) {
|
func (provider *ProviderCloudflare) getZoneID(domain string) (string, error) {
|
||||||
_, realDomain := SplitDomain(domain)
|
_, realDomain := SplitDomain(domain)
|
||||||
url := fmt.Sprintf("https://api.cloudflare.com/client/v4/zones?name=%s", realDomain)
|
url := fmt.Sprintf("https://api.cloudflare.com/client/v4/zones?name=%s", realDomain)
|
||||||
body, err := provider.sendRequest("GET", url, nil)
|
body, err := provider.sendRequest("GET", url, nil)
|
||||||
@@ -81,7 +81,7 @@ func (provider ProviderCloudflare) getZoneID(domain string) (string, error) {
|
|||||||
return "", fmt.Errorf("找不到 Zone ID")
|
return "", fmt.Errorf("找不到 Zone ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider ProviderCloudflare) findDNSRecord(zoneID string, domain string, isIPv4 bool) (map[string]interface{}, error) {
|
func (provider *ProviderCloudflare) findDNSRecord(zoneID string, domain string, isIPv4 bool) (map[string]interface{}, error) {
|
||||||
var ipType = "A"
|
var ipType = "A"
|
||||||
if !isIPv4 {
|
if !isIPv4 {
|
||||||
ipType = "AAAA"
|
ipType = "AAAA"
|
||||||
@@ -106,7 +106,7 @@ func (provider ProviderCloudflare) findDNSRecord(zoneID string, domain string, i
|
|||||||
return nil, nil // 没有找到 DNS 记录
|
return nil, nil // 没有找到 DNS 记录
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider ProviderCloudflare) createDNSRecord(zoneID string, domainConfig *DomainConfig, isIPv4 bool) bool {
|
func (provider *ProviderCloudflare) createDNSRecord(zoneID string, domainConfig *DomainConfig, isIPv4 bool) bool {
|
||||||
var ipType = "A"
|
var ipType = "A"
|
||||||
var ipAddr = domainConfig.Ipv4Addr
|
var ipAddr = domainConfig.Ipv4Addr
|
||||||
if !isIPv4 {
|
if !isIPv4 {
|
||||||
@@ -126,7 +126,7 @@ func (provider ProviderCloudflare) createDNSRecord(zoneID string, domainConfig *
|
|||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider ProviderCloudflare) updateDNSRecord(zoneID string, recordID string, domainConfig *DomainConfig, isIPv4 bool) bool {
|
func (provider *ProviderCloudflare) updateDNSRecord(zoneID string, recordID string, domainConfig *DomainConfig, isIPv4 bool) bool {
|
||||||
var ipType = "A"
|
var ipType = "A"
|
||||||
var ipAddr = domainConfig.Ipv4Addr
|
var ipAddr = domainConfig.Ipv4Addr
|
||||||
if !isIPv4 {
|
if !isIPv4 {
|
||||||
@@ -147,7 +147,7 @@ func (provider ProviderCloudflare) updateDNSRecord(zoneID string, recordID strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 以下为辅助方法,如发送 HTTP 请求等
|
// 以下为辅助方法,如发送 HTTP 请求等
|
||||||
func (provider ProviderCloudflare) sendRequest(method string, url string, data []byte) ([]byte, error) {
|
func (provider *ProviderCloudflare) sendRequest(method string, url string, data []byte) ([]byte, error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, err := http.NewRequest(method, url, bytes.NewBuffer(data))
|
req, err := http.NewRequest(method, url, bytes.NewBuffer(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+1
-1
@@ -2,6 +2,6 @@ package ddns
|
|||||||
|
|
||||||
type ProviderDummy struct{}
|
type ProviderDummy struct{}
|
||||||
|
|
||||||
func (provider ProviderDummy) UpdateDomain(domainConfig *DomainConfig) bool {
|
func (provider *ProviderDummy) UpdateDomain(domainConfig *DomainConfig) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-26
@@ -1,7 +1,7 @@
|
|||||||
package ddns
|
package ddns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"golang.org/x/net/publicsuffix"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -33,29 +33,8 @@ func SetStringHeadersToRequest(req *http.Request, headers []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SplitDomain 分割域名为前缀和一级域名
|
// SplitDomain 分割域名为前缀和一级域名
|
||||||
func SplitDomain(domain string) (prefix string, topLevelDomain string) {
|
func SplitDomain(domain string) (prefix string, realDomain string) {
|
||||||
// 带有二级TLD的一些常见例子,需要特别处理
|
realDomain, _ = publicsuffix.EffectiveTLDPlusOne(domain)
|
||||||
secondLevelTLDs := map[string]bool{
|
prefix = domain[:len(domain)-len(realDomain)-1]
|
||||||
".co.uk": true, ".com.cn": true, ".gov.cn": true, ".net.cn": true, ".org.cn": true,
|
return prefix, realDomain
|
||||||
}
|
|
||||||
|
|
||||||
// 分割域名为"."的各部分
|
|
||||||
parts := strings.Split(domain, ".")
|
|
||||||
|
|
||||||
// 处理特殊情况,例如 ".co.uk"
|
|
||||||
for i := len(parts) - 2; i > 0; i-- {
|
|
||||||
potentialTLD := fmt.Sprintf(".%s.%s", parts[i], parts[i+1])
|
|
||||||
if secondLevelTLDs[potentialTLD] {
|
|
||||||
if i > 1 {
|
|
||||||
return strings.Join(parts[:i-1], "."), strings.Join(parts[i-1:], ".")
|
|
||||||
}
|
|
||||||
return "", domain // 当域名仅为二级TLD时,无前缀
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 常规处理,查找最后一个"."前的所有内容作为前缀
|
|
||||||
if len(parts) > 2 {
|
|
||||||
return strings.Join(parts[:len(parts)-2], "."), strings.Join(parts[len(parts)-2:], ".")
|
|
||||||
}
|
|
||||||
return "", domain // 当域名不包含子域名时,无前缀
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,228 @@
|
|||||||
|
package ddns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
url = "https://dnspod.tencentcloudapi.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProviderTencentCloud struct {
|
||||||
|
SecretID string
|
||||||
|
SecretKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) UpdateDomain(domainConfig *DomainConfig) bool {
|
||||||
|
if domainConfig == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当IPv4和IPv6同时成功才算作成功
|
||||||
|
var resultV4 = true
|
||||||
|
var resultV6 = true
|
||||||
|
if domainConfig.EnableIPv4 {
|
||||||
|
if !provider.addDomainRecord(domainConfig, true) {
|
||||||
|
resultV4 = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if domainConfig.EnableIpv6 {
|
||||||
|
if !provider.addDomainRecord(domainConfig, false) {
|
||||||
|
resultV6 = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultV4 && resultV6
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) addDomainRecord(domainConfig *DomainConfig, isIpv4 bool) bool {
|
||||||
|
record, err := provider.findDNSRecord(domainConfig.FullDomain, isIpv4)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("查找 DNS 记录时出错: %s\n", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if errResponse, ok := record["Error"].(map[string]interface{}); ok {
|
||||||
|
if errCode, ok := errResponse["Code"].(string); ok && errCode == "ResourceNotFound.NoDataOfRecord" { // 没有找到 DNS 记录
|
||||||
|
// 添加 DNS 记录
|
||||||
|
return provider.createDNSRecord(domainConfig.FullDomain, domainConfig, isIpv4)
|
||||||
|
} else {
|
||||||
|
log.Printf("查询 DNS 记录时出错,错误代码为: %s\n", errCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认情况下更新 DNS 记录
|
||||||
|
return provider.updateDNSRecord(domainConfig.FullDomain, record["RecordList"].([]interface{})[0].(map[string]interface{})["RecordId"].(float64), domainConfig, isIpv4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) findDNSRecord(domain string, isIPv4 bool) (map[string]interface{}, error) {
|
||||||
|
var ipType = "A"
|
||||||
|
if !isIPv4 {
|
||||||
|
ipType = "AAAA"
|
||||||
|
}
|
||||||
|
_, realDomain := SplitDomain(domain)
|
||||||
|
prefix, _ := SplitDomain(domain)
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"RecordType": ipType,
|
||||||
|
"Domain": realDomain,
|
||||||
|
"RecordLine": "默认",
|
||||||
|
"Subdomain": prefix,
|
||||||
|
}
|
||||||
|
jsonData, _ := json.Marshal(data)
|
||||||
|
body, err := provider.sendRequest("DescribeRecordList", jsonData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var res map[string]interface{}
|
||||||
|
err = json.Unmarshal(body, &res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := res["Response"].(map[string]interface{})
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) createDNSRecord(domain string, domainConfig *DomainConfig, isIPv4 bool) bool {
|
||||||
|
var ipType = "A"
|
||||||
|
var ipAddr = domainConfig.Ipv4Addr
|
||||||
|
if !isIPv4 {
|
||||||
|
ipType = "AAAA"
|
||||||
|
ipAddr = domainConfig.Ipv6Addr
|
||||||
|
}
|
||||||
|
_, realDomain := SplitDomain(domain)
|
||||||
|
prefix, _ := SplitDomain(domain)
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"RecordType": ipType,
|
||||||
|
"RecordLine": "默认",
|
||||||
|
"Domain": realDomain,
|
||||||
|
"SubDomain": prefix,
|
||||||
|
"Value": ipAddr,
|
||||||
|
"TTL": 600,
|
||||||
|
}
|
||||||
|
jsonData, _ := json.Marshal(data)
|
||||||
|
_, err := provider.sendRequest("CreateRecord", jsonData)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) updateDNSRecord(domain string, recordID float64, domainConfig *DomainConfig, isIPv4 bool) bool {
|
||||||
|
var ipType = "A"
|
||||||
|
var ipAddr = domainConfig.Ipv4Addr
|
||||||
|
if !isIPv4 {
|
||||||
|
ipType = "AAAA"
|
||||||
|
ipAddr = domainConfig.Ipv6Addr
|
||||||
|
}
|
||||||
|
_, realDomain := SplitDomain(domain)
|
||||||
|
prefix, _ := SplitDomain(domain)
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"RecordType": ipType,
|
||||||
|
"RecordLine": "默认",
|
||||||
|
"Domain": realDomain,
|
||||||
|
"SubDomain": prefix,
|
||||||
|
"Value": ipAddr,
|
||||||
|
"TTL": 600,
|
||||||
|
"RecordId": recordID,
|
||||||
|
}
|
||||||
|
jsonData, _ := json.Marshal(data)
|
||||||
|
_, err := provider.sendRequest("ModifyRecord", jsonData)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 以下为辅助方法,如发送 HTTP 请求等
|
||||||
|
func (provider *ProviderTencentCloud) sendRequest(action string, data []byte) ([]byte, error) {
|
||||||
|
client := &http.Client{}
|
||||||
|
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("X-TC-Version", "2021-03-23")
|
||||||
|
|
||||||
|
provider.signRequest(provider.SecretID, provider.SecretKey, req, action, string(data))
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func(Body io.ReadCloser) {
|
||||||
|
err := Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("NEZHA>> 无法关闭HTTP响应体流: %s\n", err.Error())
|
||||||
|
}
|
||||||
|
}(resp.Body)
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return body, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/jeessy2/ddns-go/blob/master/util/tencent_cloud_signer.go
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) sha256hex(s string) string {
|
||||||
|
b := sha256.Sum256([]byte(s))
|
||||||
|
return hex.EncodeToString(b[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) hmacsha256(s, key string) string {
|
||||||
|
hashed := hmac.New(sha256.New, []byte(key))
|
||||||
|
hashed.Write([]byte(s))
|
||||||
|
return string(hashed.Sum(nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) WriteString(strs ...string) string {
|
||||||
|
var b strings.Builder
|
||||||
|
for _, str := range strs {
|
||||||
|
b.WriteString(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *ProviderTencentCloud) signRequest(secretId string, secretKey string, r *http.Request, action string, payload string) {
|
||||||
|
algorithm := "TC3-HMAC-SHA256"
|
||||||
|
service := "dnspod"
|
||||||
|
host := provider.WriteString(service, ".tencentcloudapi.com")
|
||||||
|
timestamp := time.Now().Unix()
|
||||||
|
timestampStr := strconv.FormatInt(timestamp, 10)
|
||||||
|
|
||||||
|
// 步骤 1:拼接规范请求串
|
||||||
|
canonicalHeaders := provider.WriteString("content-type:application/json\nhost:", host, "\nx-tc-action:", strings.ToLower(action), "\n")
|
||||||
|
signedHeaders := "content-type;host;x-tc-action"
|
||||||
|
hashedRequestPayload := provider.sha256hex(payload)
|
||||||
|
canonicalRequest := provider.WriteString("POST\n/\n\n", canonicalHeaders, "\n", signedHeaders, "\n", hashedRequestPayload)
|
||||||
|
|
||||||
|
// 步骤 2:拼接待签名字符串
|
||||||
|
date := time.Unix(timestamp, 0).UTC().Format("2006-01-02")
|
||||||
|
credentialScope := provider.WriteString(date, "/", service, "/tc3_request")
|
||||||
|
hashedCanonicalRequest := provider.sha256hex(canonicalRequest)
|
||||||
|
string2sign := provider.WriteString(algorithm, "\n", timestampStr, "\n", credentialScope, "\n", hashedCanonicalRequest)
|
||||||
|
|
||||||
|
// 步骤 3:计算签名
|
||||||
|
secretDate := provider.hmacsha256(date, provider.WriteString("TC3", secretKey))
|
||||||
|
secretService := provider.hmacsha256(service, secretDate)
|
||||||
|
secretSigning := provider.hmacsha256("tc3_request", secretService)
|
||||||
|
signature := hex.EncodeToString([]byte(provider.hmacsha256(string2sign, secretSigning)))
|
||||||
|
|
||||||
|
// 步骤 4:拼接 Authorization
|
||||||
|
authorization := provider.WriteString(algorithm, " Credential=", secretId, "/", credentialScope, ", SignedHeaders=", signedHeaders, ", Signature=", signature)
|
||||||
|
|
||||||
|
r.Header.Add("Authorization", authorization)
|
||||||
|
r.Header.Set("Host", host)
|
||||||
|
r.Header.Set("X-TC-Action", action)
|
||||||
|
r.Header.Add("X-TC-Timestamp", timestampStr)
|
||||||
|
}
|
||||||
+1
-1
@@ -14,7 +14,7 @@ type ProviderWebHook struct {
|
|||||||
RequestHeader string
|
RequestHeader string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider ProviderWebHook) UpdateDomain(domainConfig *DomainConfig) bool {
|
func (provider *ProviderWebHook) UpdateDomain(domainConfig *DomainConfig) bool {
|
||||||
if domainConfig == nil {
|
if domainConfig == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package cloudflare
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/naiba/nezha/model"
|
||||||
|
"github.com/naiba/nezha/service/singleton"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserInfo struct {
|
||||||
|
Sub string `json:"sub"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Groups []string `json:"groups"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UserInfo) MapToNezhaUser() model.User {
|
||||||
|
var user model.User
|
||||||
|
singleton.DB.Where("login = ?", u.Sub).First(&user)
|
||||||
|
user.Login = u.Sub
|
||||||
|
user.Email = u.Email
|
||||||
|
user.Name = u.Name
|
||||||
|
return user
|
||||||
|
}
|
||||||
+213
-108
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.30.0
|
// protoc-gen-go v1.34.1
|
||||||
// protoc v3.21.12
|
// protoc v5.26.1
|
||||||
// source: proto/nezha.proto
|
// source: proto/nezha.proto
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
@@ -37,6 +37,7 @@ type Host struct {
|
|||||||
Ip string `protobuf:"bytes,10,opt,name=ip,proto3" json:"ip,omitempty"`
|
Ip string `protobuf:"bytes,10,opt,name=ip,proto3" json:"ip,omitempty"`
|
||||||
CountryCode string `protobuf:"bytes,11,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"`
|
CountryCode string `protobuf:"bytes,11,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"`
|
||||||
Version string `protobuf:"bytes,12,opt,name=version,proto3" json:"version,omitempty"`
|
Version string `protobuf:"bytes,12,opt,name=version,proto3" json:"version,omitempty"`
|
||||||
|
Gpu []string `protobuf:"bytes,13,rep,name=gpu,proto3" json:"gpu,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Host) Reset() {
|
func (x *Host) Reset() {
|
||||||
@@ -155,26 +156,35 @@ func (x *Host) GetVersion() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Host) GetGpu() []string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Gpu
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Cpu float64 `protobuf:"fixed64,1,opt,name=cpu,proto3" json:"cpu,omitempty"`
|
Cpu float64 `protobuf:"fixed64,1,opt,name=cpu,proto3" json:"cpu,omitempty"`
|
||||||
MemUsed uint64 `protobuf:"varint,3,opt,name=mem_used,json=memUsed,proto3" json:"mem_used,omitempty"`
|
MemUsed uint64 `protobuf:"varint,3,opt,name=mem_used,json=memUsed,proto3" json:"mem_used,omitempty"`
|
||||||
SwapUsed uint64 `protobuf:"varint,4,opt,name=swap_used,json=swapUsed,proto3" json:"swap_used,omitempty"`
|
SwapUsed uint64 `protobuf:"varint,4,opt,name=swap_used,json=swapUsed,proto3" json:"swap_used,omitempty"`
|
||||||
DiskUsed uint64 `protobuf:"varint,5,opt,name=disk_used,json=diskUsed,proto3" json:"disk_used,omitempty"`
|
DiskUsed uint64 `protobuf:"varint,5,opt,name=disk_used,json=diskUsed,proto3" json:"disk_used,omitempty"`
|
||||||
NetInTransfer uint64 `protobuf:"varint,6,opt,name=net_in_transfer,json=netInTransfer,proto3" json:"net_in_transfer,omitempty"`
|
NetInTransfer uint64 `protobuf:"varint,6,opt,name=net_in_transfer,json=netInTransfer,proto3" json:"net_in_transfer,omitempty"`
|
||||||
NetOutTransfer uint64 `protobuf:"varint,7,opt,name=net_out_transfer,json=netOutTransfer,proto3" json:"net_out_transfer,omitempty"`
|
NetOutTransfer uint64 `protobuf:"varint,7,opt,name=net_out_transfer,json=netOutTransfer,proto3" json:"net_out_transfer,omitempty"`
|
||||||
NetInSpeed uint64 `protobuf:"varint,8,opt,name=net_in_speed,json=netInSpeed,proto3" json:"net_in_speed,omitempty"`
|
NetInSpeed uint64 `protobuf:"varint,8,opt,name=net_in_speed,json=netInSpeed,proto3" json:"net_in_speed,omitempty"`
|
||||||
NetOutSpeed uint64 `protobuf:"varint,9,opt,name=net_out_speed,json=netOutSpeed,proto3" json:"net_out_speed,omitempty"`
|
NetOutSpeed uint64 `protobuf:"varint,9,opt,name=net_out_speed,json=netOutSpeed,proto3" json:"net_out_speed,omitempty"`
|
||||||
Uptime uint64 `protobuf:"varint,10,opt,name=uptime,proto3" json:"uptime,omitempty"`
|
Uptime uint64 `protobuf:"varint,10,opt,name=uptime,proto3" json:"uptime,omitempty"`
|
||||||
Load1 float64 `protobuf:"fixed64,11,opt,name=load1,proto3" json:"load1,omitempty"`
|
Load1 float64 `protobuf:"fixed64,11,opt,name=load1,proto3" json:"load1,omitempty"`
|
||||||
Load5 float64 `protobuf:"fixed64,12,opt,name=load5,proto3" json:"load5,omitempty"`
|
Load5 float64 `protobuf:"fixed64,12,opt,name=load5,proto3" json:"load5,omitempty"`
|
||||||
Load15 float64 `protobuf:"fixed64,13,opt,name=load15,proto3" json:"load15,omitempty"`
|
Load15 float64 `protobuf:"fixed64,13,opt,name=load15,proto3" json:"load15,omitempty"`
|
||||||
TcpConnCount uint64 `protobuf:"varint,14,opt,name=tcp_conn_count,json=tcpConnCount,proto3" json:"tcp_conn_count,omitempty"`
|
TcpConnCount uint64 `protobuf:"varint,14,opt,name=tcp_conn_count,json=tcpConnCount,proto3" json:"tcp_conn_count,omitempty"`
|
||||||
UdpConnCount uint64 `protobuf:"varint,15,opt,name=udp_conn_count,json=udpConnCount,proto3" json:"udp_conn_count,omitempty"`
|
UdpConnCount uint64 `protobuf:"varint,15,opt,name=udp_conn_count,json=udpConnCount,proto3" json:"udp_conn_count,omitempty"`
|
||||||
ProcessCount uint64 `protobuf:"varint,16,opt,name=process_count,json=processCount,proto3" json:"process_count,omitempty"`
|
ProcessCount uint64 `protobuf:"varint,16,opt,name=process_count,json=processCount,proto3" json:"process_count,omitempty"`
|
||||||
|
Temperatures []*State_SensorTemperature `protobuf:"bytes,17,rep,name=temperatures,proto3" json:"temperatures,omitempty"`
|
||||||
|
Gpu float64 `protobuf:"fixed64,18,opt,name=gpu,proto3" json:"gpu,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *State) Reset() {
|
func (x *State) Reset() {
|
||||||
@@ -314,6 +324,75 @@ func (x *State) GetProcessCount() uint64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *State) GetTemperatures() []*State_SensorTemperature {
|
||||||
|
if x != nil {
|
||||||
|
return x.Temperatures
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *State) GetGpu() float64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Gpu
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type State_SensorTemperature struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
|
Temperature float64 `protobuf:"fixed64,2,opt,name=temperature,proto3" json:"temperature,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *State_SensorTemperature) Reset() {
|
||||||
|
*x = State_SensorTemperature{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_proto_nezha_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *State_SensorTemperature) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*State_SensorTemperature) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *State_SensorTemperature) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_proto_nezha_proto_msgTypes[2]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use State_SensorTemperature.ProtoReflect.Descriptor instead.
|
||||||
|
func (*State_SensorTemperature) Descriptor() ([]byte, []int) {
|
||||||
|
return file_proto_nezha_proto_rawDescGZIP(), []int{2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *State_SensorTemperature) GetName() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Name
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *State_SensorTemperature) GetTemperature() float64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Temperature
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
type Task struct {
|
type Task struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@@ -327,7 +406,7 @@ type Task struct {
|
|||||||
func (x *Task) Reset() {
|
func (x *Task) Reset() {
|
||||||
*x = Task{}
|
*x = Task{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_proto_nezha_proto_msgTypes[2]
|
mi := &file_proto_nezha_proto_msgTypes[3]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -340,7 +419,7 @@ func (x *Task) String() string {
|
|||||||
func (*Task) ProtoMessage() {}
|
func (*Task) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *Task) ProtoReflect() protoreflect.Message {
|
func (x *Task) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_nezha_proto_msgTypes[2]
|
mi := &file_proto_nezha_proto_msgTypes[3]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -353,7 +432,7 @@ func (x *Task) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use Task.ProtoReflect.Descriptor instead.
|
// Deprecated: Use Task.ProtoReflect.Descriptor instead.
|
||||||
func (*Task) Descriptor() ([]byte, []int) {
|
func (*Task) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_nezha_proto_rawDescGZIP(), []int{2}
|
return file_proto_nezha_proto_rawDescGZIP(), []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Task) GetId() uint64 {
|
func (x *Task) GetId() uint64 {
|
||||||
@@ -392,7 +471,7 @@ type TaskResult struct {
|
|||||||
func (x *TaskResult) Reset() {
|
func (x *TaskResult) Reset() {
|
||||||
*x = TaskResult{}
|
*x = TaskResult{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_proto_nezha_proto_msgTypes[3]
|
mi := &file_proto_nezha_proto_msgTypes[4]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -405,7 +484,7 @@ func (x *TaskResult) String() string {
|
|||||||
func (*TaskResult) ProtoMessage() {}
|
func (*TaskResult) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *TaskResult) ProtoReflect() protoreflect.Message {
|
func (x *TaskResult) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_nezha_proto_msgTypes[3]
|
mi := &file_proto_nezha_proto_msgTypes[4]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -418,7 +497,7 @@ func (x *TaskResult) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use TaskResult.ProtoReflect.Descriptor instead.
|
// Deprecated: Use TaskResult.ProtoReflect.Descriptor instead.
|
||||||
func (*TaskResult) Descriptor() ([]byte, []int) {
|
func (*TaskResult) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_nezha_proto_rawDescGZIP(), []int{3}
|
return file_proto_nezha_proto_rawDescGZIP(), []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *TaskResult) GetId() uint64 {
|
func (x *TaskResult) GetId() uint64 {
|
||||||
@@ -467,7 +546,7 @@ type Receipt struct {
|
|||||||
func (x *Receipt) Reset() {
|
func (x *Receipt) Reset() {
|
||||||
*x = Receipt{}
|
*x = Receipt{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_proto_nezha_proto_msgTypes[4]
|
mi := &file_proto_nezha_proto_msgTypes[5]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -480,7 +559,7 @@ func (x *Receipt) String() string {
|
|||||||
func (*Receipt) ProtoMessage() {}
|
func (*Receipt) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *Receipt) ProtoReflect() protoreflect.Message {
|
func (x *Receipt) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_proto_nezha_proto_msgTypes[4]
|
mi := &file_proto_nezha_proto_msgTypes[5]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -493,7 +572,7 @@ func (x *Receipt) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use Receipt.ProtoReflect.Descriptor instead.
|
// Deprecated: Use Receipt.ProtoReflect.Descriptor instead.
|
||||||
func (*Receipt) Descriptor() ([]byte, []int) {
|
func (*Receipt) Descriptor() ([]byte, []int) {
|
||||||
return file_proto_nezha_proto_rawDescGZIP(), []int{4}
|
return file_proto_nezha_proto_rawDescGZIP(), []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Receipt) GetProced() bool {
|
func (x *Receipt) GetProced() bool {
|
||||||
@@ -507,7 +586,7 @@ var File_proto_nezha_proto protoreflect.FileDescriptor
|
|||||||
|
|
||||||
var file_proto_nezha_proto_rawDesc = []byte{
|
var file_proto_nezha_proto_rawDesc = []byte{
|
||||||
0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x65, 0x7a, 0x68, 0x61, 0x2e, 0x70, 0x72,
|
0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x65, 0x7a, 0x68, 0x61, 0x2e, 0x70, 0x72,
|
||||||
0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe0, 0x02, 0x0a, 0x04, 0x48,
|
0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf2, 0x02, 0x0a, 0x04, 0x48,
|
||||||
0x6f, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18,
|
0x6f, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18,
|
||||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12,
|
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12,
|
||||||
0x29, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73,
|
0x29, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73,
|
||||||
@@ -529,65 +608,77 @@ var file_proto_nezha_proto_rawDesc = []byte{
|
|||||||
0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65,
|
0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65,
|
||||||
0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43,
|
0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43,
|
||||||
0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c,
|
0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd3, 0x03,
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a,
|
||||||
0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x01,
|
0x03, 0x67, 0x70, 0x75, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x67, 0x70, 0x75, 0x22,
|
||||||
0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x65, 0x6d,
|
0xa9, 0x04, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x70, 0x75,
|
||||||
0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d,
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x19, 0x0a, 0x08, 0x6d,
|
||||||
0x55, 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x75, 0x73, 0x65,
|
0x65, 0x6d, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d,
|
||||||
0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x55, 0x73, 0x65,
|
0x65, 0x6d, 0x55, 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x75,
|
||||||
0x64, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x05,
|
0x73, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x55,
|
||||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x65, 0x64, 0x12, 0x26,
|
0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x75, 0x73, 0x65, 0x64,
|
||||||
0x0a, 0x0f, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
|
0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x65, 0x64,
|
||||||
0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x65, 0x74, 0x49, 0x6e, 0x54, 0x72,
|
0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73,
|
||||||
0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x74, 0x5f, 0x6f, 0x75,
|
0x66, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x65, 0x74, 0x49, 0x6e,
|
||||||
0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04,
|
0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x74, 0x5f,
|
||||||
0x52, 0x0e, 0x6e, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72,
|
0x6f, 0x75, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01,
|
||||||
0x12, 0x20, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64,
|
0x28, 0x04, 0x52, 0x0e, 0x6e, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66,
|
||||||
0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6e, 0x65, 0x74, 0x49, 0x6e, 0x53, 0x70, 0x65,
|
0x65, 0x72, 0x12, 0x20, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x5f, 0x73, 0x70, 0x65,
|
||||||
0x65, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x70,
|
0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6e, 0x65, 0x74, 0x49, 0x6e, 0x53,
|
||||||
0x65, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x4f, 0x75,
|
0x70, 0x65, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x5f,
|
||||||
0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65,
|
0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, 0x74,
|
||||||
0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14,
|
0x4f, 0x75, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69,
|
||||||
0x0a, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x31, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x6c,
|
0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65,
|
||||||
0x6f, 0x61, 0x64, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x35, 0x18, 0x0c, 0x20,
|
0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x31, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||||
0x01, 0x28, 0x01, 0x52, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x35, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x6f,
|
0x05, 0x6c, 0x6f, 0x61, 0x64, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x35, 0x18,
|
||||||
0x61, 0x64, 0x31, 0x35, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x6c, 0x6f, 0x61, 0x64,
|
0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x35, 0x12, 0x16, 0x0a, 0x06,
|
||||||
0x31, 0x35, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x5f, 0x63,
|
0x6c, 0x6f, 0x61, 0x64, 0x31, 0x35, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x6c, 0x6f,
|
||||||
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x74, 0x63, 0x70, 0x43,
|
0x61, 0x64, 0x31, 0x35, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e,
|
||||||
0x6f, 0x6e, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x64, 0x70, 0x5f,
|
0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x74, 0x63,
|
||||||
0x63, 0x6f, 0x6e, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04,
|
0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x64,
|
||||||
0x52, 0x0c, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23,
|
0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01,
|
||||||
0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
0x28, 0x04, 0x52, 0x0c, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74,
|
||||||
0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f,
|
0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
|
||||||
0x75, 0x6e, 0x74, 0x22, 0x3e, 0x0a, 0x04, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
|
||||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74,
|
0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61,
|
||||||
0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
|
0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72,
|
||||||
0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64,
|
0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72,
|
||||||
0x61, 0x74, 0x61, 0x22, 0x7a, 0x0a, 0x0a, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c,
|
0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0c, 0x74, 0x65, 0x6d,
|
||||||
0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69,
|
0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x70, 0x75,
|
||||||
0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
|
0x18, 0x12, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x67, 0x70, 0x75, 0x22, 0x4f, 0x0a, 0x17, 0x53,
|
||||||
0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x03,
|
0x74, 0x61, 0x74, 0x65, 0x5f, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x65,
|
||||||
0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64,
|
0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
||||||
0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12,
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x65,
|
||||||
0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x18, 0x05, 0x20,
|
0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||||
0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x22,
|
0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3e, 0x0a, 0x04,
|
||||||
0x21, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72,
|
0x54, 0x61, 0x73, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
|
||||||
0x6f, 0x63, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x63,
|
0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||||
0x65, 0x64, 0x32, 0xd6, 0x01, 0x0a, 0x0c, 0x4e, 0x65, 0x7a, 0x68, 0x61, 0x53, 0x65, 0x72, 0x76,
|
0x28, 0x04, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
|
||||||
0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x79, 0x73,
|
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x7a, 0x0a, 0x0a,
|
||||||
0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
|
||||||
0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79,
|
||||||
0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f,
|
0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14,
|
||||||
0x72, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0b, 0x2e, 0x70,
|
0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x64,
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
0x65, 0x6c, 0x61, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01,
|
||||||
0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0a, 0x52,
|
0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x63, 0x63,
|
||||||
0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75,
|
||||||
0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0x0e, 0x2e, 0x70,
|
0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x22, 0x21, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x65,
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, 0x12, 0x2b,
|
0x69, 0x70, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x18, 0x01, 0x20,
|
||||||
0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0b, 0x2e,
|
0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x32, 0xd6, 0x01, 0x0a, 0x0c,
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x70, 0x72, 0x6f,
|
0x4e, 0x65, 0x7a, 0x68, 0x61, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x11,
|
||||||
0x74, 0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x42, 0x09, 0x5a, 0x07, 0x2e,
|
0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74,
|
||||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
0x65, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a,
|
||||||
|
0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22,
|
||||||
|
0x00, 0x12, 0x31, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65,
|
||||||
|
0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x6f,
|
||||||
|
0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69,
|
||||||
|
0x70, 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61,
|
||||||
|
0x73, 0x6b, 0x12, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52,
|
||||||
|
0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65,
|
||||||
|
0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||||
|
0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48,
|
||||||
|
0x6f, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b,
|
||||||
|
0x22, 0x00, 0x30, 0x01, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||||
|
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -602,28 +693,30 @@ func file_proto_nezha_proto_rawDescGZIP() []byte {
|
|||||||
return file_proto_nezha_proto_rawDescData
|
return file_proto_nezha_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_proto_nezha_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
var file_proto_nezha_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||||
var file_proto_nezha_proto_goTypes = []interface{}{
|
var file_proto_nezha_proto_goTypes = []interface{}{
|
||||||
(*Host)(nil), // 0: proto.Host
|
(*Host)(nil), // 0: proto.Host
|
||||||
(*State)(nil), // 1: proto.State
|
(*State)(nil), // 1: proto.State
|
||||||
(*Task)(nil), // 2: proto.Task
|
(*State_SensorTemperature)(nil), // 2: proto.State_SensorTemperature
|
||||||
(*TaskResult)(nil), // 3: proto.TaskResult
|
(*Task)(nil), // 3: proto.Task
|
||||||
(*Receipt)(nil), // 4: proto.Receipt
|
(*TaskResult)(nil), // 4: proto.TaskResult
|
||||||
|
(*Receipt)(nil), // 5: proto.Receipt
|
||||||
}
|
}
|
||||||
var file_proto_nezha_proto_depIdxs = []int32{
|
var file_proto_nezha_proto_depIdxs = []int32{
|
||||||
1, // 0: proto.NezhaService.ReportSystemState:input_type -> proto.State
|
2, // 0: proto.State.temperatures:type_name -> proto.State_SensorTemperature
|
||||||
0, // 1: proto.NezhaService.ReportSystemInfo:input_type -> proto.Host
|
1, // 1: proto.NezhaService.ReportSystemState:input_type -> proto.State
|
||||||
3, // 2: proto.NezhaService.ReportTask:input_type -> proto.TaskResult
|
0, // 2: proto.NezhaService.ReportSystemInfo:input_type -> proto.Host
|
||||||
0, // 3: proto.NezhaService.RequestTask:input_type -> proto.Host
|
4, // 3: proto.NezhaService.ReportTask:input_type -> proto.TaskResult
|
||||||
4, // 4: proto.NezhaService.ReportSystemState:output_type -> proto.Receipt
|
0, // 4: proto.NezhaService.RequestTask:input_type -> proto.Host
|
||||||
4, // 5: proto.NezhaService.ReportSystemInfo:output_type -> proto.Receipt
|
5, // 5: proto.NezhaService.ReportSystemState:output_type -> proto.Receipt
|
||||||
4, // 6: proto.NezhaService.ReportTask:output_type -> proto.Receipt
|
5, // 6: proto.NezhaService.ReportSystemInfo:output_type -> proto.Receipt
|
||||||
2, // 7: proto.NezhaService.RequestTask:output_type -> proto.Task
|
5, // 7: proto.NezhaService.ReportTask:output_type -> proto.Receipt
|
||||||
4, // [4:8] is the sub-list for method output_type
|
3, // 8: proto.NezhaService.RequestTask:output_type -> proto.Task
|
||||||
0, // [0:4] is the sub-list for method input_type
|
5, // [5:9] is the sub-list for method output_type
|
||||||
0, // [0:0] is the sub-list for extension type_name
|
1, // [1:5] is the sub-list for method input_type
|
||||||
0, // [0:0] is the sub-list for extension extendee
|
1, // [1:1] is the sub-list for extension type_name
|
||||||
0, // [0:0] is the sub-list for field type_name
|
1, // [1:1] is the sub-list for extension extendee
|
||||||
|
0, // [0:1] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_proto_nezha_proto_init() }
|
func init() { file_proto_nezha_proto_init() }
|
||||||
@@ -657,7 +750,7 @@ func file_proto_nezha_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_proto_nezha_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
file_proto_nezha_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*Task); i {
|
switch v := v.(*State_SensorTemperature); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
case 1:
|
case 1:
|
||||||
@@ -669,7 +762,7 @@ func file_proto_nezha_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_proto_nezha_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
file_proto_nezha_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*TaskResult); i {
|
switch v := v.(*Task); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
case 1:
|
case 1:
|
||||||
@@ -681,6 +774,18 @@ func file_proto_nezha_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_proto_nezha_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
file_proto_nezha_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*TaskResult); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_proto_nezha_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*Receipt); i {
|
switch v := v.(*Receipt); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@@ -699,7 +804,7 @@ func file_proto_nezha_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_proto_nezha_proto_rawDesc,
|
RawDescriptor: file_proto_nezha_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 5,
|
NumMessages: 6,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ message Host {
|
|||||||
string ip = 10;
|
string ip = 10;
|
||||||
string country_code = 11;
|
string country_code = 11;
|
||||||
string version = 12;
|
string version = 12;
|
||||||
|
repeated string gpu = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
message State {
|
message State {
|
||||||
@@ -41,6 +42,13 @@ message State {
|
|||||||
uint64 tcp_conn_count = 14;
|
uint64 tcp_conn_count = 14;
|
||||||
uint64 udp_conn_count = 15;
|
uint64 udp_conn_count = 15;
|
||||||
uint64 process_count = 16;
|
uint64 process_count = 16;
|
||||||
|
repeated State_SensorTemperature temperatures = 17;
|
||||||
|
double gpu = 18;
|
||||||
|
}
|
||||||
|
|
||||||
|
message State_SensorTemperature {
|
||||||
|
string name = 1;
|
||||||
|
double temperature = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Task {
|
message Task {
|
||||||
|
|||||||
Vendored
+27
-12
@@ -32,10 +32,10 @@ other = "Logout"
|
|||||||
other = "Login"
|
other = "Login"
|
||||||
|
|
||||||
[ConfirmLogout]
|
[ConfirmLogout]
|
||||||
other = "Confirm Logout?"
|
other = "Do you want to Logout?"
|
||||||
|
|
||||||
[AfterLoggingOutYouHaveToLoginAgain]
|
[AfterLoggingOutYouHaveToLoginAgain]
|
||||||
other = "You need to login again after logout to continue"
|
other = "You need to Login again to continue"
|
||||||
|
|
||||||
[Cancel]
|
[Cancel]
|
||||||
other = "Cancel"
|
other = "Cancel"
|
||||||
@@ -227,7 +227,7 @@ other = "Secret"
|
|||||||
other = "Note"
|
other = "Note"
|
||||||
|
|
||||||
[LinuxOneKeyInstall]
|
[LinuxOneKeyInstall]
|
||||||
other = "Linux One-Key Install"
|
other = "Linux One-Command Install"
|
||||||
|
|
||||||
[NoDomainAlert]
|
[NoDomainAlert]
|
||||||
other = "Set CDN bypassed Domain/IP in setting before using this function"
|
other = "Set CDN bypassed Domain/IP in setting before using this function"
|
||||||
@@ -257,7 +257,7 @@ other = "Execute by Trigger"
|
|||||||
other = "Delete Scheduled Task"
|
other = "Delete Scheduled Task"
|
||||||
|
|
||||||
[ConfirmToDeleteThisScheduledTask]
|
[ConfirmToDeleteThisScheduledTask]
|
||||||
other = "Confirm Delete?"
|
other = "Are you sure you want to Delete?"
|
||||||
|
|
||||||
[AccessDenied]
|
[AccessDenied]
|
||||||
other = "Access Denied"
|
other = "Access Denied"
|
||||||
@@ -293,7 +293,7 @@ other = "Delete Notification Method"
|
|||||||
other = "Confirm to Delete This Notification Method?"
|
other = "Confirm to Delete This Notification Method?"
|
||||||
|
|
||||||
[ForceUpdate]
|
[ForceUpdate]
|
||||||
other = "Force Update"
|
other = "Force to Update"
|
||||||
|
|
||||||
[SelectAll]
|
[SelectAll]
|
||||||
other = "Select All"
|
other = "Select All"
|
||||||
@@ -302,7 +302,7 @@ other = "Select All"
|
|||||||
other = "Version"
|
other = "Version"
|
||||||
|
|
||||||
[OneKeyInstall]
|
[OneKeyInstall]
|
||||||
other = "One-Key Install"
|
other = "One-Command Install"
|
||||||
|
|
||||||
[ClickToCopy]
|
[ClickToCopy]
|
||||||
other = "Click To Copy"
|
other = "Click To Copy"
|
||||||
@@ -398,7 +398,7 @@ other = "Virtualization"
|
|||||||
other = "Swap"
|
other = "Swap"
|
||||||
|
|
||||||
[NetTransfer]
|
[NetTransfer]
|
||||||
other = "Transfer"
|
other = "Usage"
|
||||||
|
|
||||||
[Load]
|
[Load]
|
||||||
other = "Load"
|
other = "Load"
|
||||||
@@ -419,7 +419,7 @@ other = "Last Active"
|
|||||||
other = "Version"
|
other = "Version"
|
||||||
|
|
||||||
[NetSpeed]
|
[NetSpeed]
|
||||||
other = "Speed"
|
other = "NIC"
|
||||||
|
|
||||||
[Uptime]
|
[Uptime]
|
||||||
other = "Uptime"
|
other = "Uptime"
|
||||||
@@ -473,7 +473,7 @@ other = "Next check"
|
|||||||
other = "Current Usage"
|
other = "Current Usage"
|
||||||
|
|
||||||
[VerifyPassword]
|
[VerifyPassword]
|
||||||
other = "Verify Password"
|
other = "Please enter your password"
|
||||||
|
|
||||||
[LightMode]
|
[LightMode]
|
||||||
other = "Light Mode"
|
other = "Light Mode"
|
||||||
@@ -482,7 +482,7 @@ other = "Light Mode"
|
|||||||
other = "Dark Mode"
|
other = "Dark Mode"
|
||||||
|
|
||||||
[FollowSystem]
|
[FollowSystem]
|
||||||
other = "Follow System"
|
other = "System Auto"
|
||||||
|
|
||||||
[GridLayout]
|
[GridLayout]
|
||||||
other = "Grid Layout"
|
other = "Grid Layout"
|
||||||
@@ -619,9 +619,18 @@ other = "Enable Show in Service"
|
|||||||
[EnableDDNS]
|
[EnableDDNS]
|
||||||
other = "Enable DDNS"
|
other = "Enable DDNS"
|
||||||
|
|
||||||
|
[EnableIPv4]
|
||||||
|
other = "Enable DDNS IPv4"
|
||||||
|
|
||||||
|
[EnableIpv6]
|
||||||
|
other = "Enable DDNS IPv6"
|
||||||
|
|
||||||
[DDNSDomain]
|
[DDNSDomain]
|
||||||
other = "DDNS Domain"
|
other = "DDNS Domain"
|
||||||
|
|
||||||
|
[DDNSProfile]
|
||||||
|
other = "DDNS Profile Name"
|
||||||
|
|
||||||
[Feature]
|
[Feature]
|
||||||
other = "Feature"
|
other = "Feature"
|
||||||
|
|
||||||
@@ -629,7 +638,13 @@ other = "Feature"
|
|||||||
other = "Template"
|
other = "Template"
|
||||||
|
|
||||||
[Stat]
|
[Stat]
|
||||||
other = "Stat"
|
other = "Asset"
|
||||||
|
|
||||||
|
[Temperature]
|
||||||
|
other = "Temperature"
|
||||||
|
|
||||||
[DisableSwitchTemplateInFrontend]
|
[DisableSwitchTemplateInFrontend]
|
||||||
other = "Disable Switch Template in Frontend"
|
other = "Disable Switch Template in Frontend"
|
||||||
|
|
||||||
|
[ServersOnWorldMap]
|
||||||
|
other = "Servers On World Map"
|
||||||
|
|||||||
Vendored
+16
-1
@@ -619,9 +619,18 @@ other = "Mostrar en servicio"
|
|||||||
[EnableDDNS]
|
[EnableDDNS]
|
||||||
other = "Habilitar DDNS"
|
other = "Habilitar DDNS"
|
||||||
|
|
||||||
|
[EnableIPv4]
|
||||||
|
other = "Habilitar DDNS IPv4"
|
||||||
|
|
||||||
|
[EnableIpv6]
|
||||||
|
other = "Habilitar DDNS IPv6"
|
||||||
|
|
||||||
[DDNSDomain]
|
[DDNSDomain]
|
||||||
other = "Dominio DDNS"
|
other = "Dominio DDNS"
|
||||||
|
|
||||||
|
[DDNSProfile]
|
||||||
|
other = "Nombre del perfil de DDNS"
|
||||||
|
|
||||||
[Feature]
|
[Feature]
|
||||||
other = "Característica"
|
other = "Característica"
|
||||||
|
|
||||||
@@ -631,5 +640,11 @@ other = "Plantilla"
|
|||||||
[Stat]
|
[Stat]
|
||||||
other = "Stat"
|
other = "Stat"
|
||||||
|
|
||||||
|
[Temperature]
|
||||||
|
other = "Temperatura"
|
||||||
|
|
||||||
[DisableSwitchTemplateInFrontend]
|
[DisableSwitchTemplateInFrontend]
|
||||||
other = "Deshabilitar Cambio de Plantilla en Frontend"
|
other = "Deshabilitar Cambio de Plantilla en Frontend"
|
||||||
|
|
||||||
|
[ServersOnWorldMap]
|
||||||
|
other = "Servidores en el mapa mundial"
|
||||||
Vendored
+15
@@ -619,9 +619,18 @@ other = "在服务中显示"
|
|||||||
[EnableDDNS]
|
[EnableDDNS]
|
||||||
other = "启用DDNS"
|
other = "启用DDNS"
|
||||||
|
|
||||||
|
[EnableIPv4]
|
||||||
|
other = "启用DDNS IPv4"
|
||||||
|
|
||||||
|
[EnableIpv6]
|
||||||
|
other = "启用DDNS IPv6"
|
||||||
|
|
||||||
[DDNSDomain]
|
[DDNSDomain]
|
||||||
other = "DDNS域名"
|
other = "DDNS域名"
|
||||||
|
|
||||||
|
[DDNSProfile]
|
||||||
|
other = "DDNS配置名"
|
||||||
|
|
||||||
[Feature]
|
[Feature]
|
||||||
other = "功能"
|
other = "功能"
|
||||||
|
|
||||||
@@ -631,5 +640,11 @@ other = "主题"
|
|||||||
[Stat]
|
[Stat]
|
||||||
other = "信息"
|
other = "信息"
|
||||||
|
|
||||||
|
[Temperature]
|
||||||
|
other = "温度"
|
||||||
|
|
||||||
[DisableSwitchTemplateInFrontend]
|
[DisableSwitchTemplateInFrontend]
|
||||||
other = "禁止前台切换模板"
|
other = "禁止前台切换模板"
|
||||||
|
|
||||||
|
[ServersOnWorldMap]
|
||||||
|
other = "服务器世界分布图"
|
||||||
|
|||||||
Vendored
+15
@@ -619,9 +619,18 @@ other = "在服務中顯示"
|
|||||||
[EnableDDNS]
|
[EnableDDNS]
|
||||||
other = "啟用DDNS"
|
other = "啟用DDNS"
|
||||||
|
|
||||||
|
[EnableIPv4]
|
||||||
|
other = "啟用DDNS IPv4"
|
||||||
|
|
||||||
|
[EnableIpv6]
|
||||||
|
other = "啟用DDNS IPv6"
|
||||||
|
|
||||||
[DDNSDomain]
|
[DDNSDomain]
|
||||||
other = "DDNS網域"
|
other = "DDNS網域"
|
||||||
|
|
||||||
|
[DDNSProfile]
|
||||||
|
other = "DDNS設定名"
|
||||||
|
|
||||||
[Feature]
|
[Feature]
|
||||||
other = "功能"
|
other = "功能"
|
||||||
|
|
||||||
@@ -631,5 +640,11 @@ other = "主題"
|
|||||||
[Stat]
|
[Stat]
|
||||||
other = "信息"
|
other = "信息"
|
||||||
|
|
||||||
|
[Temperature]
|
||||||
|
other = "溫度"
|
||||||
|
|
||||||
[DisableSwitchTemplateInFrontend]
|
[DisableSwitchTemplateInFrontend]
|
||||||
other = "禁止前台切換主題"
|
other = "禁止前台切換主題"
|
||||||
|
|
||||||
|
[ServersOnWorldMap]
|
||||||
|
other = "伺服器世界分布圖"
|
||||||
|
|||||||
@@ -303,6 +303,7 @@ function addOrEditServer(server, conf) {
|
|||||||
modal.find("input[name=name]").val(server ? server.Name : null);
|
modal.find("input[name=name]").val(server ? server.Name : null);
|
||||||
modal.find("input[name=Tag]").val(server ? server.Tag : null);
|
modal.find("input[name=Tag]").val(server ? server.Tag : null);
|
||||||
modal.find("input[name=DDNSDomain]").val(server ? server.DDNSDomain : null);
|
modal.find("input[name=DDNSDomain]").val(server ? server.DDNSDomain : null);
|
||||||
|
modal.find("input[name=DDNSProfile]").val(server ? server.DDNSProfile : null);
|
||||||
modal
|
modal
|
||||||
.find("input[name=DisplayIndex]")
|
.find("input[name=DisplayIndex]")
|
||||||
.val(server ? server.DisplayIndex : null);
|
.val(server ? server.DisplayIndex : null);
|
||||||
@@ -327,6 +328,16 @@ function addOrEditServer(server, conf) {
|
|||||||
} else {
|
} else {
|
||||||
modal.find(".ui.enableddns.checkbox").checkbox("set unchecked");
|
modal.find(".ui.enableddns.checkbox").checkbox("set unchecked");
|
||||||
}
|
}
|
||||||
|
if (server && server.EnableIPv4) {
|
||||||
|
modal.find(".ui.enableipv4.checkbox").checkbox("set checked");
|
||||||
|
} else {
|
||||||
|
modal.find(".ui.enableipv4.checkbox").checkbox("set unchecked");
|
||||||
|
}
|
||||||
|
if (server && server.EnableIpv6) {
|
||||||
|
modal.find(".ui.enableipv6.checkbox").checkbox("set checked");
|
||||||
|
} else {
|
||||||
|
modal.find(".ui.enableipv6.checkbox").checkbox("set unchecked");
|
||||||
|
}
|
||||||
showFormModal(".server.modal", "#serverForm", "/api/server");
|
showFormModal(".server.modal", "#serverForm", "/api/server");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
@@ -145,6 +145,10 @@ td {
|
|||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.temp-detail {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.ui.content {
|
.ui.content {
|
||||||
margin:0 !important;
|
margin:0 !important;
|
||||||
padding:1em !important;
|
padding:1em !important;
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ const mixinsVue = {
|
|||||||
adaptedTemplates: [
|
adaptedTemplates: [
|
||||||
{ key: 'default', name: 'Default', icon: 'th large' },
|
{ key: 'default', name: 'Default', icon: 'th large' },
|
||||||
{ key: 'angel-kanade', name: 'AngelKanade', icon: 'square' },
|
{ key: 'angel-kanade', name: 'AngelKanade', icon: 'square' },
|
||||||
{ key: 'server-status', name: 'SeverStatus', icon: 'list' }
|
{ key: 'server-status', name: 'ServerStatus', icon: 'list' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
@@ -157,3 +157,16 @@ body[theme="dark"] footer p a:hover {
|
|||||||
color: #f1f1f1;
|
color: #f1f1f1;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body[theme="dark"] .modal-content{
|
||||||
|
background-color: #1c1d26;
|
||||||
|
color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[theme="dark"] .modal-header{
|
||||||
|
border-bottom-color:#080808;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[theme="dark"] .modal-header i{
|
||||||
|
color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -131,4 +131,17 @@ body[theme="light"] footer p a,
|
|||||||
body[theme="light"] footer p a:hover {
|
body[theme="light"] footer p a:hover {
|
||||||
color: #333333;
|
color: #333333;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[theme="light"] .modal-content{
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: rgba(0, 0, 0, 0.87);
|
||||||
|
}
|
||||||
|
|
||||||
|
body[theme="light"] .modal-header{
|
||||||
|
border-bottom-color:#f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[theme="light"] .modal-header i{
|
||||||
|
color: rgba(0, 0, 0, 0.87);
|
||||||
}
|
}
|
||||||
+49
-3
@@ -230,6 +230,10 @@ body {
|
|||||||
max-width: 50px;
|
max-width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.temp-detail {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
/*正文结束*/
|
/*正文结束*/
|
||||||
|
|
||||||
/* 服务页 正文*/
|
/* 服务页 正文*/
|
||||||
@@ -281,10 +285,42 @@ body {
|
|||||||
.service-status .tooltip-inner {
|
.service-status .tooltip-inner {
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* 服务页 正文结束 */
|
/* 服务页 正文结束 */
|
||||||
|
|
||||||
|
|
||||||
|
/* 服务器分布图 */
|
||||||
|
#mapChartBox{
|
||||||
|
z-index: 999999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-dialog-centered{
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 1134px;
|
||||||
|
max-width: 1134px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center; /* 垂直居中 */
|
||||||
|
justify-content: center; /* 水平居中 */
|
||||||
|
min-height: calc(100%) /* 确保模态框占据整个视口高度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header i{
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
font-size: 2em;
|
||||||
|
top: 13px;
|
||||||
|
right: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 1200px) {
|
@media only screen and (max-width: 1200px) {
|
||||||
.accordian-body{
|
.accordian-body{
|
||||||
margin: 5px 0px 5px 10px;
|
margin: 5px 0px 5px 10px;
|
||||||
@@ -365,6 +401,16 @@ body {
|
|||||||
.toolbox {
|
.toolbox {
|
||||||
right: 18px;
|
right: 18px;
|
||||||
}
|
}
|
||||||
|
.modal-dialog-centered{
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
.modal-title{
|
||||||
|
line-height: 0.5;
|
||||||
|
}
|
||||||
|
.modal-header i{
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 768px) {
|
@media only screen and (min-width: 768px) {
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@
|
|||||||
/** Name of the expando, to work with multiple documents or to re-shiv one document */
|
/** Name of the expando, to work with multiple documents or to re-shiv one document */
|
||||||
var expando = '_html5shiv';
|
var expando = '_html5shiv';
|
||||||
|
|
||||||
/** The id for the the documents expando */
|
/** The id for the documents expando */
|
||||||
var expanID = 0;
|
var expanID = 0;
|
||||||
|
|
||||||
/** Cached data for each document */
|
/** Cached data for each document */
|
||||||
|
|||||||
+31
-53
@@ -7,16 +7,17 @@ const mixinsVue = {
|
|||||||
showGoTop: false,
|
showGoTop: false,
|
||||||
preferredTemplate: null,
|
preferredTemplate: null,
|
||||||
isMobile: false,
|
isMobile: false,
|
||||||
|
staticUrl: '/static/theme-server-status',
|
||||||
adaptedTemplates: [
|
adaptedTemplates: [
|
||||||
{ key: 'default', name: 'Default', icon: 'th large' },
|
{ key: 'default', name: 'Default', icon: 'th large' },
|
||||||
{ key: 'angel-kanade', name: 'AngelKanade', icon: 'square' },
|
{ key: 'angel-kanade', name: 'AngelKanade', icon: 'square' },
|
||||||
{ key: 'server-status', name: 'SeverStatus', icon: 'list' }
|
{ key: 'server-status', name: 'ServerStatus', icon: 'list' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.isMobile = this.checkIsMobile();
|
this.isMobile = this.checkIsMobile();
|
||||||
this.initTheme();
|
this.theme = this.initTheme();
|
||||||
this.storedShowGroup();
|
this.showGroup = this.initShowGroup();
|
||||||
this.preferredTemplate = this.getCookie('preferred_theme') ? this.getCookie('preferred_theme') : this.$root.defaultTemplate;
|
this.preferredTemplate = this.getCookie('preferred_theme') ? this.getCookie('preferred_theme') : this.$root.defaultTemplate;
|
||||||
window.addEventListener('scroll', this.handleScroll);
|
window.addEventListener('scroll', this.handleScroll);
|
||||||
},
|
},
|
||||||
@@ -24,22 +25,36 @@ const mixinsVue = {
|
|||||||
window.removeEventListener('scroll', this.handleScroll);
|
window.removeEventListener('scroll', this.handleScroll);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleView() {
|
initTheme() {
|
||||||
this.showGroup = !this.showGroup;
|
const storedTheme = localStorage.getItem("theme");
|
||||||
localStorage.setItem("showGroup", JSON.stringify(this.showGroup));
|
const theme = (storedTheme === 'dark' || storedTheme === 'light') ? storedTheme : (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
||||||
return this.showGroup;
|
this.setTheme(theme);
|
||||||
|
return theme;
|
||||||
},
|
},
|
||||||
storedShowGroup() {
|
setTheme(theme) {
|
||||||
|
document.body.setAttribute("theme", theme);
|
||||||
|
this.theme = theme;
|
||||||
|
localStorage.setItem("theme", theme);
|
||||||
|
// 重新赋值全局调色
|
||||||
|
this.colors = this.theme == "dark" ? this.colorsDark : this.colorsLight;
|
||||||
|
|
||||||
|
if(this.$root.page == 'index') {
|
||||||
|
this.reloadCharts(); // 重新载入echarts图表
|
||||||
|
}
|
||||||
|
},
|
||||||
|
initShowGroup() {
|
||||||
const storedShowGroup = localStorage.getItem("showGroup");
|
const storedShowGroup = localStorage.getItem("showGroup");
|
||||||
if (storedShowGroup !== null) {
|
const showGroup = storedShowGroup !== null ? JSON.parse(storedShowGroup) : false;
|
||||||
this.showGroup = JSON.parse(storedShowGroup);
|
if (storedShowGroup === null) {
|
||||||
}
|
localStorage.setItem("showGroup", showGroup);
|
||||||
|
}
|
||||||
|
return showGroup;
|
||||||
},
|
},
|
||||||
toggleTemplate(template) {
|
toggleShowGroup() {
|
||||||
if( template != this.preferredTemplate){
|
this.showGroup = !this.showGroup;
|
||||||
this.preferredTemplate = template;
|
localStorage.setItem("showGroup", this.showGroup);
|
||||||
this.updateCookie("preferred_theme", template);
|
if (this.$root.page == 'service') {
|
||||||
window.location.reload();
|
this.$root.initTooltip();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateCookie(name, value) {
|
updateCookie(name, value) {
|
||||||
@@ -57,43 +72,6 @@ const mixinsVue = {
|
|||||||
}
|
}
|
||||||
return cookieValue;
|
return cookieValue;
|
||||||
},
|
},
|
||||||
setTheme(title, store = false) {
|
|
||||||
this.theme = title;
|
|
||||||
document.body.setAttribute("theme", title);
|
|
||||||
if (store) {
|
|
||||||
localStorage.setItem("theme", title);
|
|
||||||
this.isSystemTheme = false;
|
|
||||||
if(this.$root.page == 'index') {
|
|
||||||
this.$root.reloadCharts(); //重新载入echarts图表
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setSystemTheme() {
|
|
||||||
localStorage.removeItem("theme");
|
|
||||||
this.initTheme();
|
|
||||||
this.isSystemTheme = true;
|
|
||||||
},
|
|
||||||
initTheme() {
|
|
||||||
const storeTheme = localStorage.getItem("theme");
|
|
||||||
if (storeTheme === 'dark' || storeTheme === 'light') {
|
|
||||||
this.setTheme(storeTheme, true);
|
|
||||||
} else {
|
|
||||||
this.isSystemTheme = true
|
|
||||||
const handleChange = (mediaQueryListEvent) => {
|
|
||||||
if (localStorage.getItem("theme")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (mediaQueryListEvent.matches) {
|
|
||||||
this.setTheme('dark');
|
|
||||||
} else {
|
|
||||||
this.setTheme('light');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const mediaQueryListDark = window.matchMedia('(prefers-color-scheme: dark)');
|
|
||||||
this.setTheme(mediaQueryListDark.matches ? 'dark' : 'light');
|
|
||||||
mediaQueryListDark.addEventListener("change", handleChange);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toFixed2(f) {
|
toFixed2(f) {
|
||||||
return f.toFixed(2)
|
return f.toFixed(2)
|
||||||
},
|
},
|
||||||
|
|||||||
+1277
File diff suppressed because it is too large
Load Diff
+243
File diff suppressed because one or more lines are too long
+242
File diff suppressed because one or more lines are too long
+245
File diff suppressed because one or more lines are too long
+244
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/semantic-ui/2.4.1/semantic.min.js"></script>
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/semantic-ui/2.4.1/semantic.min.js"></script>
|
||||||
<script src="/static/semantic-ui-alerts.min.js"></script>
|
<script src="/static/semantic-ui-alerts.min.js"></script>
|
||||||
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/vue/2.6.14/vue.min.js"></script>
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/vue/2.6.14/vue.min.js"></script>
|
||||||
<script src="/static/main.js?v20240224"></script>
|
<script src="/static/main.js?v20240330"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
updateLang({{.LANG }});
|
updateLang({{.LANG }});
|
||||||
|
|||||||
+17
-1
@@ -32,10 +32,26 @@
|
|||||||
<label>{{tr "EnableDDNS"}}</label>
|
<label>{{tr "EnableDDNS"}}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui enableipv4 checkbox">
|
||||||
|
<input name="EnableIPv4" type="checkbox" tabindex="0" />
|
||||||
|
<label>{{tr "EnableIPv4"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui enableipv6 checkbox">
|
||||||
|
<input name="EnableIpv6" type="checkbox" tabindex="0" />
|
||||||
|
<label>{{tr "EnableIpv6"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "DDNSDomain"}}</label>
|
<label>{{tr "DDNSDomain"}}</label>
|
||||||
<input type="text" name="DDNSDomain" placeholder="{{tr "DDNSDomain"}}">
|
<input type="text" name="DDNSDomain" placeholder="{{tr "DDNSDomain"}}">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label>{{tr "DDNSProfile"}}</label>
|
||||||
|
<input type="text" name="DDNSProfile" placeholder="{{tr "DDNSProfile"}}">
|
||||||
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>{{tr "Note"}}</label>
|
<label>{{tr "Note"}}</label>
|
||||||
<textarea name="Note"></textarea>
|
<textarea name="Note"></textarea>
|
||||||
@@ -45,7 +61,7 @@
|
|||||||
<div class="ui message">
|
<div class="ui message">
|
||||||
{{if .Conf.GRPCHost}}
|
{{if .Conf.GRPCHost}}
|
||||||
curl -L https://raw.githubusercontent.com/naiba/nezha/master/script/install.sh -o nezha.sh && chmod
|
curl -L https://raw.githubusercontent.com/naiba/nezha/master/script/install.sh -o nezha.sh && chmod
|
||||||
+x nezha.sh && sudo ./nezha.sh install_agent <code class="command">{{.Conf.GRPCHost}}</code> <code
|
+x nezha.sh && ./nezha.sh install_agent <code class="command">{{.Conf.GRPCHost}}</code> <code
|
||||||
class="command">{{if .Conf.ProxyGRPCPort}}{{.Conf.ProxyGRPCPort}}{{else}}{{.Conf.GRPCPort}}{{end}}</code> <code
|
class="command">{{if .Conf.ProxyGRPCPort}}{{.Conf.ProxyGRPCPort}}{{else}}{{.Conf.GRPCPort}}{{end}}</code> <code
|
||||||
class="command hostSecret"></code> <code class="command">{{if .Conf.TLS}}--tls{{end}}</code>
|
class="command hostSecret"></code> <code class="command">{{if .Conf.TLS}}--tls{{end}}</code>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
<th>{{tr "VersionNumber"}}</th>
|
<th>{{tr "VersionNumber"}}</th>
|
||||||
<th>{{tr "HideForGuest"}}</th>
|
<th>{{tr "HideForGuest"}}</th>
|
||||||
<th>{{tr "EnableDDNS"}}</th>
|
<th>{{tr "EnableDDNS"}}</th>
|
||||||
|
<th>{{tr "EnableIPv4"}}</th>
|
||||||
|
<th>{{tr "EnableIpv6"}}</th>
|
||||||
<th>{{tr "DDNSDomain"}}</th>
|
<th>{{tr "DDNSDomain"}}</th>
|
||||||
<th>{{tr "Secret"}}</th>
|
<th>{{tr "Secret"}}</th>
|
||||||
<th>{{tr "OneKeyInstall"}}</th>
|
<th>{{tr "OneKeyInstall"}}</th>
|
||||||
@@ -48,6 +50,8 @@
|
|||||||
<td>{{$server.Host.Version}}</td>
|
<td>{{$server.Host.Version}}</td>
|
||||||
<td>{{$server.HideForGuest}}</td>
|
<td>{{$server.HideForGuest}}</td>
|
||||||
<td>{{$server.EnableDDNS}}</td>
|
<td>{{$server.EnableDDNS}}</td>
|
||||||
|
<td>{{$server.EnableIPv4}}</td>
|
||||||
|
<td>{{$server.EnableIpv6}}</td>
|
||||||
<td>{{$server.DDNSDomain}}</td>
|
<td>{{$server.DDNSDomain}}</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="ui icon green mini button" data-clipboard-text="{{$server.Secret}}" data-tooltip="{{tr "ClickToCopy"}}">
|
<button class="ui icon green mini button" data-clipboard-text="{{$server.Secret}}" data-tooltip="{{tr "ClickToCopy"}}">
|
||||||
@@ -65,6 +69,11 @@
|
|||||||
data-tooltip="{{tr "ClickToCopy"}}">
|
data-tooltip="{{tr "ClickToCopy"}}">
|
||||||
<i class="windows icon"></i>
|
<i class="windows icon"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="ui icon green mini button"
|
||||||
|
data-clipboard-text="{{if $.Conf.GRPCHost}}curl -L https://raw.githubusercontent.com/naiba/nezha/master/script/install.command -o nezha.command && chmod +x nezha.command && sudo ./nezha.command install_agent {{$.Conf.GRPCHost}} {{if $.Conf.ProxyGRPCPort}}{{$.Conf.ProxyGRPCPort}}{{else}}{{$.Conf.GRPCPort}}{{end}} {{$server.Secret}}{{if $.Conf.TLS}} --tls{{end}}{{else}}{{tr "NoDomainAlert"}}{{end}}"
|
||||||
|
data-tooltip="{{tr "ClickToCopy"}}">
|
||||||
|
<i class="apple icon"></i>
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td style="word-break: break-word;white-space: pre-wrap;">{{$server.Note}}</td>
|
<td style="word-break: break-word;white-space: pre-wrap;">{{$server.Note}}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@
|
|||||||
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/semantic-ui/2.4.1/semantic.min.js"></script>
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/semantic-ui/2.4.1/semantic.min.js"></script>
|
||||||
<script src="/static/semantic-ui-alerts.min.js"></script>
|
<script src="/static/semantic-ui-alerts.min.js"></script>
|
||||||
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/vue/2.6.14/vue.min.js"></script>
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/vue/2.6.14/vue.min.js"></script>
|
||||||
<script src="/static/main.js?v20240224"></script>
|
<script src="/static/main.js?v20240330"></script>
|
||||||
<script src="/static/theme-default/js/mixin.js?v20240302"></script>
|
<script src="/static/theme-default/js/mixin.js?v20240302"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
[<span
|
[<span
|
||||||
v-if="server.Host.Virtualization">@#server.Host.Virtualization#@:</span>@#server.Host.Arch#@]<br />
|
v-if="server.Host.Virtualization">@#server.Host.Virtualization#@:</span>@#server.Host.Arch#@]<br />
|
||||||
CPU: @#server.Host.CPU#@<br />
|
CPU: @#server.Host.CPU#@<br />
|
||||||
|
<template v-if="server.Host.GPU">
|
||||||
|
GPU: @#server.Host.GPU#@
|
||||||
|
</template>
|
||||||
{{tr "DiskUsed"}}:
|
{{tr "DiskUsed"}}:
|
||||||
@#formatByteSize(server.State.DiskUsed)#@/@#formatByteSize(server.Host.DiskTotal)#@<br />
|
@#formatByteSize(server.State.DiskUsed)#@/@#formatByteSize(server.Host.DiskTotal)#@<br />
|
||||||
{{tr "MemUsed"}}:
|
{{tr "MemUsed"}}:
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
<i :class="item.icon + ' icon'"></i>@#item.name#@
|
<i :class="item.icon + ' icon'"></i>@#item.name#@
|
||||||
<i class="check icon" v-if="preferredTemplate === item.key"></i>
|
<i class="check icon" v-if="preferredTemplate === item.key"></i>
|
||||||
</a>
|
</a>
|
||||||
|
<a v-if="defaultTemplate === 'custom'" @click="toggleTemplate('custom')" class="item">
|
||||||
|
<i class="expand icon"></i>Custom
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
+153
-128
@@ -20,101 +20,101 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body data-theme="light" data-gridlist="grid">
|
<body data-theme="light" data-gridlist="grid">
|
||||||
<header>
|
<header>
|
||||||
<section class="nav-bar clearfix">
|
<section class="nav-bar clearfix">
|
||||||
<figure class="logo">
|
<figure class="logo">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="/static/logo.svg?v20210804" alt='{{tr "NezhaMonitoring"}}' width="50" height="50">
|
<img src="/static/logo.svg?v20210804" alt='{{tr "NezhaMonitoring"}}' width="50" height="50">
|
||||||
</a>
|
</a>
|
||||||
<a href="/">{{.Conf.Site.Brand}}</a>
|
<a href="/">{{.Conf.Site.Brand}}</a>
|
||||||
</figure>
|
</figure>
|
||||||
<div class="icon-container">
|
<div class="icon-container">
|
||||||
<div class="row cf">
|
<div class="row cf">
|
||||||
<div class="three col">
|
<div class="three col">
|
||||||
<div class="hamburger" id="hamburger-icon"><span class="line"></span><span
|
<div class="hamburger" id="hamburger-icon"><span class="line"></span><span
|
||||||
class="line"></span><span class="line"></span></div>
|
class="line"></span><span class="line"></span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<nav class="nav-menu">
|
||||||
|
<ul>
|
||||||
|
<li><a href="/">{{tr "Home"}}</a></li>
|
||||||
|
<li><a href="/service">{{tr "Services"}}</a></li>
|
||||||
|
<li><a href="/network">{{tr "NetworkSpiter"}}</a></li>
|
||||||
|
{{if .Admin}}
|
||||||
|
<li><a href="/server">{{tr "AdminPanel"}}</a></li>
|
||||||
|
{{else}}
|
||||||
|
<li><a href="/login">{{tr "Login"}}</a></li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</section>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div id="network">
|
||||||
|
<div class="server-info-container" v-for='server in servers' :id="server.ID">
|
||||||
|
<div class="info-body" @click="redirectNetwork(server.ID)">
|
||||||
|
<ul class="server-info-body-container">
|
||||||
|
<li>
|
||||||
|
<h3>@#server.Name#@</h3>
|
||||||
|
</li>
|
||||||
|
<li><img :src="'/static/theme-daynight/img/flag/'+(server.Host&&server.Host.CountryCode?server.Host.CountryCode.toUpperCase():'CN')+'.png'"
|
||||||
|
:title="server.Host.CountryCode.toUpperCase()" /></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav class="nav-menu">
|
<div class="network-chart" style="height: 800px;overflow: hidden">
|
||||||
<ul>
|
<div id="monitor-info-container" style="height: 520px;max-width: 1400px">
|
||||||
<li><a href="/">{{tr "Home"}}</a></li>
|
|
||||||
<li><a href="/service">{{tr "Services"}}</a></li>
|
|
||||||
<li><a href="/network">{{tr "NetworkSpiter"}}</a></li>
|
|
||||||
{{if .Admin}}
|
|
||||||
<li><a href="/server">{{tr "AdminPanel"}}</a></li>
|
|
||||||
{{else}}
|
|
||||||
<li><a href="/login">{{tr "Login"}}</a></li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</section>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<div id="network">
|
|
||||||
<div class="server-info-container" v-for='server in servers' :id="server.ID" style="font-size: .6em">
|
|
||||||
<div class="info-body" @click="redirectNetwork(server.ID)">
|
|
||||||
<ul class="server-info-body-container">
|
|
||||||
<li>
|
|
||||||
<h3>@#server.Name#@</h3>
|
|
||||||
</li>
|
|
||||||
<li><img :src="'/static/theme-daynight/img/flag/'+(server.Host&&server.Host.CountryCode?server.Host.CountryCode.toUpperCase():'CN')+'.png'"
|
|
||||||
:title="server.Host.CountryCode.toUpperCase()" /></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="sidebar-container">
|
||||||
<div class="network-chart" style="height: 800px;overflow: hidden">
|
<ul>
|
||||||
<div id="monitor-info-container" style="height: 520px;max-width: 1400px">
|
<li><i class="fas fa-sun" title='{{tr "LightMode"}}'></i><span>{{tr "LightMode"}}</span></li>
|
||||||
|
<li><i class="fas fa-moon" title='{{tr "DarkMode"}}'></i><span>{{tr "DarkMode"}}</span></li>
|
||||||
|
<li><i class="fas fa-th" title='{{tr "GridLayout"}}'></i><span>{{tr "GridLayout"}}</span></li>
|
||||||
|
<li><i class="fas fa-list-ul" title='{{tr "ListLayout"}}'></i><span>{{tr "ListLayout"}}</span></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
<div class="sidebar-container">
|
|
||||||
<ul>
|
|
||||||
<li><i class="fas fa-sun" title='{{tr "LightMode"}}'></i><span>{{tr "LightMode"}}</span></li>
|
|
||||||
<li><i class="fas fa-moon" title='{{tr "DarkMode"}}'></i><span>{{tr "DarkMode"}}</span></li>
|
|
||||||
<li><i class="fas fa-th" title='{{tr "GridLayout"}}'></i><span>{{tr "GridLayout"}}</span></li>
|
|
||||||
<li><i class="fas fa-list-ul" title='{{tr "ListLayout"}}'></i><span>{{tr "ListLayout"}}</span></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<section class="dark-light-toggle">
|
<section class="dark-light-toggle">
|
||||||
<label class="switcher">
|
<label class="switcher">
|
||||||
<input type="checkbox" name="theme" id="dark-light" />
|
<input type="checkbox" name="theme" id="dark-light" />
|
||||||
<div>
|
<div>
|
||||||
<i class="fas fa-adjust"></i>
|
<i class="fas fa-adjust"></i>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Back to top button -->
|
<!-- Back to top button -->
|
||||||
<a id="back-to-top"></a>
|
<a id="back-to-top"></a>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="footer-container">
|
<div class="footer-container">
|
||||||
<div><a href="https://github.com/naiba/nezha" target="_blank">Powered by {{tr "NezhaMonitoring"}} · {{.Version}}</a>
|
<div><a href="https://github.com/naiba/nezha" target="_blank">Powered by {{tr "NezhaMonitoring"}} ·
|
||||||
<p>© <span id="copyright-date">
|
{{.Version}}</a>
|
||||||
|
<p>© <span id="copyright-date">
|
||||||
<script>document.getElementById('copyright-date').appendChild(document.createTextNode(new Date().getFullYear()))</script>
|
<script>document.getElementById('copyright-date').appendChild(document.createTextNode(new Date().getFullYear()))</script>
|
||||||
</span> · <a href="https://blog.jackiesung.com" target="_blank">Theme designed by Jackie Sung</a>
|
</span> · <a href="https://blog.jackiesung.com" target="_blank">Theme designed by Jackie Sung</a>
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</footer>
|
||||||
</footer>
|
|
||||||
|
|
||||||
<script src="/static/theme-daynight/js/main.js?v202102012266"></script>
|
<script src="/static/theme-daynight/js/main.js?v202102012266"></script>
|
||||||
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/vue/2.6.14/vue.min.js"></script>
|
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/vue/2.6.14/vue.min.js"></script>
|
||||||
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/limonte-sweetalert2/11.4.4/sweetalert2.all.min.js"></script>
|
<script
|
||||||
|
src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/limonte-sweetalert2/11.4.4/sweetalert2.all.min.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const monitorInfo = JSON.parse('{{.MonitorInfos}}');
|
const monitorInfo = JSON.parse('{{.MonitorInfos}}');
|
||||||
const initData = JSON.parse('{{.Servers}}').servers;
|
const initData = JSON.parse('{{.Servers}}').servers;
|
||||||
let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}};
|
let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}};
|
||||||
if (MaxTCPPingValue == null) {
|
|
||||||
MaxTCPPingValue = 1000;
|
|
||||||
}
|
|
||||||
// 基于准备好的dom,初始化echarts实例
|
// 基于准备好的dom,初始化echarts实例
|
||||||
var myChart = echarts.init(document.getElementById('monitor-info-container'));
|
const myChart = echarts.init(document.getElementById('monitor-info-container'));
|
||||||
|
|
||||||
// 使用刚指定的配置项和数据显示图表。
|
// 使用刚指定的配置项和数据显示图表。
|
||||||
var statusCards = new Vue({
|
var statusCards = new Vue({
|
||||||
el: '#network',
|
el: '#network',
|
||||||
@@ -128,11 +128,11 @@
|
|||||||
position: function (pt) {
|
position: function (pt) {
|
||||||
return [pt[0], '10%'];
|
return [pt[0], '10%'];
|
||||||
},
|
},
|
||||||
formatter: function(params){
|
formatter: function (params) {
|
||||||
let result = params[0].axisValueLabel + "<br />";
|
let result = params[0].axisValueLabel + "<br />";
|
||||||
params.forEach(function(item){
|
params.forEach(function (item) {
|
||||||
result += item.marker + item.seriesName + ": " + item.value[1].toFixed(2) + " ms<br />";
|
result += item.marker + item.seriesName + ": " + item.value[1].toFixed(2) + " ms<br />";
|
||||||
})
|
})
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
confine: true,
|
confine: true,
|
||||||
@@ -179,9 +179,9 @@
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.DarkMode();
|
this.DarkMode();
|
||||||
this.parseMonitorInfo(monitorInfo);
|
this.parseMonitorInfo(monitorInfo);
|
||||||
window.addEventListener('resize', this.resizeHandle);
|
window.addEventListener('resize', this.resizeHandle);
|
||||||
},
|
},
|
||||||
destroyed () {
|
destroyed() {
|
||||||
window.removeEventListener('resize', this.resizeHandle)
|
window.removeEventListener('resize', this.resizeHandle)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -195,81 +195,106 @@
|
|||||||
},
|
},
|
||||||
redirectNetwork(id) {
|
redirectNetwork(id) {
|
||||||
this.getMonitorHistory(id)
|
this.getMonitorHistory(id)
|
||||||
.then(function(monitorInfo) {
|
.then(function (monitorInfo) {
|
||||||
var vm = network.__vue__;
|
var vm = network.__vue__;
|
||||||
vm.parseMonitorInfo(monitorInfo);
|
vm.parseMonitorInfo(monitorInfo);
|
||||||
})
|
})
|
||||||
.catch(function(error){
|
.catch(function (error) {
|
||||||
window.location.href = "/404";
|
window.location.href = "/404";
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getMonitorHistory(id) {
|
getMonitorHistory(id) {
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
url: "/api/v1/monitor/"+id,
|
url: "/api/v1/monitor/" + id,
|
||||||
method: "GET"
|
method: "GET"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
parseMonitorInfo(monitorInfo) {
|
parseMonitorInfo(monitorInfo) {
|
||||||
let tSeries = [];
|
let tSeries = [];
|
||||||
let tLegendData = [];
|
let tLegendData = [];
|
||||||
|
var lcolors = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'];
|
||||||
for (let i = 0; i < monitorInfo.result.length; i++) {
|
for (let i = 0; i < monitorInfo.result.length; i++) {
|
||||||
|
var lcolor = lcolors[i % lcolors.length];
|
||||||
|
var rgbaColorMarker = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.5)';
|
||||||
|
var rgbaColorBar = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.35)';
|
||||||
let loss = 0;
|
let loss = 0;
|
||||||
let data = [];
|
let data = [];
|
||||||
|
let datal = [];
|
||||||
for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) {
|
for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) {
|
||||||
avgDelay = monitorInfo.result[i].avg_delay[j];
|
avgDelay = Math.round(monitorInfo.result[i].avg_delay[j]);
|
||||||
if (avgDelay > 0.9 * MaxTCPPingValue) {
|
if (avgDelay > 0 && avgDelay < MaxTCPPingValue) {
|
||||||
loss += 1
|
data.push([monitorInfo.result[i].created_at[j], avgDelay]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
loss += 1;
|
||||||
|
datal.push({
|
||||||
|
xAxis: monitorInfo.result[i].created_at[j],
|
||||||
|
label: { show: false },
|
||||||
|
emphasis: { disabled: true },
|
||||||
|
lineStyle: {
|
||||||
|
type: "solid",
|
||||||
|
color: rgbaColorBar
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
data.push([monitorInfo.result[i].created_at[j], avgDelay]);
|
|
||||||
}
|
}
|
||||||
lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1);
|
lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1);
|
||||||
legendName = monitorInfo.result[i].monitor_name +" "+ lossRate + "%";
|
if (lossRate > 99) {
|
||||||
|
datal = [];
|
||||||
|
}
|
||||||
|
legendName = monitorInfo.result[i].monitor_name + " " + lossRate + "%";
|
||||||
tLegendData.push(legendName);
|
tLegendData.push(legendName);
|
||||||
tSeries.push({
|
tSeries.push({
|
||||||
name: legendName,
|
name: legendName,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
smooth: true,
|
smooth: true,
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
data: data
|
data: data,
|
||||||
|
markLine: {
|
||||||
|
symbol: "none",
|
||||||
|
symbolSize: 0,
|
||||||
|
data: datal
|
||||||
|
},
|
||||||
|
markPoint: {
|
||||||
|
data: [
|
||||||
|
{ type: 'max', symbol: 'pin', name: 'Max', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8 } },
|
||||||
|
{ type: 'min', symbol: 'pin', name: 'Min', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8, offset: [0, 7.5] }, symbolRotate: 180 }
|
||||||
|
]
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.option.title.text = monitorInfo.result[0].server_name;
|
this.option.title.text = monitorInfo.result[0].server_name;
|
||||||
this.option.series = tSeries;
|
this.option.series = tSeries;
|
||||||
this.option.legend.data = tLegendData;
|
this.option.legend.data = tLegendData;
|
||||||
const hour = new Date(Date.now()).getHours()
|
|
||||||
if (hour > 17 || hour < 4) {
|
|
||||||
this.option.legend.textStyle.color = "#F1F1F2";
|
|
||||||
this.option.title.textStyle.color = "#ccc";
|
|
||||||
}
|
|
||||||
myChart.clear();
|
myChart.clear();
|
||||||
myChart.setOption(this.option);
|
myChart.setOption(this.option);
|
||||||
},
|
},
|
||||||
resizeHandle () {
|
resizeHandle() {
|
||||||
this.myChart.resize();
|
myChart.resize();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
<style>
|
<style>
|
||||||
#network {
|
#network {
|
||||||
display: grid;
|
width: calc(100vw - 6em);
|
||||||
/*grid-template-columns: repeat(5, 1fr);*/
|
max-width: 1400px;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
margin: 1em auto;
|
||||||
grid-gap: 1em;
|
}
|
||||||
width: 100%;
|
|
||||||
width: calc(100vw - 6em);
|
#monitor-info-container {
|
||||||
max-width: 1400px;
|
margin: 0em auto;
|
||||||
margin: 1em auto;
|
align-content: start;
|
||||||
align-content: start;
|
background-color: #F1F1F2;
|
||||||
}
|
}
|
||||||
#monitor-info-container{
|
|
||||||
margin: 0em auto;
|
.server-info-container {
|
||||||
align-content: start;
|
font-size: .6em;
|
||||||
background-color: #F1F1F2;
|
width: fit-content;
|
||||||
}
|
display: inline-block;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
+12
-11
@@ -7,19 +7,20 @@
|
|||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<meta content="telephone=no" name="format-detection">
|
<meta content="telephone=no" name="format-detection">
|
||||||
<title>{{.Title}}</title>
|
<title>{{.Title}}</title>
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/assets/font-logos.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/lipis/[email protected]/css/flag-icons.min.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="/static/semantic-ui-alerts.min.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="/static/theme-default/css/main.css?v20240226">
|
|
||||||
<link rel="shortcut icon" type="image/png" href="/static/logo.svg" />
|
<link rel="shortcut icon" type="image/png" href="/static/logo.svg" />
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/semantic.min.css">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.js"></script>
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/assets/font-logos.css">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/font/bootstrap-icons.min.css">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/css/flag-icons.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/semantic-ui-alerts.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/theme-default/css/main.css?v20240616">
|
||||||
|
<script src="https://unpkg.com/[email protected]/dist/jquery.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/[email protected]/dist/semantic.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/[email protected]/dist/echarts.min.js"></script>
|
||||||
<script src="/static/semantic-ui-alerts.min.js"></script>
|
<script src="/static/semantic-ui-alerts.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
|
|
||||||
<script src="/static/theme-default/js/mixin.js?v20240302"></script>
|
<script src="/static/theme-default/js/mixin.js?v20240302"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|||||||
+612
-512
File diff suppressed because it is too large
Load Diff
+3
@@ -27,6 +27,9 @@
|
|||||||
<i :class="item.icon + ' icon'"></i>@#item.name#@
|
<i :class="item.icon + ' icon'"></i>@#item.name#@
|
||||||
<i class="check icon" v-if="preferredTemplate === item.key"></i>
|
<i class="check icon" v-if="preferredTemplate === item.key"></i>
|
||||||
</a>
|
</a>
|
||||||
|
<a v-if="defaultTemplate === 'custom'" @click="toggleTemplate('custom')" class="item">
|
||||||
|
<i class="expand icon"></i>Custom
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
+28
-9
@@ -28,9 +28,6 @@
|
|||||||
const monitorInfo = JSON.parse('{{.MonitorInfos}}');
|
const monitorInfo = JSON.parse('{{.MonitorInfos}}');
|
||||||
const initData = JSON.parse('{{.Servers}}').servers;
|
const initData = JSON.parse('{{.Servers}}').servers;
|
||||||
let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}};
|
let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}};
|
||||||
if (MaxTCPPingValue == null) {
|
|
||||||
MaxTCPPingValue = 1000;
|
|
||||||
}
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
delimiters: ['@#', '#@'],
|
delimiters: ['@#', '#@'],
|
||||||
@@ -185,19 +182,36 @@
|
|||||||
parseMonitorInfo(monitorInfo) {
|
parseMonitorInfo(monitorInfo) {
|
||||||
let tSeries = [];
|
let tSeries = [];
|
||||||
let tLegendData = [];
|
let tLegendData = [];
|
||||||
|
var lcolors = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'];
|
||||||
for (let i = 0; i < monitorInfo.result.length; i++) {
|
for (let i = 0; i < monitorInfo.result.length; i++) {
|
||||||
|
var lcolor = lcolors[i % lcolors.length];
|
||||||
|
var rgbaColorMarker = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.5)';
|
||||||
|
var rgbaColorBar = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.35)';
|
||||||
let loss = 0;
|
let loss = 0;
|
||||||
let data = [];
|
let data = [];
|
||||||
|
let datal = [];
|
||||||
for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) {
|
for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) {
|
||||||
avgDelay = Math.round(monitorInfo.result[i].avg_delay[j]);
|
avgDelay = Math.round(monitorInfo.result[i].avg_delay[j]);
|
||||||
if (avgDelay > 0.9 * MaxTCPPingValue) {
|
if (avgDelay > 0 && avgDelay < MaxTCPPingValue) {
|
||||||
loss += 1
|
|
||||||
}
|
|
||||||
if (avgDelay > 0) {
|
|
||||||
data.push([monitorInfo.result[i].created_at[j], avgDelay]);
|
data.push([monitorInfo.result[i].created_at[j], avgDelay]);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
loss += 1;
|
||||||
|
datal.push({
|
||||||
|
xAxis: monitorInfo.result[i].created_at[j],
|
||||||
|
label: { show: false },
|
||||||
|
emphasis: { disabled: true },
|
||||||
|
lineStyle: {
|
||||||
|
type: "solid",
|
||||||
|
color: rgbaColorBar
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1);
|
lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1);
|
||||||
|
if (lossRate > 99) {
|
||||||
|
datal = [];
|
||||||
|
}
|
||||||
legendName = monitorInfo.result[i].monitor_name +" "+ lossRate + "%";
|
legendName = monitorInfo.result[i].monitor_name +" "+ lossRate + "%";
|
||||||
tLegendData.push(legendName);
|
tLegendData.push(legendName);
|
||||||
tSeries.push({
|
tSeries.push({
|
||||||
@@ -206,10 +220,15 @@
|
|||||||
smooth: true,
|
smooth: true,
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
data: data,
|
data: data,
|
||||||
|
markLine: {
|
||||||
|
symbol: "none",
|
||||||
|
symbolSize :0,
|
||||||
|
data: datal
|
||||||
|
},
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', symbol: 'pin', name: 'Max', itemStyle: { color: '#f00' } },
|
{ type: 'max', symbol: 'pin', name: 'Max', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8 } },
|
||||||
{ type: 'min', symbol: 'pin', name: 'Min', itemStyle: { color: '#0f0' } }
|
{ type: 'min', symbol: 'pin', name: 'Min', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8, offset: [0, 7.5] }, symbolRotate: 180 }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-1
@@ -221,7 +221,7 @@
|
|||||||
var disk = this.formatByteSize(server.State.DiskUsed) + '/' + this.formatByteSize(server.Host.DiskTotal);
|
var disk = this.formatByteSize(server.State.DiskUsed) + '/' + this.formatByteSize(server.Host.DiskTotal);
|
||||||
var upTime = this.secondToDate(server.State.Uptime);
|
var upTime = this.secondToDate(server.State.Uptime);
|
||||||
var tooltip =
|
var tooltip =
|
||||||
`{content: 'System: ${server.Host.Platform}-${server.Host.PlatformVersion}[${server.Host.Arch}]<br>CPU: ${server.Host.CPU}<br>Disk: ${disk}<br>Online: ${upTime}<br>Version: ${server.Host.Version}'}`;
|
`{content: 'System: ${server.Host.Platform}-${server.Host.PlatformVersion}[${server.Host.Arch}]<br>CPU: ${server.Host.CPU}<br>GPU: ${server.Host.GPU}<br>Disk: ${disk}<br>Online: ${upTime}<br>Version: ${server.Host.Version}'}`;
|
||||||
return tooltip
|
return tooltip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-10
@@ -55,9 +55,6 @@
|
|||||||
const monitorInfo = JSON.parse('{{.MonitorInfos}}');
|
const monitorInfo = JSON.parse('{{.MonitorInfos}}');
|
||||||
const initData = JSON.parse('{{.Servers}}').servers;
|
const initData = JSON.parse('{{.Servers}}').servers;
|
||||||
let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}};
|
let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}};
|
||||||
if (MaxTCPPingValue == null) {
|
|
||||||
MaxTCPPingValue = 1000;
|
|
||||||
}
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
delimiters: ['@#', '#@'],
|
delimiters: ['@#', '#@'],
|
||||||
@@ -208,19 +205,36 @@
|
|||||||
parseMonitorInfo(monitorInfo) {
|
parseMonitorInfo(monitorInfo) {
|
||||||
let tSeries = [];
|
let tSeries = [];
|
||||||
let tLegendData = [];
|
let tLegendData = [];
|
||||||
|
var lcolors = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'];
|
||||||
for (let i = 0; i < monitorInfo.result.length; i++) {
|
for (let i = 0; i < monitorInfo.result.length; i++) {
|
||||||
|
var lcolor = lcolors[i % lcolors.length];
|
||||||
|
var rgbaColorMarker = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.5)';
|
||||||
|
var rgbaColorBar = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.35)';
|
||||||
let loss = 0;
|
let loss = 0;
|
||||||
let data = [];
|
let data = [];
|
||||||
|
let datal = [];
|
||||||
for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) {
|
for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) {
|
||||||
avgDelay = Math.round(monitorInfo.result[i].avg_delay[j]);
|
avgDelay = Math.round(monitorInfo.result[i].avg_delay[j]);
|
||||||
if (avgDelay > 0.9 * MaxTCPPingValue) {
|
if (avgDelay > 0 && avgDelay < MaxTCPPingValue) {
|
||||||
loss += 1
|
|
||||||
}
|
|
||||||
if (avgDelay > 0) {
|
|
||||||
data.push([monitorInfo.result[i].created_at[j], avgDelay]);
|
data.push([monitorInfo.result[i].created_at[j], avgDelay]);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
loss += 1;
|
||||||
|
datal.push({
|
||||||
|
xAxis: monitorInfo.result[i].created_at[j],
|
||||||
|
label: { show: false },
|
||||||
|
emphasis: { disabled: true },
|
||||||
|
lineStyle: {
|
||||||
|
type: "solid",
|
||||||
|
color: rgbaColorBar
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1);
|
lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1);
|
||||||
|
if (lossRate > 99) {
|
||||||
|
datal = [];
|
||||||
|
}
|
||||||
legendName = monitorInfo.result[i].monitor_name +" "+ lossRate + "%";
|
legendName = monitorInfo.result[i].monitor_name +" "+ lossRate + "%";
|
||||||
tLegendData.push(legendName);
|
tLegendData.push(legendName);
|
||||||
tSeries.push({
|
tSeries.push({
|
||||||
@@ -229,10 +243,15 @@
|
|||||||
smooth: true,
|
smooth: true,
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
data: data,
|
data: data,
|
||||||
|
markLine: {
|
||||||
|
symbol: "none",
|
||||||
|
symbolSize :0,
|
||||||
|
data: datal
|
||||||
|
},
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', symbol: 'pin', name: 'Max', itemStyle: { color: '#f00' } },
|
{ type: 'max', symbol: 'pin', name: 'Max', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8 } },
|
||||||
{ type: 'min', symbol: 'pin', name: 'Min', itemStyle: { color: '#0f0' } }
|
{ type: 'min', symbol: 'pin', name: 'Min', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8, offset: [0, 7.5] }, symbolRotate: 180 }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,13 +5,16 @@
|
|||||||
</p>
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
<aside class="toolbox">
|
<aside class="toolbox">
|
||||||
|
<span v-if="page=='index' && countryMapChartData.length!=0" class="showMapChart">
|
||||||
|
<i @click="showMapChart" data-toggle="modal" data-target="#mapChartBox" class="bi bi-geo-alt"></i>
|
||||||
|
</span>
|
||||||
<span class="toggleView">
|
<span class="toggleView">
|
||||||
<i v-if="showGroup" @click="toggleView" class="show-nogroup bi bi-justify"></i>
|
<i v-if="showGroup" @click="toggleShowGroup" class="show-nogroup bi bi-justify"></i>
|
||||||
<i v-else @click="toggleView" class="show-group bi bi-view-stacked"></i>
|
<i v-else @click="toggleShowGroup" class="show-group bi bi-view-stacked"></i>
|
||||||
</span>
|
</span>
|
||||||
<span class="setTheme">
|
<span class="setTheme">
|
||||||
<i v-if="theme === 'light'" @click="setTheme('dark', true)" class="setTheme-dark bi bi-moon-fill"></i>
|
<i v-if="theme === 'light'" @click="setTheme('dark')" class="setTheme-dark bi bi-moon-fill"></i>
|
||||||
<i v-else @click="setTheme('light', true)" class="setTheme-light bi bi-brightness-high-fill"></i>
|
<i v-else @click="setTheme('light')" class="setTheme-light bi bi-brightness-high-fill"></i>
|
||||||
</span>
|
</span>
|
||||||
<span v-if="showGoTop" class="showGoTop">
|
<span v-if="showGoTop" class="showGoTop">
|
||||||
<i @click="goTop" class="goTop bi bi-arrow-up"></i>
|
<i @click="goTop" class="goTop bi bi-arrow-up"></i>
|
||||||
|
|||||||
@@ -39,6 +39,11 @@
|
|||||||
<i class="check icon" v-if="preferredTemplate === item.key"></i>
|
<i class="check icon" v-if="preferredTemplate === item.key"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-if="defaultTemplate === 'custom'">
|
||||||
|
<a @click="toggleTemplate('custom')" class="item">
|
||||||
|
<i class="expand icon" style="font-size:1em"></i>Custom
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
+22
-15
@@ -6,16 +6,21 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
|
|
||||||
<link rel="stylesheet" href="/static/theme-server-status/css/bootstrap-theme.min.css">
|
|
||||||
<link rel="stylesheet" href="/static/theme-server-status/css/main.css?v20240225">
|
|
||||||
<link rel="stylesheet" href="/static/theme-server-status/css/dark.css">
|
|
||||||
<link rel="stylesheet" href="/static/theme-server-status/css/light.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/assets/font-logos.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/lipis/[email protected]/css/flag-icons.min.css">
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/semantic.min.css">
|
|
||||||
<link rel="shortcut icon" type="image/png" href="/static/logo.svg" />
|
<link rel="shortcut icon" type="image/png" href="/static/logo.svg" />
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/css/bootstrap-theme.min.css">
|
||||||
|
<link rel="stylesheet" href="/static/theme-server-status/css/main.css?v20240616">
|
||||||
|
<link rel="stylesheet" href="/static/theme-server-status/css/dark.css?v20240407">
|
||||||
|
<link rel="stylesheet" href="/static/theme-server-status/css/light.css?v20240407">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/font/bootstrap-icons.min.css">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/assets/font-logos.css">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/css/flag-icons.min.css">
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/semantic.min.css">
|
||||||
|
<script src="https://unpkg.com/[email protected]/dist/jquery.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/[email protected]/dist/js/bootstrap.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
|
||||||
|
<script src="https://unpkg.com/[email protected]/dist/echarts.min.js"></script>
|
||||||
|
<script src="/static/theme-server-status/js/mixin.js?v20240707"></script>
|
||||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
<script src="/static/theme-server-status/js/html5shiv.js"></script>
|
<script src="/static/theme-server-status/js/html5shiv.js"></script>
|
||||||
@@ -24,11 +29,13 @@
|
|||||||
{{if ts .CustomCode}}
|
{{if ts .CustomCode}}
|
||||||
{{.CustomCode|safe}}
|
{{.CustomCode|safe}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
|
|
||||||
<script src="/static/theme-server-status/js/mixin.js?v20240302"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+29
-8
@@ -27,10 +27,10 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="node-cell name center">@#node.name#@</td>
|
<td class="node-cell name center">@#node.name#@</td>
|
||||||
<td class="node-cell os center">
|
<td class="node-cell os center">
|
||||||
<i v-if='node.os == "darwin"' class="apple icon"></i>
|
<i v-if='isWindowsPlatform(node.host.Platform)' class="windows icon"></i>
|
||||||
<i v-else-if='isWindowsPlatform(node.host.Platform)' class="windows icon"></i>
|
<i v-else-if='getFontLogoClass(node.host.Platform) == "" && node.stateuptime > 0' class="fl-tux"></i>
|
||||||
<i v-else :class="'fl-' + getFontLogoClass(node.host.Platform)"></i>
|
<i v-else :class="'fl-' + getFontLogoClass(node.host.Platform)"></i>
|
||||||
<span class="node-cell-os-text">@#node.os#@</span>
|
<span class="node-cell-os-text">@#getPlatformName(node.os)#@</span>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align: center;" class="node-cell location">
|
<td style="text-align: center;" class="node-cell location">
|
||||||
<i :class="'fi fi-' + node.location"></i>
|
<i :class="'fi fi-' + node.location"></i>
|
||||||
@@ -71,20 +71,28 @@
|
|||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand" v-if="node.host.CPU">
|
<span class="node-cell-expand" v-if="node.host.CPU">
|
||||||
<span class="node-cell-expand-label">CPU:</span>
|
<span class="node-cell-expand-label">CPU:</span>
|
||||||
@#node.host.CPU.join(",")#@
|
@#node.host.CPU.join(",")#@ (@#node.cpu.percent#@%)
|
||||||
|
</span>
|
||||||
|
<span class="node-cell-expand" v-if="node.host.GPU">
|
||||||
|
<span class="node-cell-expand-label">GPU:</span>
|
||||||
|
@#node.host.GPU.join(",")#@
|
||||||
|
(@#parseInt(node.state.GPU >=0 ? node.state.GPU : 0)#@%)
|
||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "DiskUsed"}}:</span>
|
<span class="node-cell-expand-label">{{tr "DiskUsed"}}:</span>
|
||||||
@#formatByteSize(node.state.DiskUsed)#@ / @#formatByteSize(node.host.DiskTotal)#@
|
@#formatByteSize(node.state.DiskUsed)#@ / @#formatByteSize(node.host.DiskTotal)#@ (@#node.hdd.percent#@%)
|
||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "MemUsed"}}:</span>
|
<span class="node-cell-expand-label">{{tr "MemUsed"}}:</span>
|
||||||
@#formatByteSize(node.state.MemUsed)#@ / @#formatByteSize(node.host.MemTotal)#@(@#toFixed2(node.state.MemUsed / node.host.MemTotal * 100)#@%)
|
@#formatByteSize(node.state.MemUsed)#@ / @#formatByteSize(node.host.MemTotal)#@ (@#node.memory.percent#@%)
|
||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span v-if="node.host.SwapTotal > 0" class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "SwapUsed"}}:</span>
|
<span class="node-cell-expand-label">{{tr "SwapUsed"}}:</span>
|
||||||
@#formatByteSize(node.state.SwapUsed)#@ / @#formatByteSize(node.host.SwapTotal)#@
|
@#formatByteSize(node.state.SwapUsed)#@ / @#formatByteSize(node.host.SwapTotal)#@
|
||||||
<span v-if="node.host.SwapTotal">(@#toFixed2(node.state.SwapUsed / node.host.SwapTotal * 100)#@%)</span>
|
<span>(@#toFixed2(node.state.SwapUsed / node.host.SwapTotal * 100)#@%)</span>
|
||||||
|
</span>
|
||||||
|
<span v-else class="node-cell-expand">
|
||||||
|
<span class="node-cell-expand-label">{{tr "SwapUsed"}}: OFF</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "NetTransfer"}}:</span>
|
<span class="node-cell-expand-label">{{tr "NetTransfer"}}:</span>
|
||||||
@@ -117,6 +125,19 @@
|
|||||||
<span class="node-cell-expand-label">{{tr "Uptime"}}:</span>
|
<span class="node-cell-expand-label">{{tr "Uptime"}}:</span>
|
||||||
@#node.uptime#@
|
@#node.uptime#@
|
||||||
</span>
|
</span>
|
||||||
|
<span v-if="node.state.Temperatures && getTemperature(node.state.Temperatures, sensorList) > 0" @click="toggleDetailedTemp(node.ID)" class="node-cell-expand temp-detail" :id="`temp-${node.ID}`" temp-detail-show="0">
|
||||||
|
<span class="node-cell-expand-label">{{tr "Temperature"}}:</span>
|
||||||
|
<span :id="`temp-main-${node.ID}`" class="node-cell-expand-label">
|
||||||
|
@#getTemperature(node.state.Temperatures, sensorList)#@°C
|
||||||
|
<i class="bi bi-chevron-double-down"></i>
|
||||||
|
</span>
|
||||||
|
<span :id="`temp-detail-${node.ID}`" class="node-cell-expand-label" style="display:none">
|
||||||
|
<span v-for="temp in node.state.Temperatures" :key="temp.Name" v-if="temp.Temperature !== 0">
|
||||||
|
[ @#temp.Name#@ : @#temp.Temperature#@°C ]
|
||||||
|
</span>
|
||||||
|
<i class="bi bi-chevron-double-up"></i>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "Version"}}:</span>
|
<span class="node-cell-expand-label">{{tr "Version"}}:</span>
|
||||||
@#node.host.Version#@
|
@#node.host.Version#@
|
||||||
|
|||||||
+29
-8
@@ -30,10 +30,10 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="node-cell name center">@#node.name#@</td>
|
<td class="node-cell name center">@#node.name#@</td>
|
||||||
<td class="node-cell os center">
|
<td class="node-cell os center">
|
||||||
<i v-if='node.os == "darwin"' class="apple icon"></i>
|
<i v-if='isWindowsPlatform(node.host.Platform)' class="windows icon"></i>
|
||||||
<i v-else-if='isWindowsPlatform(node.host.Platform)' class="windows icon"></i>
|
<i v-else-if='getFontLogoClass(node.host.Platform) == "" && node.stateuptime > 0' class="fl-tux"></i>
|
||||||
<i v-else :class="'fl-' + getFontLogoClass(node.host.Platform)"></i>
|
<i v-else :class="'fl-' + getFontLogoClass(node.host.Platform)"></i>
|
||||||
<span class="node-cell-os-text">@#node.os#@</span>
|
<span class="node-cell-os-text">@#getPlatformName(node.os)#@</span>
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align: center;" class="node-cell location">
|
<td style="text-align: center;" class="node-cell location">
|
||||||
<i :class="'fi fi-' + node.location"></i>
|
<i :class="'fi fi-' + node.location"></i>
|
||||||
@@ -74,20 +74,28 @@
|
|||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand" v-if="node.host.CPU">
|
<span class="node-cell-expand" v-if="node.host.CPU">
|
||||||
<span class="node-cell-expand-label">CPU:</span>
|
<span class="node-cell-expand-label">CPU:</span>
|
||||||
@#node.host.CPU.join(",")#@
|
@#node.host.CPU.join(",")#@ (@#node.cpu.percent#@%)
|
||||||
|
</span>
|
||||||
|
<span class="node-cell-expand" v-if="node.host.GPU">
|
||||||
|
<span class="node-cell-expand-label">GPU:</span>
|
||||||
|
@#node.host.GPU.join(",")#@
|
||||||
|
(@#parseInt(node.state.GPU >=0 ? node.state.GPU : 0)#@%)
|
||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "DiskUsed"}}:</span>
|
<span class="node-cell-expand-label">{{tr "DiskUsed"}}:</span>
|
||||||
@#formatByteSize(node.state.DiskUsed)#@ / @#formatByteSize(node.host.DiskTotal)#@
|
@#formatByteSize(node.state.DiskUsed)#@ / @#formatByteSize(node.host.DiskTotal)#@ (@#node.hdd.percent#@%)
|
||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "MemUsed"}}:</span>
|
<span class="node-cell-expand-label">{{tr "MemUsed"}}:</span>
|
||||||
@#formatByteSize(node.state.MemUsed)#@ / @#formatByteSize(node.host.MemTotal)#@(@#toFixed2(node.state.MemUsed / node.host.MemTotal * 100)#@%)
|
@#formatByteSize(node.state.MemUsed)#@ / @#formatByteSize(node.host.MemTotal)#@ (@#node.memory.percent#@%)
|
||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span v-if="node.host.SwapTotal > 0" class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "SwapUsed"}}:</span>
|
<span class="node-cell-expand-label">{{tr "SwapUsed"}}:</span>
|
||||||
@#formatByteSize(node.state.SwapUsed)#@ / @#formatByteSize(node.host.SwapTotal)#@
|
@#formatByteSize(node.state.SwapUsed)#@ / @#formatByteSize(node.host.SwapTotal)#@
|
||||||
<span v-if="node.host.SwapTotal">(@#toFixed2(node.state.SwapUsed / node.host.SwapTotal * 100)#@%)</span>
|
<span>(@#toFixed2(node.state.SwapUsed / node.host.SwapTotal * 100)#@%)</span>
|
||||||
|
</span>
|
||||||
|
<span v-else class="node-cell-expand">
|
||||||
|
<span class="node-cell-expand-label">{{tr "SwapUsed"}}: OFF</span>
|
||||||
</span>
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "NetTransfer"}}:</span>
|
<span class="node-cell-expand-label">{{tr "NetTransfer"}}:</span>
|
||||||
@@ -120,6 +128,19 @@
|
|||||||
<span class="node-cell-expand-label">{{tr "Uptime"}}:</span>
|
<span class="node-cell-expand-label">{{tr "Uptime"}}:</span>
|
||||||
@#node.uptime#@
|
@#node.uptime#@
|
||||||
</span>
|
</span>
|
||||||
|
<span v-if="node.state.Temperatures && getTemperature(node.state.Temperatures, sensorList) > 0" @click="toggleDetailedTemp(node.ID)" class="node-cell-expand temp-detail" :id="`temp-${node.ID}`" temp-detail-show="0">
|
||||||
|
<span class="node-cell-expand-label">{{tr "Temperature"}}:</span>
|
||||||
|
<span :id="`temp-main-${node.ID}`" class="node-cell-expand-label">
|
||||||
|
@#getTemperature(node.state.Temperatures, sensorList)#@°C
|
||||||
|
<i class="bi bi-chevron-double-down"></i>
|
||||||
|
</span>
|
||||||
|
<span :id="`temp-detail-${node.ID}`" class="node-cell-expand-label" style="display:none">
|
||||||
|
<span v-for="temp in node.state.Temperatures" :key="temp.Name" v-if="temp.Temperature !== 0">
|
||||||
|
[ @#temp.Name#@ : @#temp.Temperature#@°C ]
|
||||||
|
</span>
|
||||||
|
<i class="bi bi-chevron-double-up"></i>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
<span class="node-cell-expand">
|
<span class="node-cell-expand">
|
||||||
<span class="node-cell-expand-label">{{tr "Version"}}:</span>
|
<span class="node-cell-expand-label">{{tr "Version"}}:</span>
|
||||||
@#node.host.Version#@
|
@#node.host.Version#@
|
||||||
|
|||||||
+251
-6
@@ -14,6 +14,19 @@
|
|||||||
{{template "theme-server-status/home-group-false" .}}
|
{{template "theme-server-status/home-group-false" .}}
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
<div class="modal fade" id="mapChartBox" tabindex="-1" role="dialog" aria-labelledby="mapChartTitle" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" id="mapChartTitle">{{tr "ServersOnWorldMap"}}</h4>
|
||||||
|
<i class="bi bi-x" data-dismiss="modal" aria-label="Close"></i>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div id="mapChart" style="width:100%;height:auto;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{{template "theme-server-status/content-footer" .}}
|
{{template "theme-server-status/content-footer" .}}
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@@ -29,7 +42,30 @@
|
|||||||
nodesTag: [],
|
nodesTag: [],
|
||||||
nodesNoTag: [],
|
nodesNoTag: [],
|
||||||
chartDataList: [],
|
chartDataList: [],
|
||||||
ws: null
|
ws: null,
|
||||||
|
language: {{.Conf.Language}},
|
||||||
|
countryMap: {},
|
||||||
|
countryServer: [],
|
||||||
|
countryNameMap: {},
|
||||||
|
countryMapChartData: [],
|
||||||
|
countryMapGeoFile: localStorage.getItem("countryMapGeoFile") ? localStorage.getItem("countryMapGeoFile") : 'nezha.world.geo.json',
|
||||||
|
sensorList: [
|
||||||
|
'TC0D', //CPU Die 温度,代表 CPU 内部的温度
|
||||||
|
'TC0H', //CPU Heatsink 温度,代表 CPU 散热器的温度
|
||||||
|
'TC0P', //CPU Proximity 温度,代表 CPU 附近的温度
|
||||||
|
'k10temp', //AMD K10(Phenom、Athlon、Sempron 等)系列处理器的温度监测
|
||||||
|
'k10temp_tctl', //AMD K10 (Athlon II、Phenom II 等)系列处理器的温度监测
|
||||||
|
'coretemp_package_id_0', //整个封装处理器温度
|
||||||
|
'cpu_thermal_zone', //全志
|
||||||
|
'cpu-thermal', //树莓派(博通)
|
||||||
|
'soc_thermal', //新瑞芯微
|
||||||
|
'cpu_thermal', //老瑞芯微
|
||||||
|
'ACPI\\ThermalZone\\TZ0__0', //Windows
|
||||||
|
'ACPI\\ThermalZone\\CPUZ_0', //Windows
|
||||||
|
'ACPI\\ThermalZone\\TZ00_0', //Windows
|
||||||
|
'ACPI\\ThermalZone\\TZ001_0', //Windows
|
||||||
|
'ACPI\\ThermalZone\\THM0_0' //Windows
|
||||||
|
]
|
||||||
},
|
},
|
||||||
mixins: [mixinsVue],
|
mixins: [mixinsVue],
|
||||||
created() {
|
created() {
|
||||||
@@ -39,6 +75,12 @@
|
|||||||
} else {
|
} else {
|
||||||
this.nodesNoTag = this.handleNodes(this.servers);
|
this.nodesNoTag = this.handleNodes(this.servers);
|
||||||
}
|
}
|
||||||
|
this.initCountryMap().then(countryMap => {
|
||||||
|
this.countryMap = countryMap;
|
||||||
|
this.countryNameMap = this.initCountryNameMap();
|
||||||
|
this.countryServer = this.initCountryServer();
|
||||||
|
this.countryMapChartData = this.initCountryMapChartData();
|
||||||
|
})
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// 初始化时建立WebSocket连接
|
// 初始化时建立WebSocket连接
|
||||||
@@ -55,9 +97,145 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
initCountryMap() {
|
||||||
|
return fetch(this.staticUrl + '/maps/nezha.countrymap.json')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
initCountryNameMap(){
|
||||||
|
const result = {};
|
||||||
|
for (const item in this.countryMap) {
|
||||||
|
result[this.countryMap[item].en] = this.language=='zh-CN' ? this.countryMap[item].zh : this.countryMap[item].en;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
initCountryServer() {
|
||||||
|
let count = {};
|
||||||
|
let result = [];
|
||||||
|
let exist = {};
|
||||||
|
this.servers.forEach(item => {
|
||||||
|
if (item.Host.CountryCode) {
|
||||||
|
if(this.countryMapGeoFile == 'nezha.world.geo.json' || this.countryMapGeoFile == 'nezha.world.antarctica.geo.json') {
|
||||||
|
if(item.Host.CountryCode.toLowerCase() == 'tw' || item.Host.CountryCode.toLowerCase() == 'hk' || item.Host.CountryCode.toLowerCase() == 'mo') item.Host.CountryCode = 'cn';
|
||||||
|
}
|
||||||
|
if (!exist[item.Host.CountryCode]) {
|
||||||
|
exist[item.Host.CountryCode] = true;
|
||||||
|
count[item.Host.CountryCode] = 1;
|
||||||
|
const obj = {
|
||||||
|
'countryCode': item.Host.CountryCode,
|
||||||
|
'count': count[item.Host.CountryCode]
|
||||||
|
};
|
||||||
|
result.push(obj);
|
||||||
|
} else {
|
||||||
|
count[item.Host.CountryCode]++;
|
||||||
|
result.find(obj => obj.countryCode === item.Host.CountryCode).count = count[item.Host.CountryCode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
initCountryMapChartData(){
|
||||||
|
let result = [];
|
||||||
|
this.countryServer.forEach(item => {
|
||||||
|
var obj = {
|
||||||
|
"name": this.language=='zh-CN' ? this.countryMap[item.countryCode].zh : this.countryMap[item.countryCode].en,
|
||||||
|
"value": item.count
|
||||||
|
}
|
||||||
|
result.push(obj);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
showMapChart(){
|
||||||
|
// 处理异常
|
||||||
|
if( this.countryMapChartData.length == 0 ) {
|
||||||
|
console.log('init countryMapChartData not complete');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const unit = this.language=='zh-CN' ? '台' : 'servers';
|
||||||
|
const isMobile = this.checkIsMobile();
|
||||||
|
const width = isMobile ? 338 : 1102;
|
||||||
|
const height = isMobile ? 200 : 500;
|
||||||
|
const backgroundColor = this.theme == "dark" ? '#1C1D26' : '#ffffff';
|
||||||
|
const inRangeColor = this.theme == "dark" ? '#D2B206' : '#FFDF32';
|
||||||
|
const tooltipBackgroundColor = this.theme == "dark" ? "#ffffff" : '#ffffff';
|
||||||
|
const tooltipBorderColor = this.theme == "dark" ? "#ffffff" : "#ffffff";
|
||||||
|
const fontSize = isMobile ? 10 : 12;
|
||||||
|
const fontColor = this.theme == "dark" ? "#000000" : "#000000";
|
||||||
|
const chartContainer = document.getElementById('mapChart');
|
||||||
|
const mapChart = echarts.init(chartContainer, '', { // init图表
|
||||||
|
renderer: 'canvas',
|
||||||
|
useDirtyRect: false,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
});
|
||||||
|
fetch(this.staticUrl + '/maps/' + this.countryMapGeoFile)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(worldMap => {
|
||||||
|
echarts.registerMap('nezha-world-map', worldMap);
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
grid: {
|
||||||
|
top: 0,
|
||||||
|
left: 10,
|
||||||
|
right: 10
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: function (params) {
|
||||||
|
if (params.data && params.data.value > 0) {
|
||||||
|
return params.name + ' ' + params.data.value + ' ' + unit;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backgroundColor: tooltipBackgroundColor,
|
||||||
|
borderColor: tooltipBorderColor,
|
||||||
|
padding: [4,10],
|
||||||
|
textStyle: {
|
||||||
|
fontSize: fontSize,
|
||||||
|
color: fontColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
visualMap: {
|
||||||
|
show: false,
|
||||||
|
min: 0,
|
||||||
|
max: 1000,
|
||||||
|
calculable: false,
|
||||||
|
inRange: {
|
||||||
|
color: inRangeColor
|
||||||
|
}
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'map',
|
||||||
|
map: 'nezha-world-map',
|
||||||
|
roam: true,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
fontSize: 8
|
||||||
|
},
|
||||||
|
data: this.countryMapChartData,
|
||||||
|
nameMap: this.countryNameMap,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
mapChart.setOption(option);
|
||||||
|
});
|
||||||
|
},
|
||||||
isWindowsPlatform(str) {
|
isWindowsPlatform(str) {
|
||||||
return str.includes('Windows')
|
return str.includes('Windows')
|
||||||
},
|
},
|
||||||
|
getPlatformName(str){
|
||||||
|
if (str.toLowerCase().includes('opensuse')) {
|
||||||
|
return 'openSUSE';
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
},
|
||||||
getFontLogoClass(str) {
|
getFontLogoClass(str) {
|
||||||
if (["almalinux",
|
if (["almalinux",
|
||||||
"alpine",
|
"alpine",
|
||||||
@@ -104,6 +282,9 @@
|
|||||||
> -1) {
|
> -1) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
if (str == 'darwin') {
|
||||||
|
return 'apple';
|
||||||
|
}
|
||||||
if (['openwrt', 'linux', "immortalwrt"].indexOf(str) > -1) {
|
if (['openwrt', 'linux', "immortalwrt"].indexOf(str) > -1) {
|
||||||
return 'tux';
|
return 'tux';
|
||||||
}
|
}
|
||||||
@@ -113,6 +294,9 @@
|
|||||||
if (str == 'arch') {
|
if (str == 'arch') {
|
||||||
return 'archlinux';
|
return 'archlinux';
|
||||||
}
|
}
|
||||||
|
if (str.toLowerCase().includes('opensuse')) {
|
||||||
|
return 'opensuse';
|
||||||
|
}
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
secondToDate(s) {
|
secondToDate(s) {
|
||||||
@@ -139,6 +323,9 @@
|
|||||||
},
|
},
|
||||||
formatPercents(live,percent) {
|
formatPercents(live,percent) {
|
||||||
//if(!live) { percent = 0; }
|
//if(!live) { percent = 0; }
|
||||||
|
if (isNaN(percent)) {
|
||||||
|
percent = 0;
|
||||||
|
}
|
||||||
if (percent <= 0) {
|
if (percent <= 0) {
|
||||||
percent = 0;
|
percent = 0;
|
||||||
}
|
}
|
||||||
@@ -222,6 +409,7 @@
|
|||||||
name: server.Name,
|
name: server.Name,
|
||||||
os: platform,
|
os: platform,
|
||||||
location: server.Host.CountryCode,
|
location: server.Host.CountryCode,
|
||||||
|
stateuptime: server.State.Uptime,
|
||||||
uptime: this.secondToDate(server.State.Uptime),
|
uptime: this.secondToDate(server.State.Uptime),
|
||||||
load: this.toFixed2(server.State.Load1),
|
load: this.toFixed2(server.State.Load1),
|
||||||
network: this.getNetworkSpeed(server.State.NetInSpeed, server.State.NetOutSpeed),
|
network: this.getNetworkSpeed(server.State.NetInSpeed, server.State.NetOutSpeed),
|
||||||
@@ -242,6 +430,46 @@
|
|||||||
getNetworkSpeed(netInSpeed, netOutSpeed) {
|
getNetworkSpeed(netInSpeed, netOutSpeed) {
|
||||||
return this.formatByteSize(netInSpeed) + ' | ' + this.formatByteSize(netOutSpeed)
|
return this.formatByteSize(netInSpeed) + ' | ' + this.formatByteSize(netOutSpeed)
|
||||||
},
|
},
|
||||||
|
toggleDetailedTemp(id){
|
||||||
|
const tempDom = document.getElementById(`temp-${id}`);
|
||||||
|
const tempDetailShow = tempDom.getAttribute('temp-detail-show');
|
||||||
|
const tempMain = document.getElementById(`temp-main-${id}`);
|
||||||
|
const tempDetail = document.getElementById(`temp-detail-${id}`);
|
||||||
|
if (tempDetailShow == 0){
|
||||||
|
tempMain.style.display = 'none';
|
||||||
|
tempDetail.style.display = 'inline';
|
||||||
|
tempDom.setAttribute('temp-detail-show', 1);
|
||||||
|
} else {
|
||||||
|
tempMain.style.display = 'inline';
|
||||||
|
tempDetail.style.display = 'none';
|
||||||
|
tempDom.setAttribute('temp-detail-show', 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getTemperature(temperatureList, sensorList) {
|
||||||
|
// 将 sensorList 中的所有项转换为小写
|
||||||
|
const lowerCaseSensorList = sensorList.map(sensor => sensor.toLowerCase());
|
||||||
|
|
||||||
|
// 合并过滤逻辑:过滤出 Temperature 不为 0 且 Name 在 sensorList 中的元素(忽略大小写)
|
||||||
|
const filtered = temperatureList.filter(item => item.Temperature !== 0 && lowerCaseSensorList.includes(item.Name.toLowerCase()));
|
||||||
|
|
||||||
|
// 如果有匹配的元素,则计算这些元素的 Temperature 的最大值
|
||||||
|
if (filtered.length > 0) {
|
||||||
|
return filtered.reduce((max, current) => {
|
||||||
|
return current.Temperature > max ? current.Temperature : max;
|
||||||
|
}, filtered[0].Temperature);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有匹配的元素,则计算 temperatureList 中所有 Temperature 不为 0 的元素的最大值
|
||||||
|
const nonZeroTemps = temperatureList.filter(item => item.Temperature !== 0);
|
||||||
|
if (nonZeroTemps.length > 0) {
|
||||||
|
return nonZeroTemps.reduce((max, current) => {
|
||||||
|
return current.Temperature > max ? current.Temperature : max;
|
||||||
|
}, nonZeroTemps[0].Temperature);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果所有元素的 Temperature 都为 0,则返回一个默认值 0
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
showCharts(event, id) {
|
showCharts(event, id) {
|
||||||
const chartContainer = this.$refs[`chart${id}`][0];
|
const chartContainer = this.$refs[`chart${id}`][0];
|
||||||
const chartboxShow = chartContainer.getAttribute('chartbox-show');
|
const chartboxShow = chartContainer.getAttribute('chartbox-show');
|
||||||
@@ -308,7 +536,7 @@
|
|||||||
const data = item.avg_delay.map((avgDelay, index) => {
|
const data = item.avg_delay.map((avgDelay, index) => {
|
||||||
if(avgDelay > 0 && avgDelay < MaxTCPPingValue){
|
if(avgDelay > 0 && avgDelay < MaxTCPPingValue){
|
||||||
loss += avgDelay > 0.9 * MaxTCPPingValue ? 1 : 0;
|
loss += avgDelay > 0.9 * MaxTCPPingValue ? 1 : 0;
|
||||||
return [item.created_at[index], avgDelay];
|
return [item.created_at[index], avgDelay.toFixed(2)];
|
||||||
}else{
|
}else{
|
||||||
loss += 1;
|
loss += 1;
|
||||||
}
|
}
|
||||||
@@ -324,6 +552,21 @@
|
|||||||
connectNulls: true
|
connectNulls: true
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const legendData = chartData.map(item => item.monitor_name);
|
||||||
|
const maxLegendsPerRowMobile = localStorage.getItem("maxLegendsPerRowMobile") ? localStorage.getItem("maxLegendsPerRowMobile") : 3;
|
||||||
|
const maxLegendsPerRowPc = localStorage.getItem("maxLegendsPerRowPc") ? localStorage.getItem("maxLegendsPerRowPc") : 6;
|
||||||
|
const autoIncrement = Math.floor((legendData.length - 1) / (isMobile ? maxLegendsPerRowMobile : maxLegendsPerRowPc)) * (isMobile ? 20 : 28)
|
||||||
|
const height = 300 + autoIncrement;
|
||||||
|
const gridTop = 40 + autoIncrement;
|
||||||
|
const legendIcon = isMobile ? 'rect' : "";
|
||||||
|
const itemWidth = isMobile ? 10 : 25;
|
||||||
|
const itemHeight = isMobile ? 10 : 14;
|
||||||
|
chart.resize({
|
||||||
|
width: 'auto',
|
||||||
|
height: height
|
||||||
|
});
|
||||||
|
|
||||||
const option = {
|
const option = {
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
title: {
|
title: {
|
||||||
@@ -339,8 +582,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
data: chartData.map(item => item.monitor_name),
|
data: legendData,
|
||||||
show: true,
|
show: true,
|
||||||
|
icon: legendIcon,
|
||||||
textStyle: {
|
textStyle: {
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
color: fontColor
|
color: fontColor
|
||||||
@@ -348,7 +592,9 @@
|
|||||||
top: legendTop,
|
top: legendTop,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: legendLeft,
|
left: legendLeft,
|
||||||
padding: legendPadding
|
padding: legendPadding,
|
||||||
|
itemWidth: itemWidth,
|
||||||
|
itemHeight: itemHeight,
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
@@ -380,7 +626,7 @@
|
|||||||
color: fontColor
|
color: fontColor
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
top: '40',
|
top: gridTop,
|
||||||
left: gridLeft,
|
left: gridLeft,
|
||||||
right: gridRight
|
right: gridRight
|
||||||
}
|
}
|
||||||
@@ -401,4 +647,3 @@
|
|||||||
</script>
|
</script>
|
||||||
{{template "theme-server-status/footer" .}}
|
{{template "theme-server-status/footer" .}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|||||||
+28
-9
@@ -22,9 +22,6 @@
|
|||||||
const monitorInfo = JSON.parse('{{.MonitorInfos}}');
|
const monitorInfo = JSON.parse('{{.MonitorInfos}}');
|
||||||
const initData = JSON.parse('{{.Servers}}').servers;
|
const initData = JSON.parse('{{.Servers}}').servers;
|
||||||
let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}};
|
let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}};
|
||||||
if (MaxTCPPingValue == null) {
|
|
||||||
MaxTCPPingValue = 1000;
|
|
||||||
}
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
delimiters: ['@#', '#@'],
|
delimiters: ['@#', '#@'],
|
||||||
@@ -171,19 +168,36 @@
|
|||||||
parseMonitorInfo(monitorInfo) {
|
parseMonitorInfo(monitorInfo) {
|
||||||
let tSeries = [];
|
let tSeries = [];
|
||||||
let tLegendData = [];
|
let tLegendData = [];
|
||||||
|
var lcolors = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'];
|
||||||
for (let i = 0; i < monitorInfo.result.length; i++) {
|
for (let i = 0; i < monitorInfo.result.length; i++) {
|
||||||
|
var lcolor = lcolors[i % lcolors.length];
|
||||||
|
var rgbaColorMarker = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.5)';
|
||||||
|
var rgbaColorBar = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.35)';
|
||||||
let loss = 0;
|
let loss = 0;
|
||||||
let data = [];
|
let data = [];
|
||||||
|
let datal = [];
|
||||||
for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) {
|
for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) {
|
||||||
avgDelay = Math.round(monitorInfo.result[i].avg_delay[j]);
|
avgDelay = Math.round(monitorInfo.result[i].avg_delay[j]);
|
||||||
if (avgDelay > 0.9 * MaxTCPPingValue) {
|
if (avgDelay > 0 && avgDelay < MaxTCPPingValue) {
|
||||||
loss += 1
|
|
||||||
}
|
|
||||||
if (avgDelay > 0) {
|
|
||||||
data.push([monitorInfo.result[i].created_at[j], avgDelay]);
|
data.push([monitorInfo.result[i].created_at[j], avgDelay]);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
loss += 1;
|
||||||
|
datal.push({
|
||||||
|
xAxis: monitorInfo.result[i].created_at[j],
|
||||||
|
label: { show: false },
|
||||||
|
emphasis: { disabled: true },
|
||||||
|
lineStyle: {
|
||||||
|
type: "solid",
|
||||||
|
color: rgbaColorBar
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1);
|
lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1);
|
||||||
|
if (lossRate > 99) {
|
||||||
|
datal = [];
|
||||||
|
}
|
||||||
legendName = monitorInfo.result[i].monitor_name +" "+ lossRate + "%";
|
legendName = monitorInfo.result[i].monitor_name +" "+ lossRate + "%";
|
||||||
tLegendData.push(legendName);
|
tLegendData.push(legendName);
|
||||||
tSeries.push({
|
tSeries.push({
|
||||||
@@ -192,10 +206,15 @@
|
|||||||
smooth: true,
|
smooth: true,
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
data: data,
|
data: data,
|
||||||
|
markLine: {
|
||||||
|
symbol: "none",
|
||||||
|
symbolSize :0,
|
||||||
|
data: datal
|
||||||
|
},
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', symbol: 'pin', name: 'Max', itemStyle: { color: '#f00' } },
|
{ type: 'max', symbol: 'pin', name: 'Max', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8 } },
|
||||||
{ type: 'min', symbol: 'pin', name: 'Min', itemStyle: { color: '#0f0' } }
|
{ type: 'min', symbol: 'pin', name: 'Min', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8, offset: [0, 7.5] }, symbolRotate: 180 }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+118
-99
@@ -4,74 +4,74 @@
|
|||||||
{{template "theme-server-status/content-nav" .}}
|
{{template "theme-server-status/content-nav" .}}
|
||||||
<!-- showGroup true -->
|
<!-- showGroup true -->
|
||||||
<template v-if="showGroup">
|
<template v-if="showGroup">
|
||||||
<section class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;" v-for="group in servicesTag">
|
<section v-if="servicesTag.length === 0" class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;">
|
||||||
|
<p>No Valid Service Monitor Configuration Entries Found. Please Verify in the <a href="/monitor">Admin Panel</a>.</p>
|
||||||
|
</section>
|
||||||
|
<section v-else class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;" v-for="group in servicesTag">
|
||||||
{{template "theme-server-status/service-group-true" .}}
|
{{template "theme-server-status/service-group-true" .}}
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
<!-- showGroup false -->
|
<!-- showGroup false -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<section class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;">
|
<section v-if="servicesNoTag.length === 0" class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;">
|
||||||
|
<p>No Valid Service Monitor Configuration Entries Found. Please Verify in the <a href="/monitor">Admin Panel</a>.</p>
|
||||||
|
</section>
|
||||||
|
<section v-else class="container content" style="max-width: 95vw; min-height: .01%;overflow-x: auto;">
|
||||||
{{template "theme-server-status/service-group-false" .}}
|
{{template "theme-server-status/service-group-false" .}}
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
<section class="container content table-responsive" style="max-width: 95vw">
|
{{if .CycleTransferStats}}
|
||||||
{{if .CycleTransferStats}}
|
<section class="container content table-responsive" style="max-width: 95vw">
|
||||||
<table class="table table-striped table-condensed table-hover">
|
<table class="table table-striped table-condensed table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="node-group-tag">
|
<tr class="node-group-tag">
|
||||||
<th colspan="16" style="border:none;">
|
<th colspan="16" style="border:none;">
|
||||||
{{tr "CycleTransferStats"}}
|
{{tr "CycleTransferStats"}}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="node-group-cell">
|
<tr class="node-group-cell">
|
||||||
<th class="node-cell center">ID</th>
|
<th class="node-cell center">ID</th>
|
||||||
<th class="node-cell center">{{tr "Rules"}}</th>
|
<th class="node-cell center">{{tr "Rules"}}</th>
|
||||||
<th class="node-cell center">{{tr "Server"}}</th>
|
<th class="node-cell center">{{tr "Server"}}</th>
|
||||||
<th class="node-cell center">{{tr "From"}}</th>
|
<th class="node-cell center">{{tr "From"}}</th>
|
||||||
<th class="node-cell center">{{tr "To"}}</th>
|
<th class="node-cell center">{{tr "To"}}</th>
|
||||||
<th class="node-cell center">MAX</th>
|
<th class="node-cell center">MAX</th>
|
||||||
<th class="node-cell center">MIN</th>
|
<th class="node-cell center">MIN</th>
|
||||||
<th class="node-cell center">{{tr "NextCheck"}}</th>
|
<th class="node-cell center">{{tr "NextCheck"}}</th>
|
||||||
<th class="node-cell center">{{tr "CurrentUsage"}}</th>
|
<th class="node-cell center">{{tr "CurrentUsage"}}</th>
|
||||||
<th class="node-cell center">{{tr "Transleft"}}</th>
|
<th class="node-cell center">{{tr "Transleft"}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{range $id, $stats := .CycleTransferStats}}
|
{{range $id, $stats := .CycleTransferStats}}
|
||||||
{{range $innerId, $transfer := $stats.Transfer}}
|
{{range $innerId, $transfer := $stats.Transfer}}
|
||||||
{{$TransLeftPercent := TransLeftPercent (UintToFloat $transfer) (UintToFloat $stats.Max)}}
|
{{$TransLeftPercent := TransLeftPercent (UintToFloat $transfer) (UintToFloat $stats.Max)}}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="node-cell center">{{$id}}</td>
|
<td class="node-cell center">{{$id}}</td>
|
||||||
<td class="node-cell center">{{$stats.Name}}</td>
|
<td class="node-cell center">{{$stats.Name}}</td>
|
||||||
<td class="node-cell center">{{index $stats.ServerName $innerId}}</td>
|
<td class="node-cell center">{{index $stats.ServerName $innerId}}</td>
|
||||||
<td class="node-cell center">{{$stats.From|tf}}</td>
|
<td class="node-cell center">{{$stats.From|tf}}</td>
|
||||||
<td class="node-cell center">{{$stats.To|tf}}</td>
|
<td class="node-cell center">{{$stats.To|tf}}</td>
|
||||||
<td class="node-cell center">{{$stats.Max|bf}}</td>
|
<td class="node-cell center">{{$stats.Max|bf}}</td>
|
||||||
<td class="node-cell center">{{$stats.Min|bf}}</td>
|
<td class="node-cell center">{{$stats.Min|bf}}</td>
|
||||||
<td class="node-cell center">{{(index $stats.NextUpdate $innerId)|sft}}</td>
|
<td class="node-cell center">{{(index $stats.NextUpdate $innerId)|sft}}</td>
|
||||||
<td class="node-cell center">{{$transfer|bf}}</td>
|
<td class="node-cell center">{{$transfer|bf}}</td>
|
||||||
<td class="node-cell center">
|
<td class="node-cell center">
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
<div style="width: {{$TransLeftPercent}}%" :class="'progress-bar progress-bar-' + toSSBar('{{TransClassName $TransLeftPercent}}')">
|
<div style="width: {{$TransLeftPercent}}%" :class="'progress-bar progress-bar-' + toSSBar('{{TransClassName $TransLeftPercent}}')">
|
||||||
<small style="display: inline-block;width: max-content;">{{TransLeft $stats.Max $transfer}} / {{$TransLeftPercent}} %</small>
|
<small style="display: inline-block;width: max-content;">{{TransLeft $stats.Max $transfer}} / {{$TransLeftPercent}} %</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{{end}}
|
</section>
|
||||||
</section>
|
{{end}}
|
||||||
{{template "theme-server-status/content-footer" .}}
|
{{template "theme-server-status/content-footer" .}}
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
// 初始化 Tooltip
|
|
||||||
$(document).ready(function(){
|
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<script>
|
<script>
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
@@ -80,13 +80,16 @@
|
|||||||
page: 'service',
|
page: 'service',
|
||||||
defaultTemplate: {{.Conf.Site.Theme}},
|
defaultTemplate: {{.Conf.Site.Theme}},
|
||||||
templates: {{.Themes}},
|
templates: {{.Themes}},
|
||||||
|
services: {{.Services}},
|
||||||
servicesTag: [],
|
servicesTag: [],
|
||||||
servicesNoTag: [],
|
servicesNoTag: []
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initData();
|
this.servicesTag = this.groupingData(this.initData(this.services),"type");
|
||||||
|
this.servicesNoTag = this.initData(this.services);
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.initTooltip();
|
||||||
},
|
},
|
||||||
mixins: [mixinsVue],
|
mixins: [mixinsVue],
|
||||||
methods: {
|
methods: {
|
||||||
@@ -103,32 +106,36 @@
|
|||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
},
|
},
|
||||||
initData() {
|
initData(services) {
|
||||||
// @formatter:off
|
let nodes = [];
|
||||||
const services = []
|
for (let key in services) {
|
||||||
{{range $service := .Services}}
|
const service = services[key];
|
||||||
services.push({
|
let node = {
|
||||||
type: '{{$service.Monitor.Type}}',
|
type: service.Monitor.Type,
|
||||||
name: '{{$service.Monitor.Name}}',
|
name: service.Monitor.Name,
|
||||||
currentUp: parseInt('{{$service.CurrentUp}}'),
|
currentUp: parseInt(service.CurrentUp),
|
||||||
currentDown: parseInt('{{$service.CurrentDown}}'),
|
currentDown: parseInt(service.CurrentDown),
|
||||||
totalUp: parseInt('{{$service.TotalUp}}'),
|
totalUp: parseInt(service.TotalUp),
|
||||||
totalDown: parseInt('{{$service.TotalDown}}'),
|
totalDown: parseInt(service.TotalDown),
|
||||||
delay: '{{$service.Delay}}'.replaceAll("[","").replaceAll("]","").split(" "),
|
up: service.Up,
|
||||||
up: '{{$service.Up}}'.replaceAll("[","").replaceAll("]","").split(" "),
|
down: service.Down,
|
||||||
down: '{{$service.Down}}'.replaceAll("[","").replaceAll("]","").split(" "),
|
delay: service.Delay,
|
||||||
})
|
avgDelay: parseInt(this.getAvgDelay(service.Delay)) + "ms",
|
||||||
{{end}}
|
health: this.getStateInfo(this.getPercent(service.CurrentUp, service.CurrentDown)),
|
||||||
// @formatter:on
|
totalUpTime: this.getProgressInfo(this.getPercent(service.TotalUp, service.TotalDown))
|
||||||
for (let i = 0; i < services.length; i++) {
|
};
|
||||||
const service = services[i];
|
nodes.push(node);
|
||||||
service.avgDelay = parseInt(service.delay[service.delay.length - 1]) + "ms"
|
};
|
||||||
service.health = this.getStateInfo(this.getPercent(service.currentUp, service.currentDown))
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
service.dayDetail = this.getDayTails(service)
|
const node = nodes[i];
|
||||||
service.totalUpTime = this.getProgressInfo(this.getPercent(service.totalUp, service.totalDown))
|
node.dayDetail = this.getDayTails(node)
|
||||||
}
|
}
|
||||||
this.servicesTag = this.groupingData(services,"type");
|
return nodes
|
||||||
this.servicesNoTag = services;
|
},
|
||||||
|
initTooltip() {
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
getPercent(up, down) {
|
getPercent(up, down) {
|
||||||
if (!up) {
|
if (!up) {
|
||||||
@@ -151,24 +158,24 @@
|
|||||||
return this.toFixed2(currentUp / total * 100)
|
return this.toFixed2(currentUp / total * 100)
|
||||||
},
|
},
|
||||||
getDayTails(service) {
|
getDayTails(service) {
|
||||||
const result = []
|
const result = [];
|
||||||
for (let i = 0; i < service.up.length; i++) {
|
for (let i = 0; i < service.up.length; i++) {
|
||||||
const up = service.up[i]
|
const up = service.up[i];
|
||||||
const down = service.down[i]
|
const down = service.down[i];
|
||||||
const delay = service.delay[i]
|
let delay = Number(service.delay[i]);
|
||||||
let percent = this.getPercent(up, down)
|
let percent = this.getPercent(up, down);
|
||||||
if (percent <= 0) {
|
if (percent <= 0) {
|
||||||
percent = 0;
|
percent = 0;
|
||||||
}
|
}
|
||||||
let className = this.getStateInfo(percent).className
|
let className = this.getStateInfo(percent).className;
|
||||||
let available = '{{tr "Availability"}}'
|
let available = '{{tr "Availability"}}';
|
||||||
let averageLatency = '{{tr "AverageLatency"}}'
|
let averageLatency = '{{tr "AverageLatency"}}';
|
||||||
const text = `${this.beforeDay(service.up.length - i - 1)},${available}:${percent}%,${averageLatency}:${delay}ms`
|
const text = `${this.beforeDay(service.up.length - i - 1)},${available}:${Number(percent).toFixed(3)}%,${averageLatency}:${Number(delay).toFixed(3)}ms`;
|
||||||
result.push({
|
result.push({
|
||||||
text, className
|
text, className
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
return result
|
return result;
|
||||||
},
|
},
|
||||||
beforeDay(days) {
|
beforeDay(days) {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
@@ -203,12 +210,13 @@
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
getProgressInfo(percent) {
|
getProgressInfo(percent) {
|
||||||
const result = this.getStateInfo(percent)
|
const result = this.getStateInfo(percent);
|
||||||
result.style = `width: ${parseInt(percent)}%`;
|
result.style = `width: ${parseInt(percent)}%`;
|
||||||
|
result.percent = Number(percent).toFixed(2);
|
||||||
const className = result.className;
|
const className = result.className;
|
||||||
if (className === "good") {
|
if (className === "good") {
|
||||||
result.className = 'progress-bar progress-bar-success'
|
result.className = 'progress-bar progress-bar-success'
|
||||||
} else if (className === "waining") {
|
} else if (className === "warning") {
|
||||||
result.className = 'progress-bar progress-bar-warning'
|
result.className = 'progress-bar progress-bar-warning'
|
||||||
} else if (className === "danger") {
|
} else if (className === "danger") {
|
||||||
result.className = 'progress-bar progress-bar-danger'
|
result.className = 'progress-bar progress-bar-danger'
|
||||||
@@ -218,8 +226,19 @@
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
},
|
},
|
||||||
|
getAvgDelay(array) {
|
||||||
|
const { sum, count } = array.reduce((acc, value) => {
|
||||||
|
if (value !== 0) {
|
||||||
|
acc.sum += value;
|
||||||
|
acc.count += 1;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, { sum: 0, count: 0 });
|
||||||
|
|
||||||
|
return count > 0 ? sum / count : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
{{template "theme-server-status/footer" .}}
|
{{template "theme-server-status/footer" .}}
|
||||||
{{end}}
|
{{end}}
|
||||||
+10
-1
@@ -14,7 +14,7 @@ site:
|
|||||||
theme: "default"
|
theme: "default"
|
||||||
ddns:
|
ddns:
|
||||||
enable: false
|
enable: false
|
||||||
provider: "webhook"
|
provider: "webhook" # 如需使用多配置功能,请把此项留空
|
||||||
accessid: ""
|
accessid: ""
|
||||||
accesssecret: ""
|
accesssecret: ""
|
||||||
webhookmethod: ""
|
webhookmethod: ""
|
||||||
@@ -22,3 +22,12 @@ ddns:
|
|||||||
webhookrequestbody: ""
|
webhookrequestbody: ""
|
||||||
webhookheaders: ""
|
webhookheaders: ""
|
||||||
maxretries: 3
|
maxretries: 3
|
||||||
|
profiles:
|
||||||
|
example:
|
||||||
|
provider: ""
|
||||||
|
accessid: ""
|
||||||
|
accesssecret: ""
|
||||||
|
webhookmethod: ""
|
||||||
|
webhookurl: ""
|
||||||
|
webhookrequestbody: ""
|
||||||
|
webhookheaders: ""
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#========================================================
|
||||||
|
# System Required: macOS 10.13+
|
||||||
|
# Description: Nezha Agent Install Script (macOS)
|
||||||
|
# Github: https://github.com/naiba/nezha
|
||||||
|
#========================================================
|
||||||
|
|
||||||
|
NZ_BASE_PATH="/opt/nezha"
|
||||||
|
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
|
||||||
|
|
||||||
|
red='\033[0;31m'
|
||||||
|
green='\033[0;32m'
|
||||||
|
yellow='\033[0;33m'
|
||||||
|
plain='\033[0m'
|
||||||
|
export PATH=$PATH:/usr/local/bin
|
||||||
|
|
||||||
|
pre_check() {
|
||||||
|
# check root
|
||||||
|
[[ $EUID -ne 0 ]] && echo -e "${red}ERROR: ${plain} This script must be run with the root user!\n" && exit 1
|
||||||
|
|
||||||
|
## os_arch
|
||||||
|
if [[ $(uname -m | grep 'x86_64') != "" ]]; then
|
||||||
|
os_arch="amd64"
|
||||||
|
elif [[ $(uname -m | grep 'arm64\|arm64e') != "" ]]; then
|
||||||
|
os_arch="arm64"
|
||||||
|
fi
|
||||||
|
|
||||||
|
## China_IP
|
||||||
|
if [[ -z "${CN}" ]]; then
|
||||||
|
if [[ $(curl -m 10 -s https://ipapi.co/json | grep 'China') != "" ]]; then
|
||||||
|
echo "According to the information provided by ipapi.co, the current IP may be in China"
|
||||||
|
read -e -r -p "Is the installation done with a Chinese Mirror? [Y/n] (Custom Mirror Input 3):" input
|
||||||
|
case $input in
|
||||||
|
[yY][eE][sS] | [yY])
|
||||||
|
echo "Use Chinese Mirror"
|
||||||
|
CN=true
|
||||||
|
;;
|
||||||
|
|
||||||
|
[nN][oO] | [nN])
|
||||||
|
echo "No Use Chinese Mirror"
|
||||||
|
;;
|
||||||
|
|
||||||
|
[3])
|
||||||
|
echo "Use Custom Mirror"
|
||||||
|
read -e -r -p "Please enter a custom image (e.g. :dn-dao-github-mirror.daocloud.io), leave blank to nouse: " input
|
||||||
|
case $input in
|
||||||
|
*)
|
||||||
|
CUSTOM_MIRROR=$input
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "No Use Chinese Mirror"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${CUSTOM_MIRROR}" ]]; then
|
||||||
|
GITHUB_RAW_URL="gitee.com/naibahq/nezha/raw/master"
|
||||||
|
GITHUB_URL=$CUSTOM_MIRROR
|
||||||
|
else
|
||||||
|
if [[ -z "${CN}" ]]; then
|
||||||
|
GITHUB_RAW_URL="raw.githubusercontent.com/naiba/nezha/master"
|
||||||
|
GITHUB_URL="github.com"
|
||||||
|
Get_Docker_URL="get.docker.com"
|
||||||
|
Get_Docker_Argu=" "
|
||||||
|
Docker_IMG="ghcr.io\/naiba\/nezha-dashboard"
|
||||||
|
else
|
||||||
|
GITHUB_RAW_URL="gitee.com/naibahq/nezha/raw/master"
|
||||||
|
GITHUB_URL="github.com"
|
||||||
|
Get_Docker_URL="get.docker.com"
|
||||||
|
Get_Docker_Argu=" -s docker --mirror Aliyun"
|
||||||
|
Docker_IMG="registry.cn-shanghai.aliyuncs.com\/naibahq\/nezha-dashboard"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
before_show_menu() {
|
||||||
|
echo && echo -n -e "${yellow}* Press Enter to return to the main menu *${plain}" && read temp
|
||||||
|
show_menu
|
||||||
|
}
|
||||||
|
|
||||||
|
install_agent() {
|
||||||
|
echo -e "> Install Nezha Agent"
|
||||||
|
|
||||||
|
echo -e "Obtaining Agent version"
|
||||||
|
|
||||||
|
local version=$(curl -m 10 -sL "https://api.github.com/repos/nezhahq/agent/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
|
||||||
|
if [ ! -n "$version" ]; then
|
||||||
|
version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g')
|
||||||
|
fi
|
||||||
|
if [ ! -n "$version" ]; then
|
||||||
|
version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -n "$version" ]; then
|
||||||
|
echo -e "Fail to obtaine agent version, please check if the network can link https://api.github.com/repos/nezhahq/agent/releases/latest"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "The current latest version is: ${version}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Nezha Agent Folder
|
||||||
|
mkdir -p $NZ_AGENT_PATH
|
||||||
|
chmod -R 777 $NZ_AGENT_PATH
|
||||||
|
|
||||||
|
echo -e "Downloading Agent"
|
||||||
|
curl -o nezha-agent_darwin_${os_arch}.zip -L -f --retry 2 --retry-max-time 60 https://${GITHUB_URL}/nezhahq/agent/releases/download/${version}/nezha-agent_darwin_${os_arch}.zip >/dev/null 2>&1
|
||||||
|
if [[ $? != 0 ]]; then
|
||||||
|
echo -e "${red}Fail to download agent, please check if the network can link ${GITHUB_URL}${plain}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
unzip -qo nezha-agent_darwin_${os_arch}.zip &&
|
||||||
|
mv nezha-agent $NZ_AGENT_PATH &&
|
||||||
|
rm -rf nezha-agent_darwin_${os_arch}.zip README.md
|
||||||
|
|
||||||
|
if [ $# -ge 3 ]; then
|
||||||
|
modify_agent_config "$@"
|
||||||
|
else
|
||||||
|
modify_agent_config 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $# == 0 ]]; then
|
||||||
|
before_show_menu
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
modify_agent_config() {
|
||||||
|
echo -e "> Modify Agent Configuration"
|
||||||
|
|
||||||
|
if [ $# -lt 3 ]; then
|
||||||
|
echo "Please add Agent in the admin panel first, record the secret" &&
|
||||||
|
read -ep "Please enter a domain that resolves to the IP where the panel is located (no CDN sets): " nz_grpc_host &&
|
||||||
|
read -ep "Please enter the panel RPC port (default 5555): " nz_grpc_port &&
|
||||||
|
read -ep "Please enter the Agent secret: " nz_client_secret &&
|
||||||
|
read -ep "Do you want to enable SSL/TLS encryption for the gRPC port (--tls)? Press [y] if yes, the default is not required, and users can press Enter to skip if you don't understand: " nz_grpc_proxy
|
||||||
|
grep -qiw 'Y' <<<"${nz_grpc_proxy}" && args='--tls'
|
||||||
|
if [[ -z "${nz_grpc_host}" || -z "${nz_client_secret}" ]]; then
|
||||||
|
echo -e "${red}All options cannot be empty${plain}"
|
||||||
|
before_show_menu
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [[ -z "${nz_grpc_port}" ]]; then
|
||||||
|
nz_grpc_port=5555
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
nz_grpc_host=$1
|
||||||
|
nz_grpc_port=$2
|
||||||
|
nz_client_secret=$3
|
||||||
|
shift 3
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
args=" $*"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
${NZ_AGENT_PATH}/nezha-agent service install -s "$nz_grpc_host:$nz_grpc_port" -p $nz_client_secret $args >/dev/null 2>&1
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
${NZ_AGENT_PATH}/nezha-agent service uninstall >/dev/null 2>&1
|
||||||
|
${NZ_AGENT_PATH}/nezha-agent service install -s "$nz_grpc_host:$nz_grpc_port" -p $nz_client_secret $args >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "Agent configuration ${green} modified successfully, please wait for agent self-restart to take effect${plain}"
|
||||||
|
|
||||||
|
#if [[ $# == 0 ]]; then
|
||||||
|
# before_show_menu
|
||||||
|
#fi
|
||||||
|
}
|
||||||
|
|
||||||
|
show_agent_log() {
|
||||||
|
echo -e "> > View Agent Log"
|
||||||
|
|
||||||
|
tail -n 10 /var/log/nezha-agent.err.log
|
||||||
|
|
||||||
|
if [[ $# == 0 ]]; then
|
||||||
|
before_show_menu
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall_agent() {
|
||||||
|
echo -e "> Uninstall Agent"
|
||||||
|
|
||||||
|
${NZ_AGENT_PATH}/nezha-agent service uninstall
|
||||||
|
|
||||||
|
rm -rf $NZ_AGENT_PATH
|
||||||
|
clean_all
|
||||||
|
|
||||||
|
if [[ $# == 0 ]]; then
|
||||||
|
before_show_menu
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
restart_agent() {
|
||||||
|
echo -e "> Restart Agent"
|
||||||
|
|
||||||
|
${NZ_AGENT_PATH}/nezha-agent service restart
|
||||||
|
|
||||||
|
if [[ $# == 0 ]]; then
|
||||||
|
before_show_menu
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_all() {
|
||||||
|
if [ -z "$(ls -A ${NZ_BASE_PATH})" ]; then
|
||||||
|
rm -rf ${NZ_BASE_PATH}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
show_usage() {
|
||||||
|
echo "Nezha Agent Management Script Usage: "
|
||||||
|
echo "--------------------------------------------------------"
|
||||||
|
echo "./nezha.sh install_agent - Install Agent"
|
||||||
|
echo "./nezha.sh modify_agent_config - Modify Agent Configuration"
|
||||||
|
echo "./nezha.sh show_agent_log - View Agent Log"
|
||||||
|
echo "./nezha.sh uninstall_agent - Uninstall Agent"
|
||||||
|
echo "./nezha.sh restart_agent - Restart Agent"
|
||||||
|
echo "./nezha.sh update_script - Update Script"
|
||||||
|
echo "--------------------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
show_menu() {
|
||||||
|
echo -e "
|
||||||
|
${green}Nezha Agent Management Script${plain} ${red}macOS${plain}
|
||||||
|
--- https://github.com/naiba/nezha ---
|
||||||
|
${green}1.${plain} Install Agent
|
||||||
|
${green}2.${plain} Modify Agent Configuration
|
||||||
|
${green}3.${plain} View Agent Log
|
||||||
|
${green}4.${plain} Uninstall Agent
|
||||||
|
${green}5.${plain} Restart Agent
|
||||||
|
————————————————-
|
||||||
|
${green}0.${plain} Exit Script
|
||||||
|
"
|
||||||
|
echo && read -ep "Please enter [0-5]: " num
|
||||||
|
case "${num}" in
|
||||||
|
0)
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
1)
|
||||||
|
install_agent
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
modify_agent_config
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
show_agent_log
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
uninstall_agent
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
restart_agent
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${red}Please enter the correct number [0-5]${plain}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
pre_check
|
||||||
|
|
||||||
|
if [[ $# > 0 ]]; then
|
||||||
|
case $1 in
|
||||||
|
"install_agent")
|
||||||
|
shift
|
||||||
|
if [ $# -ge 3 ]; then
|
||||||
|
install_agent "$@"
|
||||||
|
else
|
||||||
|
install_agent 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"modify_agent_config")
|
||||||
|
modify_agent_config 0
|
||||||
|
;;
|
||||||
|
"show_agent_log")
|
||||||
|
show_agent_log 0
|
||||||
|
;;
|
||||||
|
"uninstall_agent")
|
||||||
|
uninstall_agent 0
|
||||||
|
;;
|
||||||
|
"restart_agent")
|
||||||
|
restart_agent 0
|
||||||
|
;;
|
||||||
|
*) show_usage ;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
show_menu
|
||||||
|
fi
|
||||||
+30
-25
@@ -7,64 +7,69 @@ if($PSVersionTable.PSVersion.Major -lt 5){
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
$agentrepo = "nezhahq/agent"
|
$agentrepo = "nezhahq/agent"
|
||||||
$nssmrepo = "nezhahq/nssm-backup"
|
# x86 or x64 or arm64
|
||||||
# x86 or x64
|
|
||||||
if ([System.Environment]::Is64BitOperatingSystem) {
|
if ([System.Environment]::Is64BitOperatingSystem) {
|
||||||
$file = "nezha-agent_windows_amd64.zip"
|
if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") {
|
||||||
|
$file = "nezha-agent_windows_arm64.zip"
|
||||||
|
} else {
|
||||||
|
$file = "nezha-agent_windows_amd64.zip"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$file = "nezha-agent_windows_386.zip"
|
$file = "nezha-agent_windows_386.zip"
|
||||||
}
|
}
|
||||||
$agentreleases = "https://api.github.com/repos/$agentrepo/releases"
|
$agentreleases = "https://api.github.com/repos/$agentrepo/releases"
|
||||||
$nssmreleases = "https://api.github.com/repos/$nssmrepo/releases"
|
|
||||||
#重复运行自动更新
|
#重复运行自动更新
|
||||||
if (Test-Path "C:\nezha") {
|
if (Test-Path "C:\nezha\nezha-agent.exe") {
|
||||||
Write-Host "Nezha monitoring already exists, delete and reinstall" -BackgroundColor DarkGreen -ForegroundColor White
|
Write-Host "Nezha monitoring already exists, delete and reinstall" -BackgroundColor DarkGreen -ForegroundColor White
|
||||||
C:/nezha/nssm.exe stop nezha
|
C:\nezha\nezha-agent.exe service uninstall
|
||||||
C:/nezha/nssm.exe remove nezha
|
|
||||||
Remove-Item "C:\nezha" -Recurse
|
Remove-Item "C:\nezha" -Recurse
|
||||||
}
|
}
|
||||||
#TLS/SSL
|
#TLS/SSL
|
||||||
Write-Host "Determining latest nezha release" -BackgroundColor DarkGreen -ForegroundColor White
|
Write-Host "Determining latest nezha release" -BackgroundColor DarkGreen -ForegroundColor White
|
||||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
$agenttag = (Invoke-WebRequest -Uri $agentreleases -UseBasicParsing | ConvertFrom-Json)[0].tag_name
|
$agenttag = (Invoke-WebRequest -Uri $agentreleases -UseBasicParsing | ConvertFrom-Json)[0].tag_name
|
||||||
$nssmtag = (Invoke-WebRequest -Uri $nssmreleases -UseBasicParsing | ConvertFrom-Json)[0].tag_name
|
if ([string]::IsNullOrWhiteSpace($agenttag)) {
|
||||||
|
$optionUrl = "https://fastly.jsdelivr.net/gh/nezhahq/agent/"
|
||||||
|
Try {
|
||||||
|
$response = Invoke-WebRequest -Uri $optionUrl -UseBasicParsing -TimeoutSec 10
|
||||||
|
if ($response.StatusCode -eq 200) {
|
||||||
|
$versiontext = $response.Content | findstr /c:"option.value"
|
||||||
|
$version = [regex]::Match($versiontext, "@(\d+\.\d+\.\d+)").Groups[1].Value
|
||||||
|
$agenttag = "v" + $version
|
||||||
|
}
|
||||||
|
} Catch {
|
||||||
|
$optionUrl = "https://gcore.jsdelivr.net/gh/nezhahq/agent/"
|
||||||
|
$response = Invoke-WebRequest -Uri $optionUrl -UseBasicParsing -TimeoutSec 10
|
||||||
|
if ($response.StatusCode -eq 200) {
|
||||||
|
$versiontext = $response.Content | findstr /c:"option.value"
|
||||||
|
$version = [regex]::Match($versiontext, "@(\d+\.\d+\.\d+)").Groups[1].Value
|
||||||
|
$agenttag = "v" + $version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#Region判断
|
#Region判断
|
||||||
$ipapi= Invoke-RestMethod -Uri "https://api.myip.com/" -UserAgent "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1"
|
$ipapi= Invoke-RestMethod -Uri "https://api.myip.com/" -UserAgent "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1"
|
||||||
$region=$ipapi.cc
|
$region=$ipapi.cc
|
||||||
echo $ipapi
|
echo $ipapi
|
||||||
if($region -ne "CN"){
|
if($region -ne "CN"){
|
||||||
$download = "https://github.com/$agentrepo/releases/download/$agenttag/$file"
|
$download = "https://github.com/$agentrepo/releases/download/$agenttag/$file"
|
||||||
$nssmdownload="https://github.com/$nssmrepo/releases/download/$nssmtag/nssm.zip"
|
|
||||||
Write-Host "Location:$region,connect directly!" -BackgroundColor DarkRed -ForegroundColor Green
|
Write-Host "Location:$region,connect directly!" -BackgroundColor DarkRed -ForegroundColor Green
|
||||||
}else{
|
}else{
|
||||||
$download = "https://dn-dao-github-mirror.daocloud.io/$agentrepo/releases/download/$agenttag/$file"
|
$download = "https://github.com/$agentrepo/releases/download/$agenttag/$file"
|
||||||
$nssmdownload="https://dn-dao-github-mirror.daocloud.io/$nssmrepo/releases/download/$nssmtag/nssm.zip"
|
|
||||||
Write-Host "Location:CN,use mirror address" -BackgroundColor DarkRed -ForegroundColor Green
|
Write-Host "Location:CN,use mirror address" -BackgroundColor DarkRed -ForegroundColor Green
|
||||||
}
|
}
|
||||||
echo $download
|
echo $download
|
||||||
echo $nssmdownload
|
|
||||||
Invoke-WebRequest $download -OutFile "C:\nezha.zip"
|
Invoke-WebRequest $download -OutFile "C:\nezha.zip"
|
||||||
#使用nssm安装服务
|
|
||||||
Invoke-WebRequest $nssmdownload -OutFile "C:\nssm.zip"
|
|
||||||
#解压
|
#解压
|
||||||
Expand-Archive "C:\nezha.zip" -DestinationPath "C:\temp" -Force
|
Expand-Archive "C:\nezha.zip" -DestinationPath "C:\temp" -Force
|
||||||
Expand-Archive "C:\nssm.zip" -DestinationPath "C:\temp" -Force
|
|
||||||
if (!(Test-Path "C:\nezha")) { New-Item -Path "C:\nezha" -type directory }
|
if (!(Test-Path "C:\nezha")) { New-Item -Path "C:\nezha" -type directory }
|
||||||
#整理文件
|
#整理文件
|
||||||
Move-Item -Path "C:\temp\nezha-agent.exe" -Destination "C:\nezha\nezha-agent.exe"
|
Move-Item -Path "C:\temp\nezha-agent.exe" -Destination "C:\nezha\nezha-agent.exe"
|
||||||
if ($file = "nezha-agent_windows_amd64.zip") {
|
|
||||||
Move-Item -Path "C:\temp\nssm-2.24\win64\nssm.exe" -Destination "C:\nezha\nssm.exe"
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Move-Item -Path "C:\temp\nssm-2.24\win32\nssm.exe" -Destination "C:\nezha\nssm.exe"
|
|
||||||
}
|
|
||||||
#清理垃圾
|
#清理垃圾
|
||||||
Remove-Item "C:\nezha.zip"
|
Remove-Item "C:\nezha.zip"
|
||||||
Remove-Item "C:\nssm.zip"
|
|
||||||
Remove-Item "C:\temp" -Recurse
|
Remove-Item "C:\temp" -Recurse
|
||||||
#安装部分
|
#安装部分
|
||||||
C:\nezha\nssm.exe install nezha C:\nezha\nezha-agent.exe -s $server -p $key $tls -d
|
C:\nezha\nezha-agent.exe service install -s $server -p $key $tls
|
||||||
C:\nezha\nssm.exe start nezha
|
|
||||||
#enjoy
|
#enjoy
|
||||||
Write-Host "Enjoy It!" -BackgroundColor DarkGreen -ForegroundColor Red
|
Write-Host "Enjoy It!" -BackgroundColor DarkGreen -ForegroundColor Red
|
||||||
+385
-637
File diff suppressed because it is too large
Load Diff
+365
-613
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
|||||||
#!/sbin/openrc-run
|
|
||||||
supervisor=supervise-daemon
|
|
||||||
name=nezha-agent
|
|
||||||
supervise_daemon_args="--stdout /var/log/${name}.log --stderr /var/log/${name}.err"
|
|
||||||
SERVER="nz_grpc_host:nz_grpc_port" #Dashboard 地址 ip:port
|
|
||||||
SECRET="nz_client_secret" #SECRET
|
|
||||||
NZ_BASE_PATH="/opt/nezha"
|
|
||||||
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
|
|
||||||
pidfile="/run/${RC_SVCNAME}.pid"
|
|
||||||
command="/opt/nezha/agent/nezha-agent"
|
|
||||||
command_args="-s ${SERVER} -p ${SECRET}"
|
|
||||||
command_background=true
|
|
||||||
depend() {
|
|
||||||
need net
|
|
||||||
}
|
|
||||||
checkconfig() {
|
|
||||||
GITHUB_URL="github.com"
|
|
||||||
if [ ! -f "${NZ_AGENT_PATH}/nezha-agent" ]; then
|
|
||||||
if [[ $(uname -m | grep 'x86_64') != "" ]]; then
|
|
||||||
os_arch="amd64"
|
|
||||||
elif [[ $(uname -m | grep 'i386\|i686') != "" ]]; then
|
|
||||||
os_arch="386"
|
|
||||||
elif [[ $(uname -m | grep 'aarch64\|armv8b\|armv8l') != "" ]]; then
|
|
||||||
os_arch="arm64"
|
|
||||||
elif [[ $(uname -m | grep 'arm') != "" ]]; then
|
|
||||||
os_arch="arm"
|
|
||||||
elif [[ $(uname -m | grep 's390x') != "" ]]; then
|
|
||||||
os_arch="s390x"
|
|
||||||
elif [[ $(uname -m | grep 'riscv64') != "" ]]; then
|
|
||||||
os_arch="riscv64"
|
|
||||||
fi
|
|
||||||
local version=$(curl -m 10 -sL "https://api.github.com/repos/nezhahq/agent/releases/latest" | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g')
|
|
||||||
if [ ! -n "$version" ]; then
|
|
||||||
version=$(curl -m 10 -sL "https://fastly.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g')
|
|
||||||
fi
|
|
||||||
if [ ! -n "$version" ]; then
|
|
||||||
version=$(curl -m 10 -sL "https://gcore.jsdelivr.net/gh/nezhahq/agent/" | grep "option\.value" | awk -F "'" '{print $2}' | sed 's/nezhahq\/agent@/v/g')
|
|
||||||
fi
|
|
||||||
if [ ! -n "$version" ]; then
|
|
||||||
echo -e "获取版本号失败,请检查本机能否链接 https://api.github.com/repos/nezhahq/agent/releases/latest"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo -e "当前最新版本为: ${version}"
|
|
||||||
fi
|
|
||||||
wget -t 2 -T 10 -O nezha-agent_linux_${os_arch}.zip https://${GITHUB_URL}/nezhahq/agent/releases/download/${version}/nezha-agent_linux_${os_arch}.zip >/dev/null 2>&1
|
|
||||||
if [[ $? != 0 ]]; then
|
|
||||||
echo -e "Release 下载失败,请检查本机能否连接 ${GITHUB_URL}${plain}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
mkdir -p $NZ_AGENT_PATH
|
|
||||||
chmod 755 -R $NZ_AGENT_PATH
|
|
||||||
unzip -qo nezha-agent_linux_${os_arch}.zip && mv nezha-agent $NZ_AGENT_PATH && rm -rf nezha-agent_linux_${os_arch}.zip README.md
|
|
||||||
fi
|
|
||||||
if [ ! -x "${NZ_AGENT_PATH}/nezha-agent" ]; then
|
|
||||||
chmod +x ${NZ_AGENT_PATH}/nezha-agent
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
start_pre() {
|
|
||||||
if [ "${RC_CMD}" != "restart" ]; then
|
|
||||||
checkconfig || return $?
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Nezha Agent
|
|
||||||
After=syslog.target
|
|
||||||
#After=network.target
|
|
||||||
#After=nezha-dashboard.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
# Modify these two values and uncomment them if you have
|
|
||||||
# repos with lots of files and get an HTTP error 500 because
|
|
||||||
# of that
|
|
||||||
###
|
|
||||||
#LimitMEMLOCK=infinity
|
|
||||||
#LimitNOFILE=65535
|
|
||||||
Type=simple
|
|
||||||
User=root
|
|
||||||
Group=root
|
|
||||||
WorkingDirectory=/opt/nezha/agent/
|
|
||||||
ExecStart=/opt/nezha/agent/nezha-agent -s nz_grpc_host:nz_grpc_port -p nz_client_secret
|
|
||||||
Restart=always
|
|
||||||
#Environment=DEBUG=true
|
|
||||||
|
|
||||||
# Some distributions may not support these hardening directives. If you cannot start the service due
|
|
||||||
# to an unknown option, comment out the ones not supported by your version of systemd.
|
|
||||||
#ProtectSystem=full
|
|
||||||
#PrivateDevices=yes
|
|
||||||
#PrivateTmp=yes
|
|
||||||
#NoNewPrivileges=true
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
Regular → Executable
+7
-5
@@ -1,4 +1,8 @@
|
|||||||
#!/sbin/openrc-run
|
#!/sbin/openrc-run
|
||||||
|
supervisor=supervise-daemon
|
||||||
|
name=nezha-dashboard
|
||||||
|
output_log=/var/log/${name}.log
|
||||||
|
error_log=/var/log/${name}.err
|
||||||
pidfile="/run/${RC_SVCNAME}.pid"
|
pidfile="/run/${RC_SVCNAME}.pid"
|
||||||
command="/opt/nezha/dashboard/app"
|
command="/opt/nezha/dashboard/app"
|
||||||
command_args=""
|
command_args=""
|
||||||
@@ -6,11 +10,9 @@ command_background=true
|
|||||||
directory="/opt/nezha/dashboard"
|
directory="/opt/nezha/dashboard"
|
||||||
|
|
||||||
depend() {
|
depend() {
|
||||||
need net
|
need net
|
||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
start_pre() {
|
||||||
ebegin "Reloading ${RC_SVCNAME}"
|
checkpath -f -m 0644 -o root:root "/var/log/${name}.log"
|
||||||
start-stop-daemon --signal HUP --pidfile "${pidfile}"
|
|
||||||
eend $?
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ func (s *NezhaHandler) ReportSystemState(c context.Context, r *pb.State) (*pb.Re
|
|||||||
|
|
||||||
func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Receipt, error) {
|
func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Receipt, error) {
|
||||||
var clientID uint64
|
var clientID uint64
|
||||||
|
var provider ddns.Provider
|
||||||
var err error
|
var err error
|
||||||
if clientID, err = s.Auth.Check(c); err != nil {
|
if clientID, err = s.Auth.Check(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -122,13 +123,17 @@ func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Rece
|
|||||||
singleton.ServerList[clientID].Host.IP != host.IP {
|
singleton.ServerList[clientID].Host.IP != host.IP {
|
||||||
|
|
||||||
serverDomain := singleton.ServerList[clientID].DDNSDomain
|
serverDomain := singleton.ServerList[clientID].DDNSDomain
|
||||||
provider, err := singleton.GetDDNSProviderFromString(singleton.Conf.DDNS.Provider)
|
if singleton.Conf.DDNS.Provider == "" {
|
||||||
|
provider, err = singleton.GetDDNSProviderFromProfile(singleton.ServerList[clientID].DDNSProfile)
|
||||||
|
} else {
|
||||||
|
provider, err = singleton.GetDDNSProviderFromString(singleton.Conf.DDNS.Provider)
|
||||||
|
}
|
||||||
if err == nil && serverDomain != "" {
|
if err == nil && serverDomain != "" {
|
||||||
ipv4, ipv6, _ := utils.SplitIPAddr(host.IP)
|
ipv4, ipv6, _ := utils.SplitIPAddr(host.IP)
|
||||||
maxRetries := int(singleton.Conf.DDNS.MaxRetries)
|
maxRetries := int(singleton.Conf.DDNS.MaxRetries)
|
||||||
config := &ddns.DomainConfig{
|
config := &ddns.DomainConfig{
|
||||||
EnableIPv4: true,
|
EnableIPv4: singleton.ServerList[clientID].EnableIPv4,
|
||||||
EnableIpv6: true,
|
EnableIpv6: singleton.ServerList[clientID].EnableIpv6,
|
||||||
FullDomain: serverDomain,
|
FullDomain: serverDomain,
|
||||||
Ipv4Addr: ipv4,
|
Ipv4Addr: ipv4,
|
||||||
Ipv6Addr: ipv6,
|
Ipv6Addr: ipv6,
|
||||||
@@ -137,7 +142,7 @@ func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Rece
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 虽然会在启动时panic, 可以断言不会走这个分支, 但是考虑到动态加载配置或者其它情况, 这里输出一下方便检查奇奇怪怪的BUG
|
// 虽然会在启动时panic, 可以断言不会走这个分支, 但是考虑到动态加载配置或者其它情况, 这里输出一下方便检查奇奇怪怪的BUG
|
||||||
log.Printf("NEZHA>> 未找到对应的DDNS提供者(%s), 请前往config.yml检查你的设置\n", singleton.Conf.DDNS.Provider)
|
log.Printf("NEZHA>> 未找到对应的DDNS配置(%s), 或者是provider填写不正确, 请前往config.yml检查你的设置\n", singleton.ServerList[clientID].DDNSProfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package singleton
|
package singleton
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
ddns2 "github.com/naiba/nezha/pkg/ddns"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
ddns2 "github.com/naiba/nezha/pkg/ddns"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RetryableUpdateDomain(provider ddns2.Provider, config *ddns2.DomainConfig, maxRetries int) bool {
|
func RetryableUpdateDomain(provider ddns2.Provider, config *ddns2.DomainConfig, maxRetries int) bool {
|
||||||
@@ -25,18 +25,64 @@ func RetryableUpdateDomain(provider ddns2.Provider, config *ddns2.DomainConfig,
|
|||||||
func GetDDNSProviderFromString(provider string) (ddns2.Provider, error) {
|
func GetDDNSProviderFromString(provider string) (ddns2.Provider, error) {
|
||||||
switch provider {
|
switch provider {
|
||||||
case "webhook":
|
case "webhook":
|
||||||
return ddns2.ProviderWebHook{
|
return &ddns2.ProviderWebHook{
|
||||||
URL: Conf.DDNS.WebhookURL,
|
URL: Conf.DDNS.WebhookURL,
|
||||||
RequestMethod: Conf.DDNS.WebhookMethod,
|
RequestMethod: Conf.DDNS.WebhookMethod,
|
||||||
RequestBody: Conf.DDNS.WebhookRequestBody,
|
RequestBody: Conf.DDNS.WebhookRequestBody,
|
||||||
RequestHeader: Conf.DDNS.WebhookHeaders,
|
RequestHeader: Conf.DDNS.WebhookHeaders,
|
||||||
}, nil
|
}, nil
|
||||||
case "dummy":
|
case "dummy":
|
||||||
return ddns2.ProviderDummy{}, nil
|
return &ddns2.ProviderDummy{}, nil
|
||||||
case "cloudflare":
|
case "cloudflare":
|
||||||
return ddns2.ProviderCloudflare{
|
return &ddns2.ProviderCloudflare{
|
||||||
Secret: Conf.DDNS.AccessSecret,
|
Secret: Conf.DDNS.AccessSecret,
|
||||||
}, nil
|
}, nil
|
||||||
|
case "tencentcloud":
|
||||||
|
return &ddns2.ProviderTencentCloud{
|
||||||
|
SecretID: Conf.DDNS.AccessID,
|
||||||
|
SecretKey: Conf.DDNS.AccessSecret,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
return ddns2.ProviderDummy{}, errors.New(fmt.Sprintf("无法找到配置的DDNS提供者%s", Conf.DDNS.Provider))
|
return &ddns2.ProviderDummy{}, fmt.Errorf("无法找到配置的DDNS提供者%s", Conf.DDNS.Provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDDNSProviderFromProfile(profileName string) (ddns2.Provider, error) {
|
||||||
|
profile, ok := Conf.DDNS.Profiles[profileName]
|
||||||
|
if !ok {
|
||||||
|
return &ddns2.ProviderDummy{}, fmt.Errorf("未找到配置项 %s", profileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch profile.Provider {
|
||||||
|
case "webhook":
|
||||||
|
return &ddns2.ProviderWebHook{
|
||||||
|
URL: profile.WebhookURL,
|
||||||
|
RequestMethod: profile.WebhookMethod,
|
||||||
|
RequestBody: profile.WebhookRequestBody,
|
||||||
|
RequestHeader: profile.WebhookHeaders,
|
||||||
|
}, nil
|
||||||
|
case "dummy":
|
||||||
|
return &ddns2.ProviderDummy{}, nil
|
||||||
|
case "cloudflare":
|
||||||
|
return &ddns2.ProviderCloudflare{
|
||||||
|
Secret: profile.AccessSecret,
|
||||||
|
}, nil
|
||||||
|
case "tencentcloud":
|
||||||
|
return &ddns2.ProviderTencentCloud{
|
||||||
|
SecretID: profile.AccessID,
|
||||||
|
SecretKey: profile.AccessSecret,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return &ddns2.ProviderDummy{}, fmt.Errorf("无法找到配置的DDNS提供者%s", profile.Provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateDDNSProvidersFromProfiles() error {
|
||||||
|
validProviders := map[string]bool{"webhook": true, "dummy": true, "cloudflare": true, "tencentcloud": true}
|
||||||
|
providers := make(map[string]string)
|
||||||
|
for profileName, profile := range Conf.DDNS.Profiles {
|
||||||
|
if _, ok := validProviders[profile.Provider]; !ok {
|
||||||
|
return fmt.Errorf("无法找到配置的DDNS提供者%s", profile.Provider)
|
||||||
|
}
|
||||||
|
providers[profileName] = profile.Provider
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ func (ss *ServiceSentinel) Monitors() []*model.Monitor {
|
|||||||
return monitors
|
return monitors
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadStats 加载服务监控器的历史状态信息
|
// loadMonitorHistory 加载服务监控器的历史状态信息
|
||||||
func (ss *ServiceSentinel) loadMonitorHistory() {
|
func (ss *ServiceSentinel) loadMonitorHistory() {
|
||||||
var monitors []*model.Monitor
|
var monitors []*model.Monitor
|
||||||
err := DB.Find(&monitors).Error
|
err := DB.Find(&monitors).Error
|
||||||
@@ -335,7 +335,7 @@ func (ss *ServiceSentinel) worker() {
|
|||||||
// 从服务状态汇报管道获取汇报的服务数据
|
// 从服务状态汇报管道获取汇报的服务数据
|
||||||
for r := range ss.serviceReportChannel {
|
for r := range ss.serviceReportChannel {
|
||||||
if ss.monitors[r.Data.GetId()] == nil || ss.monitors[r.Data.GetId()].ID == 0 {
|
if ss.monitors[r.Data.GetId()] == nil || ss.monitors[r.Data.GetId()].ID == 0 {
|
||||||
log.Printf("NEZAH>> 错误的服务监控上报 %+v", r)
|
log.Printf("NEZHA>> 错误的服务监控上报 %+v", r)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
mh := r.Data
|
mh := r.Data
|
||||||
|
|||||||
@@ -52,12 +52,16 @@ func InitConfigFromPath(path string) {
|
|||||||
|
|
||||||
// ValidateConfig 验证配置文件有效性
|
// ValidateConfig 验证配置文件有效性
|
||||||
func ValidateConfig() {
|
func ValidateConfig() {
|
||||||
// 如果DDNS启用则检查Provider是否存在, 不存在直接退出
|
var err error
|
||||||
|
if Conf.DDNS.Provider == "" {
|
||||||
|
err = ValidateDDNSProvidersFromProfiles()
|
||||||
|
} else {
|
||||||
|
_, err = GetDDNSProviderFromString(Conf.DDNS.Provider)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
if Conf.DDNS.Enable {
|
if Conf.DDNS.Enable {
|
||||||
_, err := GetDDNSProviderFromString(Conf.DDNS.Provider)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if Conf.DDNS.MaxRetries < 1 || Conf.DDNS.MaxRetries > 10 {
|
if Conf.DDNS.MaxRetries < 1 || Conf.DDNS.MaxRetries > 10 {
|
||||||
panic(fmt.Errorf("DDNS.MaxRetries值域为[1, 10]的整数, 当前为 %d", Conf.DDNS.MaxRetries))
|
panic(fmt.Errorf("DDNS.MaxRetries值域为[1, 10]的整数, 当前为 %d", Conf.DDNS.MaxRetries))
|
||||||
}
|
}
|
||||||
@@ -89,7 +93,7 @@ func RecordTransferHourlyUsage() {
|
|||||||
ServerLock.Lock()
|
ServerLock.Lock()
|
||||||
defer ServerLock.Unlock()
|
defer ServerLock.Unlock()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
nowTrimSeconds := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, Loc)
|
nowTrimSeconds := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location())
|
||||||
var txs []model.Transfer
|
var txs []model.Transfer
|
||||||
for id, server := range ServerList {
|
for id, server := range ServerList {
|
||||||
tx := model.Transfer{
|
tx := model.Transfer{
|
||||||
@@ -132,7 +136,7 @@ func CleanMonitorHistory() {
|
|||||||
if !rule.IsTransferDurationRule() {
|
if !rule.IsTransferDurationRule() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dataCouldRemoveBefore := rule.GetTransferDurationStart()
|
dataCouldRemoveBefore := rule.GetTransferDurationStart().UTC()
|
||||||
// 判断规则影响的机器范围
|
// 判断规则影响的机器范围
|
||||||
if rule.Cover == model.RuleCoverAll {
|
if rule.Cover == model.RuleCoverAll {
|
||||||
// 更新全局可以清理的数据点
|
// 更新全局可以清理的数据点
|
||||||
@@ -151,12 +155,12 @@ func CleanMonitorHistory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for id, couldRemove := range specialServerKeep {
|
for id, couldRemove := range specialServerKeep {
|
||||||
DB.Unscoped().Delete(&model.Transfer{}, "server_id = ? AND created_at < ?", id, couldRemove)
|
DB.Unscoped().Delete(&model.Transfer{}, "server_id = ? AND datetime(`created_at`) < datetime(?)", id, couldRemove)
|
||||||
}
|
}
|
||||||
if allServerKeep.IsZero() {
|
if allServerKeep.IsZero() {
|
||||||
DB.Unscoped().Delete(&model.Transfer{}, "server_id NOT IN (?)", specialServerIDs)
|
DB.Unscoped().Delete(&model.Transfer{}, "server_id NOT IN (?)", specialServerIDs)
|
||||||
} else {
|
} else {
|
||||||
DB.Unscoped().Delete(&model.Transfer{}, "server_id NOT IN (?) AND created_at < ?", specialServerIDs, allServerKeep)
|
DB.Unscoped().Delete(&model.Transfer{}, "server_id NOT IN (?) AND datetime(`created_at`) < datetime(?)", specialServerIDs, allServerKeep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user