mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-10 16:00:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e8581a7de | ||
|
|
0ba83d1353 | ||
|
|
a302e100ec | ||
|
|
4f58fd492d | ||
|
|
0b06a4fac6 | ||
|
|
4e1a7bf42c | ||
|
|
ef2fb1c62e | ||
|
|
f5fcbcd87a | ||
|
|
986bffaf2b | ||
|
|
766a2a0546 | ||
|
|
291b594ad9 | ||
|
|
7742e3da38 | ||
|
|
c5f70eae4c | ||
|
|
8bdf02c4c0 | ||
|
|
8abe132c25 | ||
|
|
3a447b02a1 | ||
|
|
aa718eef88 | ||
|
|
60b1c9ba32 | ||
|
|
9b50581fd4 | ||
|
|
ee33fdab89 | ||
|
|
c8f19467ba | ||
|
|
1fc0f1c71b | ||
|
|
2258ba108d | ||
|
|
d21f4ffae6 | ||
|
|
4bd9c4c0fc | ||
|
|
29165f0f6f | ||
|
|
f75b786916 | ||
|
|
011914339e | ||
|
|
08a07214ef | ||
|
|
f682f07dbc | ||
|
|
50e99f1f4c | ||
|
|
feabc488fe | ||
|
|
72d3f5071b | ||
|
|
27dc662430 | ||
|
|
80e233c4a6 | ||
|
|
a099308a82 | ||
|
|
6f0673f184 | ||
|
|
b428e699db | ||
|
|
f4334eadc0 | ||
|
|
a2a6503030 | ||
|
|
9c22005b79 | ||
|
|
7448953b7d | ||
|
|
18214095ab | ||
|
|
bcfc78e510 | ||
|
|
cc6b506176 | ||
|
|
c61828fb39 | ||
|
|
23876ed186 | ||
|
|
ac4962cf19 | ||
|
|
d9e7c8d880 | ||
|
|
ea25b800d2 | ||
|
|
7ba06e73d7 | ||
|
|
39cf26628f | ||
|
|
ea7f324a9d | ||
|
|
789d451ea2 | ||
|
|
7313f3d591 | ||
|
|
1662546bef | ||
|
|
53f75086ec | ||
|
|
81fcc61ec9 | ||
|
|
324a47966b | ||
|
|
5a0c50b9a2 | ||
|
|
66465beb39 | ||
|
|
c5d403f10a | ||
|
|
598098c2ed | ||
|
|
bff1a8ad60 | ||
|
|
592e315f21 | ||
|
|
76933bc6ef | ||
|
|
0dc312db64 | ||
|
|
4deb92e715 | ||
|
|
bc95e47b92 | ||
|
|
f2335d313c | ||
|
|
4c287f4a2d | ||
|
|
0a6e1c275b | ||
|
|
ff2dc05e7f | ||
|
|
f62ce085bf | ||
|
|
29306827ba | ||
|
|
222d07175a | ||
|
|
663196c3d9 | ||
|
|
df839714a3 | ||
|
|
dcb004e983 | ||
|
|
cee0604efc | ||
|
|
dfbd364f60 | ||
|
|
339d6732d7 | ||
|
|
b0dbfb4c7c | ||
|
|
021603d25d | ||
|
|
a875e1ec5c | ||
|
|
5c5904216b | ||
|
|
1dae294d76 | ||
|
|
acbb151b15 | ||
|
|
a1311a2a0d | ||
|
|
bc8d564ce8 | ||
|
|
97cdf7bc78 | ||
|
|
ce69b4de01 | ||
|
|
e880df8142 | ||
|
|
a35ca87778 | ||
|
|
5a34e2d380 | ||
|
|
abf3247c50 | ||
|
|
8663ed129d | ||
|
|
c0a0f4c801 | ||
|
|
e84aa49003 | ||
|
|
6f45b90520 | ||
|
|
0685984a80 | ||
|
|
5f33c083bf | ||
|
|
ab0e0f3f43 | ||
|
|
6b62b84157 | ||
|
|
fd9627576b | ||
|
|
39f334f3a2 | ||
|
|
ca84909716 | ||
|
|
283609cf2d | ||
|
|
9591409fe2 | ||
|
|
9cf52ccc97 | ||
|
|
261cb2061b | ||
|
|
f45af6e0cc | ||
|
|
c752ea4959 | ||
|
|
b2b578a5f0 | ||
|
|
47e60bfdcb | ||
|
|
780b6cdec9 | ||
|
|
0a5b13a418 | ||
|
|
ebdc3f05de | ||
|
|
aad79077bf | ||
|
|
00b25b39c5 | ||
|
|
dd6a709053 | ||
|
|
99b04e3635 | ||
|
|
2e06b78409 | ||
|
|
c7d603e142 | ||
|
|
4fcf845934 | ||
|
|
83cefb2a72 | ||
|
|
7ab40996e0 | ||
|
|
bbe4d49947 | ||
|
|
b6fbacc992 | ||
|
|
89491eac56 | ||
|
|
acf27693b2 | ||
|
|
5fd9d20f99 | ||
|
|
fd9c421969 | ||
|
|
f5bae6d75c | ||
|
|
4ac8bc7bd2 | ||
|
|
ec81d0d2c3 | ||
|
|
815b633fb8 | ||
|
|
c69c76f97d | ||
|
|
75197db3e6 | ||
|
|
d09d686378 | ||
|
|
d6f16cf700 | ||
|
|
536a5fc1a0 | ||
|
|
a07df9d7fe | ||
|
|
e9c195c778 | ||
|
|
0637ca308b | ||
|
|
fd1e0e72a0 | ||
|
|
34b80373c7 | ||
|
|
1ade1b8d8b | ||
|
|
19fa30fb96 | ||
|
|
efe7815a7e | ||
|
|
e9b4ff1932 | ||
|
|
0dca3fc997 | ||
|
|
4e6ebb53ac | ||
|
|
83ed835c9e | ||
|
|
7bcc897379 | ||
|
|
cd2109fefe | ||
|
|
d337c4726d | ||
|
|
356e6a4ef6 | ||
|
|
037da3a7fd | ||
|
|
18462296ae | ||
|
|
1d76e54b0d | ||
|
|
22c903f555 | ||
|
|
6d4d53e2c7 | ||
|
|
6b81ae1b7b | ||
|
|
5b62a0f2b3 | ||
|
|
137465683a | ||
|
|
6be7b4a75a | ||
|
|
58ca377418 | ||
|
|
b173e808c7 | ||
|
|
ec44ba9335 | ||
|
|
f54ac59ff7 | ||
|
|
db44204c1a | ||
|
|
ec01aef71a | ||
|
|
b706774b5b | ||
|
|
9eee2d6b6f | ||
|
|
c9d4e2a4b5 | ||
|
|
4c4df5cbb0 | ||
|
|
cb69128838 | ||
|
|
81af207dc5 | ||
|
|
5e9c43fc71 | ||
|
|
fb44e3c1e2 | ||
|
|
7e23ae126a | ||
|
|
7e229c05e7 | ||
|
|
764fc8fec4 | ||
|
|
ad17918c84 | ||
|
|
d7013727b9 | ||
|
|
6a8bd11fc9 | ||
|
|
4df0c3e461 | ||
|
|
f8f47b51e9 | ||
|
|
b735178fcd | ||
|
|
1759c2c81e | ||
|
|
2be7054b40 | ||
|
|
c77d2f7dd6 | ||
|
|
3256ac9f44 | ||
|
|
b156ef9476 | ||
|
|
c49c16cbb5 | ||
|
|
2b7ec9ffe1 | ||
|
|
c2ad006a19 | ||
|
|
c12bab477c | ||
|
|
fe39545cf6 | ||
|
|
39d3b819fb | ||
|
|
04a0e15899 | ||
|
|
3dc81d85e9 | ||
|
|
5a8ddde495 | ||
|
|
4e6f872c02 | ||
|
|
e76836f394 | ||
|
|
9fed5f4bb8 | ||
|
|
b3a55ea44d | ||
|
|
270411f7fd | ||
|
|
3c01198e61 | ||
|
|
483b47ad63 | ||
|
|
b10de66ed3 | ||
|
|
305eff048c | ||
|
|
da7968d364 | ||
|
|
d3e2c8e9d3 | ||
|
|
e3a9f2dfb7 | ||
|
|
3c967f8906 | ||
|
|
39bb7acdba | ||
|
|
a30066989b | ||
|
|
0c30dfa092 | ||
|
|
7a44493d13 | ||
|
|
9b726d5d22 | ||
|
|
78e3d9e5fb | ||
|
|
d74b41a5f2 | ||
|
|
f122afdbec | ||
|
|
37308b5c42 | ||
|
|
9c5a6e3925 | ||
|
|
58b95ef2ba | ||
|
|
f617c9d5dd | ||
|
|
c661cc37b3 | ||
|
|
7c49f6c79b | ||
|
|
12b9356c17 | ||
|
|
d3a34293f7 | ||
|
|
c131061f81 | ||
|
|
6a5e1ebaa5 | ||
|
|
a07d016951 | ||
|
|
9d343a90db | ||
|
|
4c813be09d | ||
|
|
d48166f546 | ||
|
|
0f138c1b7c | ||
|
|
8542323c0b | ||
|
|
00f103c66a | ||
|
|
430c75e7ed | ||
|
|
67ffb5e938 | ||
|
|
9c292bebf0 | ||
|
|
ba4307c1dc | ||
|
|
b8b2041a0c | ||
|
|
c45bb60b50 | ||
|
|
fba46be47a | ||
|
|
be0a460935 | ||
|
|
c0a041d024 | ||
|
|
2ce5ad82ce | ||
|
|
50dcb6c7e4 | ||
|
|
017424bf7b | ||
|
|
c7e7407f7c | ||
|
|
cab42b3c7d | ||
|
|
78f280c88f | ||
|
|
22f5a975c3 | ||
|
|
90ba036e39 | ||
|
|
d1e18e43ee | ||
|
|
a801140a82 | ||
|
|
951ab2502e | ||
|
|
0316cb0662 | ||
|
|
04b9cbd87a | ||
|
|
4565c5b300 | ||
|
|
bf9a9bf17a | ||
|
|
70df4dc6c4 | ||
|
|
ed3e738fff | ||
|
|
bc376ec495 | ||
|
|
40314e9079 | ||
|
|
82f978c683 | ||
|
|
ed288368ea | ||
|
|
db8fa144eb | ||
|
|
57b76d97ec | ||
|
|
28d8210ce6 | ||
|
|
80ce60c56c | ||
|
|
2758ab07dc | ||
|
|
0828804de2 | ||
|
|
134b17d2f0 | ||
|
|
3af254cdda | ||
|
|
f3d3d54722 | ||
|
|
fa419809f6 | ||
|
|
da606826c6 | ||
|
|
b3d9cc156a | ||
|
|
ba03d26b2c | ||
|
|
40f02889fe | ||
|
|
4f8fb26d89 | ||
|
|
0ca11e2b88 | ||
|
|
0daf0d690c | ||
|
|
0cfdf0f335 | ||
|
|
cca1863b63 | ||
|
|
033f08a6d2 | ||
|
|
a83a6690ff | ||
|
|
83df457379 | ||
|
|
657e55cde3 | ||
|
|
90e76e3a0f | ||
|
|
2af1993383 | ||
|
|
6e650d977e | ||
|
|
8a76171dbe | ||
|
|
949b6fe944 | ||
|
|
3f90333090 | ||
|
|
aeaca0c5cd | ||
|
|
fb7f638a54 | ||
|
|
7994193a39 | ||
|
|
3334bf594d | ||
|
|
71193cc912 | ||
|
|
9fde8c447d | ||
|
|
117faa952e | ||
|
|
6427337728 | ||
|
|
81f97f6f88 | ||
|
|
b3b472d711 | ||
|
|
1c22e1cf99 | ||
|
|
3110d91bf6 | ||
|
|
624a11407a | ||
|
|
ead6d1268f | ||
|
|
80c00c5a8c | ||
|
|
da0f6acd01 | ||
|
|
485aa99dea | ||
|
|
5f68d7ce90 | ||
|
|
685fca6c8c | ||
|
|
9c609da332 | ||
|
|
84608b7d42 | ||
|
|
02cf2a80cb | ||
|
|
a74c6dd522 | ||
|
|
5d4ab23d95 | ||
|
|
a8faba3206 | ||
|
|
c603495b12 | ||
|
|
adce6103bd | ||
|
|
6b673017c5 | ||
|
|
e66bd43fc6 | ||
|
|
ff5cdb9a02 | ||
|
|
1aec5e443d | ||
|
|
0b1f7e9322 | ||
|
|
3ec2dec49b | ||
|
|
7cbebc8236 | ||
|
|
700076f278 | ||
|
|
7bf1bf61a7 | ||
|
|
ef2cb1b315 | ||
|
|
75bfc3a114 | ||
|
|
70f63090fe | ||
|
|
ab2cf0d0c3 | ||
|
|
ea1a34f57a | ||
|
|
765add6184 | ||
|
|
e5263d6c05 | ||
|
|
c391177d34 | ||
|
|
7d5f0aa906 | ||
|
|
2694a725d6 | ||
|
|
54ca40bbcd | ||
|
|
b20411f8f1 | ||
|
|
355e656caa | ||
|
|
383bdd5f15 | ||
|
|
96208c786d | ||
|
|
4c7b04cf27 | ||
|
|
a067a97e21 | ||
|
|
4a07603a7c | ||
|
|
7196c5b656 | ||
|
|
b5de2df119 | ||
|
|
2f72eb37ee | ||
|
|
0128cd3138 | ||
|
|
157d3093f8 | ||
|
|
4ca188973e | ||
|
|
f387d89a45 | ||
|
|
54567db22f | ||
|
|
2bee68dd40 | ||
|
|
e2b6ea5253 | ||
|
|
9974c5fa20 | ||
|
|
997b706d8a | ||
|
|
3f26412585 | ||
|
|
ac99d77fbb | ||
|
|
4f6f7632f5 | ||
|
|
f74248f0d7 | ||
|
|
bb8a15ca56 | ||
|
|
52432002c7 | ||
|
|
3fade48f8f | ||
|
|
fc81801c4c | ||
|
|
c23c5b2859 | ||
|
|
ccec57e32d | ||
|
|
56ae5fbf70 | ||
|
|
735b44856e | ||
|
|
1f6ea9f494 | ||
|
|
afa643519f | ||
|
|
1767b84026 | ||
|
|
e855e7692e | ||
|
|
94d37eb68a | ||
|
|
e10b19bcde | ||
|
|
e9192e75ea | ||
|
|
2fa4f68b1e | ||
|
|
08f53a4a37 | ||
|
|
c522295c56 | ||
|
|
7a45548387 | ||
|
|
810ea9c421 | ||
|
|
ba6a4fe6d7 | ||
|
|
4d144f7a8e | ||
|
|
45c41184c1 | ||
|
|
5c29c5e7dd | ||
|
|
4da9a84363 | ||
|
|
22d8fb7867 | ||
|
|
c7058cb3e6 | ||
|
|
e6092b2658 | ||
|
|
ae19b72e61 | ||
|
|
da117582d6 | ||
|
|
c7ca1ccbd7 | ||
|
|
911b5c406d | ||
|
|
71ed4b946a | ||
|
|
4ef9fcde59 | ||
|
|
7889b5ad69 | ||
|
|
be6d3ea337 | ||
|
|
64fd715973 | ||
|
|
315f99a03a | ||
|
|
7e1351c543 | ||
|
|
bd3c829653 | ||
|
|
4f6dde02d2 | ||
|
|
8cc7d1f67f | ||
|
|
2bbba9d755 | ||
|
|
e9e4755348 | ||
|
|
9fbb63df95 | ||
|
|
5b5a649589 | ||
|
|
79556affbd | ||
|
|
9cba19d4db | ||
|
|
4f377c04b8 | ||
|
|
763df5606b | ||
|
|
e1d20e3ec9 | ||
|
|
215c082a04 | ||
|
|
984985e650 | ||
|
|
249b3c3245 | ||
|
|
725786d6aa | ||
|
|
2edddaf487 | ||
|
|
49cbab08c1 | ||
|
|
a75df66151 | ||
|
|
43e9c13c5e | ||
|
|
5ad06f121b | ||
|
|
0eaaf7aacb | ||
|
|
dd44fdd1f2 | ||
|
|
669855de70 | ||
|
|
193ae2b7d6 | ||
|
|
af4b23e0e0 | ||
|
|
c35991315d | ||
|
|
9aa852370c | ||
|
|
8f18497551 | ||
|
|
4c59951e8c | ||
|
|
eb2a80d216 | ||
|
|
41d0175a6d | ||
|
|
2f6aa0f45b | ||
|
|
17c685bc4c | ||
|
|
cf230ca6e7 | ||
|
|
bb99853000 | ||
|
|
0c64c8ff52 | ||
|
|
e3e2006c19 | ||
|
|
eddc1b6a8d | ||
|
|
83e1db723e | ||
|
|
76c608c703 | ||
|
|
d61a77bec7 | ||
|
|
a6a2d9991c | ||
|
|
060dd08167 | ||
|
|
dd1d93e096 | ||
|
|
e4b24f51fc | ||
|
|
e472269a4e | ||
|
|
4032276556 | ||
|
|
420537f092 | ||
|
|
3867e536b2 | ||
|
|
4bc7b96ae4 | ||
|
|
9f0338382f | ||
|
|
692c77eb1a | ||
|
|
0778e3e81d | ||
|
|
80e217e839 | ||
|
|
47547ad4e1 | ||
|
|
8b22acce27 | ||
|
|
754ac64bf6 | ||
|
|
3b37d5ae72 | ||
|
|
4e2f24a8f0 | ||
|
|
23a1fbdd4b | ||
|
|
795223e7fa | ||
|
|
10039c6173 | ||
|
|
146b628cc1 | ||
|
|
0c31fcc8a3 | ||
|
|
2c290dbbf7 | ||
|
|
0df8a33b9e | ||
|
|
1278e910f5 | ||
|
|
429e2c6cbe | ||
|
|
00a5cc654a | ||
|
|
d68a0b076b | ||
|
|
99ef8e9310 | ||
|
|
5e549fdb71 | ||
|
|
8f7b026f0e | ||
|
|
fabf33a83b | ||
|
|
211c956c4b | ||
|
|
55d966a52e | ||
|
|
a0d5319cd9 | ||
|
|
d9358b87c4 | ||
|
|
89526d9075 | ||
|
|
b1799d8c06 | ||
|
|
185eaf1211 | ||
|
|
4aa7dbfa9f | ||
|
|
daef59b568 | ||
|
|
be2c30c9e0 | ||
|
|
3b166801d6 | ||
|
|
c289a5f14f | ||
|
|
5dfb4def56 | ||
|
|
c6d70f4dc8 | ||
|
|
254a6e6dbf | ||
|
|
62c010ce13 | ||
|
|
272536a3b5 | ||
|
|
13dc94aca5 | ||
|
|
b9a80f15e6 | ||
|
|
5cab80d842 | ||
|
|
8a4ff3c809 | ||
|
|
5b9e13f35b | ||
|
|
fd5437139b | ||
|
|
26852b6676 | ||
|
|
b8a02cc094 | ||
|
|
f7fa6cf567 | ||
|
|
64e74e87c4 | ||
|
|
f843438baf | ||
|
|
4528f1feaf | ||
|
|
1eae519e1a | ||
|
|
1416fb0f6e | ||
|
|
e9257735ba | ||
|
|
81caf126f7 |
@@ -12,7 +12,7 @@ jobs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.2'
|
||||
node-version: '22.19.0'
|
||||
- name: Build Web
|
||||
run: |
|
||||
cd frontend && npm install && npm run build:pro
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.2'
|
||||
node-version: '22.19.0'
|
||||
- name: Build Web
|
||||
run: |
|
||||
cd frontend && npm install && npm run build:pro
|
||||
|
||||
@@ -32,6 +32,7 @@ builds:
|
||||
- arm
|
||||
- ppc64le
|
||||
- s390x
|
||||
- riscv64
|
||||
hooks:
|
||||
post:
|
||||
- ./ci/script.sh compress_binary {{ .Path }} {{ .Arch }}
|
||||
@@ -57,6 +58,7 @@ builds:
|
||||
- arm
|
||||
- ppc64le
|
||||
- s390x
|
||||
- riscv64
|
||||
hooks:
|
||||
post:
|
||||
- ./ci/script.sh compress_binary {{ .Path }} {{ .Arch }}
|
||||
|
||||
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"ansible.python.interpreterPath": "/opt/homebrew/bin/python3"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -125,4 +125,4 @@ enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
https://www.contributor-covenant.org/translations.
|
||||
|
||||
@@ -60,7 +60,7 @@ func (b *BaseApi) RecreateOllamaModel(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /ai/ollama/model/close [post]
|
||||
// @Router /ai/ollama/close [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"关闭 Ollama 模型连接 [name]","formatEN":"close conn for Ollama model [name]"}
|
||||
func (b *BaseApi) CloseOllamaModel(c *gin.Context) {
|
||||
var req dto.OllamaModelName
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (b *BaseApi) PageAlert(c *gin.Context) {
|
||||
var req dto.AlertSearch
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
total, alerts, err := alertService.PageAlert(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Total: total,
|
||||
Items: alerts,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetAlerts(c *gin.Context) {
|
||||
alerts, err := alertService.GetAlerts()
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, alerts)
|
||||
}
|
||||
|
||||
func (b *BaseApi) CreateAlert(c *gin.Context) {
|
||||
var req dto.AlertCreate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
err := alertService.CreateAlert(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteAlert(c *gin.Context) {
|
||||
var req dto.DeleteRequest
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
err := alertService.DeleteAlert(req.ID)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
func (b *BaseApi) UpdateAlert(c *gin.Context) {
|
||||
var req dto.AlertUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := alertService.UpdateAlert(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetAlert(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, errors.New("no such id in request param"))
|
||||
return
|
||||
}
|
||||
alert, err := alertService.GetAlert(id)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, alert)
|
||||
}
|
||||
|
||||
func (b *BaseApi) UpdateAlertStatus(c *gin.Context) {
|
||||
var req dto.AlertUpdateStatus
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := alertService.UpdateStatus(req.ID, req.Status); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetDisks(c *gin.Context) {
|
||||
alerts, err := alertService.GetDisks()
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, alerts)
|
||||
}
|
||||
|
||||
func (b *BaseApi) PageAlertLogs(c *gin.Context) {
|
||||
var req dto.AlertLogSearch
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
total, alertLogs, err := alertService.PageAlertLogs(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Total: total,
|
||||
Items: alertLogs,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *BaseApi) CleanAlertLogs(c *gin.Context) {
|
||||
if err := alertService.CleanAlertLogs(); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetClams(c *gin.Context) {
|
||||
clams, err := alertService.GetClams()
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, clams)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetCronJobs(c *gin.Context) {
|
||||
var req dto.CronJobReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
cronJobs, err := alertService.GetCronJobs(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, cronJobs)
|
||||
}
|
||||
|
||||
func (b *BaseApi) GetAlertConfig(c *gin.Context) {
|
||||
config, err := alertService.GetAlertConfig()
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, config)
|
||||
}
|
||||
|
||||
func (b *BaseApi) UpdateAlertConfig(c *gin.Context) {
|
||||
var req dto.AlertConfigUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := alertService.UpdateAlertConfig(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
func (b *BaseApi) DeleteAlertConfig(c *gin.Context) {
|
||||
var req dto.DeleteRequest
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
err := alertService.DeleteAlertConfig(req.ID)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
func (b *BaseApi) TestAlertConfig(c *gin.Context) {
|
||||
var req dto.AlertConfigTest
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
flag, err := alertService.TestAlertConfig(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, flag)
|
||||
}
|
||||
@@ -109,7 +109,7 @@ func (b *BaseApi) LoadPort(c *gin.Context) {
|
||||
// @Success 200 {object} response.DatabaseConn
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /apps/installed/conninfo/:key [get]
|
||||
// @Router /apps/installed/conninfo [POST]
|
||||
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -327,3 +327,25 @@ func (b *BaseApi) UpdateAppConfig(c *gin.Context) {
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Get app install info
|
||||
// @Accept json
|
||||
// @Param appInstallId path integer true "App install id"
|
||||
// @Success 200 {object} dto.AppInstallInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /apps/installed/info/:appInstallId [get]
|
||||
func (b *BaseApi) GetAppInstallInfo(c *gin.Context) {
|
||||
appInstallId, err := helper.GetIntParamByKey(c, "appInstallId")
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
info, err := appInstallService.GetAppInstallInfo(appInstallId)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, info)
|
||||
}
|
||||
|
||||
+34
-12
@@ -74,7 +74,7 @@ func (b *BaseApi) RefreshToken(c *gin.Context) {
|
||||
// @Success 200 {array} object
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /buckets [post]
|
||||
// @Router /backups/buckets [post]
|
||||
func (b *BaseApi) ListBuckets(c *gin.Context) {
|
||||
var req dto.ForBuckets
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -133,6 +133,28 @@ func (b *BaseApi) UpdateBackup(c *gin.Context) {
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Backup Account
|
||||
// @Summary Upload file for recover
|
||||
// @Accept json
|
||||
// @Param request body dto.UploadForRecover true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /backups/upload [post]
|
||||
// @x-panel-log {"bodyKeys":["filePath"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传备份文件 [filePath]","formatEN":"upload backup file [filePath]"}
|
||||
func (b *BaseApi) UploadForRecover(c *gin.Context) {
|
||||
var req dto.UploadForRecover
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := backupService.UploadForRecover(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Backup Account
|
||||
// @Summary Load backup account options
|
||||
// @Accept json
|
||||
@@ -273,7 +295,7 @@ func (b *BaseApi) SearchBackupRecordsByCronjob(c *gin.Context) {
|
||||
// @Success 200 {string} filePath
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /backup/record/download [post]
|
||||
// @Router /backups/record/download [post]
|
||||
// @x-panel-log {"bodyKeys":["source","fileName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载备份记录 [source][fileName]","formatEN":"download backup records [source][fileName]"}
|
||||
func (b *BaseApi) DownloadRecord(c *gin.Context) {
|
||||
var req dto.DownloadRecord
|
||||
@@ -296,7 +318,7 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /backup/record/description/update [post]
|
||||
// @Router /backups/record/description/update [post]
|
||||
func (b *BaseApi) UpdateRecordDescription(c *gin.Context) {
|
||||
var req dto.UpdateDescription
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -317,7 +339,7 @@ func (b *BaseApi) UpdateRecordDescription(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /record/del [post]
|
||||
// @Router /backups/record/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"backup_records","output_column":"file_name","output_value":"files"}],"formatZH":"删除备份记录 [files]","formatEN":"delete backup records [files]"}
|
||||
func (b *BaseApi) DeleteBackupRecord(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
@@ -371,12 +393,12 @@ func (b *BaseApi) Backup(c *gin.Context) {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
case "mysql", "mariadb":
|
||||
case "mysql", "mariadb", constant.AppMysqlCluster:
|
||||
if err := backupService.MysqlBackup(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
case constant.AppPostgresql:
|
||||
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
||||
if err := backupService.PostgresqlBackup(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
@@ -386,7 +408,7 @@ func (b *BaseApi) Backup(c *gin.Context) {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
case "redis":
|
||||
case "redis", constant.AppRedisCluster:
|
||||
if err := backupService.RedisBackup(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
@@ -421,12 +443,12 @@ func (b *BaseApi) Recover(c *gin.Context) {
|
||||
}
|
||||
req.File = downloadPath
|
||||
switch req.Type {
|
||||
case "mysql", "mariadb":
|
||||
case "mysql", "mariadb", constant.AppMysqlCluster:
|
||||
if err := backupService.MysqlRecover(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
case constant.AppPostgresql:
|
||||
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
||||
if err := backupService.PostgresqlRecover(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
@@ -436,7 +458,7 @@ func (b *BaseApi) Recover(c *gin.Context) {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
case "redis":
|
||||
case "redis", constant.AppRedisCluster:
|
||||
if err := backupService.RedisRecover(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
@@ -466,12 +488,12 @@ func (b *BaseApi) RecoverByUpload(c *gin.Context) {
|
||||
}
|
||||
|
||||
switch req.Type {
|
||||
case "mysql", "mariadb":
|
||||
case "mysql", "mariadb", constant.AppMysqlCluster:
|
||||
if err := backupService.MysqlRecoverByUpload(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
case constant.AppPostgresql:
|
||||
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
||||
if err := backupService.PostgresqlRecoverByUpload(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
|
||||
@@ -104,7 +104,7 @@ func (b *BaseApi) SearchClam(c *gin.Context) {
|
||||
// @Success 200 {object} dto.ClamBaseInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /toolbox/clam/base [get]
|
||||
// @Router /toolbox/clam/base [post]
|
||||
func (b *BaseApi) LoadClamBaseInfo(c *gin.Context) {
|
||||
info, err := clamService.LoadBaseInfo()
|
||||
if err != nil {
|
||||
@@ -152,7 +152,7 @@ func (b *BaseApi) CleanClamRecord(c *gin.Context) {
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := clamService.CleanRecord(req); err != nil {
|
||||
if err := clamService.CleanRecord(req.ID); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
@@ -174,7 +174,7 @@ func (b *BaseApi) SearchClamRecord(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
total, list, err := clamService.LoadRecords(req)
|
||||
total, list, err := clamService.SearchRecords(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
@@ -186,29 +186,6 @@ func (b *BaseApi) SearchClamRecord(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Clam
|
||||
// @Summary Load clam record detail
|
||||
// @Accept json
|
||||
// @Param request body dto.ClamLogReq true "request"
|
||||
// @Success 200 {string} content
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /toolbox/clam/record/log [post]
|
||||
func (b *BaseApi) LoadClamRecordLog(c *gin.Context) {
|
||||
var req dto.ClamLogReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
content, err := clamService.LoadRecordLog(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, content)
|
||||
}
|
||||
|
||||
// @Tags Clam
|
||||
// @Summary Load clam file
|
||||
// @Accept json
|
||||
@@ -289,7 +266,7 @@ func (b *BaseApi) HandleClamScan(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := clamService.HandleOnce(req); err != nil {
|
||||
if err := clamService.HandleOnce(req.ID); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -35,11 +35,29 @@ func (b *BaseApi) SearchContainer(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Load container users
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithName true "request"
|
||||
// @Produce json
|
||||
// @Success 200 {array} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/users [post]
|
||||
func (b *BaseApi) LoadContainerUsers(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, containerService.LoadUsers(req))
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary List containers
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {array} string
|
||||
// @Success 200 {array} dto.ContainerOptions
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/list [post]
|
||||
@@ -47,6 +65,23 @@ func (b *BaseApi) ListContainer(c *gin.Context) {
|
||||
helper.SuccessWithData(c, containerService.List())
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary List containers by image
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.ContainerOptions
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/list/byimage [post]
|
||||
func (b *BaseApi) ListContainerByImage(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, containerService.ListByImage(req.Name))
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Load containers status
|
||||
// @Accept json
|
||||
@@ -243,7 +278,7 @@ func (b *BaseApi) ContainerCreate(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := containerService.ContainerCreate(req); err != nil {
|
||||
if err := containerService.ContainerCreate(req, true); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
@@ -297,7 +332,7 @@ func (b *BaseApi) ContainerUpgrade(c *gin.Context) {
|
||||
// @Summary Clean container
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerPrune true "request"
|
||||
// @Success 200 {object} dto.ContainerPruneReport
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/prune [post]
|
||||
@@ -308,12 +343,11 @@ func (b *BaseApi) ContainerPrune(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
report, err := containerService.Prune(req)
|
||||
if err != nil {
|
||||
if err := containerService.Prune(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, report)
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
@@ -663,7 +697,7 @@ func (b *BaseApi) ComposeUpdate(c *gin.Context) {
|
||||
// @Param tail query string false "显示行号"
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/search/log [post]
|
||||
// @Router /containers/search/log [get]
|
||||
func (b *BaseApi) ContainerStreamLogs(c *gin.Context) {
|
||||
c.Header("Content-Type", "text/event-stream")
|
||||
c.Header("Cache-Control", "no-cache")
|
||||
|
||||
+67
-24
@@ -1,6 +1,8 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
@@ -53,6 +55,49 @@ func (b *BaseApi) LoadCronjobInfo(c *gin.Context) {
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Export cronjob list
|
||||
// @Accept json
|
||||
// @Param request body dto.OperateByIDs true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /cronjobs/export [post]
|
||||
func (b *BaseApi) ExportCronjob(c *gin.Context) {
|
||||
var req dto.OperateByIDs
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
content, err := cronjobService.Export(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
http.ServeContent(c.Writer, c.Request, "", time.Now(), strings.NewReader(content))
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Import cronjob list
|
||||
// @Accept json
|
||||
// @Param request body dto.CronjobImport true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /cronjobs/import [post]
|
||||
func (b *BaseApi) ImportCronjob(c *gin.Context) {
|
||||
var req dto.CronjobImport
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := cronjobService.Import(req.Cronjobs); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Load script options
|
||||
// @Success 200 {array} dto.ScriptOptions
|
||||
@@ -225,6 +270,28 @@ func (b *BaseApi) UpdateCronjob(c *gin.Context) {
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Update cronjob group
|
||||
// @Accept json
|
||||
// @Param request body dto.ChangeGroup true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /cronjobs/group/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"更新计划任务分组 [name]","formatEN":"update cronjob group [name]"}
|
||||
func (b *BaseApi) UpdateCronjobGroup(c *gin.Context) {
|
||||
var req dto.ChangeGroup
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := cronjobService.UpdateGroup(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Update cronjob status
|
||||
// @Accept json
|
||||
@@ -247,30 +314,6 @@ func (b *BaseApi) UpdateCronjobStatus(c *gin.Context) {
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Download cronjob records
|
||||
// @Accept json
|
||||
// @Param request body dto.CronjobDownload true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /cronjobs/download [post]
|
||||
// @x-panel-log {"bodyKeys":["recordID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"recordID","isList":false,"db":"job_records","output_column":"file","output_value":"file"}],"formatZH":"下载计划任务记录 [file]","formatEN":"download the cronjob record [file]"}
|
||||
func (b *BaseApi) TargetDownload(c *gin.Context) {
|
||||
var req dto.CronjobDownload
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
filePath, err := cronjobService.Download(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Handle cronjob once
|
||||
// @Accept json
|
||||
|
||||
@@ -83,6 +83,38 @@ func (b *BaseApi) UpdateAppLauncher(c *gin.Context) {
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Dashboard
|
||||
// @Summary Load quick jump options
|
||||
// @Success 200 {Array} dto.QuickJump
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /dashboard/quick/option [get]
|
||||
func (b *BaseApi) LoadQuickOption(c *gin.Context) {
|
||||
helper.SuccessWithData(c, dashboardService.LoadQuickOptions())
|
||||
}
|
||||
|
||||
// @Tags Dashboard
|
||||
// @Summary Update quick jump
|
||||
// @Accept json
|
||||
// @Param request body dto.ChangeQuicks true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /dashboard/quick/change [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"切换快速跳转","formatEN":"change quick jump"}
|
||||
func (b *BaseApi) UpdateQuickJump(c *gin.Context) {
|
||||
var req dto.ChangeQuicks
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := dashboardService.ChangeQuick(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Dashboard
|
||||
// @Summary Load dashboard base info
|
||||
// @Accept json
|
||||
|
||||
@@ -160,7 +160,7 @@ func (b *BaseApi) GetDatabase(c *gin.Context) {
|
||||
// @Success 200 {array} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /db/remote/del/check [post]
|
||||
// @Router /databases/db/del/check [post]
|
||||
func (b *BaseApi) DeleteCheckDatabase(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
|
||||
@@ -11,13 +11,13 @@ import (
|
||||
// @Tags Database Redis
|
||||
// @Summary Load redis status info
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithName true "request"
|
||||
// @Param request body dto.LoadRedisStatus true "request"
|
||||
// @Success 200 {object} dto.RedisStatus
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /databases/redis/status [post]
|
||||
func (b *BaseApi) LoadRedisStatus(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
var req dto.LoadRedisStatus
|
||||
if err := helper.CheckBind(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -33,13 +33,13 @@ func (b *BaseApi) LoadRedisStatus(c *gin.Context) {
|
||||
// @Tags Database Redis
|
||||
// @Summary Load redis conf
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithName true "request"
|
||||
// @Param request body dto.LoadRedisStatus true "request"
|
||||
// @Success 200 {object} dto.RedisConf
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /databases/redis/conf [post]
|
||||
func (b *BaseApi) LoadRedisConf(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
var req dto.LoadRedisStatus
|
||||
if err := helper.CheckBind(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -55,13 +55,13 @@ func (b *BaseApi) LoadRedisConf(c *gin.Context) {
|
||||
// @Tags Database Redis
|
||||
// @Summary Load redis persistence conf
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithName true "request"
|
||||
// @Param request body dto.LoadRedisStatus true "request"
|
||||
// @Success 200 {object} dto.RedisPersistence
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /databases/redis/persistence/conf [post]
|
||||
func (b *BaseApi) LoadPersistenceConf(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
var req dto.LoadRedisStatus
|
||||
if err := helper.CheckBind(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags Disk Management
|
||||
// @Summary Get complete disk information
|
||||
// @Description Get information about all disks including partitioned and unpartitioned disks
|
||||
// @Produce json
|
||||
// @Success 200 {object} response.CompleteDiskInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /hosts/disks [get]
|
||||
func (b *BaseApi) GetCompleteDiskInfo(c *gin.Context) {
|
||||
diskInfo, err := diskService.GetCompleteDiskInfo()
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, diskInfo)
|
||||
}
|
||||
|
||||
// @Tags Disk Management
|
||||
// @Summary Partition disk
|
||||
// @Description Create partition and format disk with specified filesystem
|
||||
// @Accept json
|
||||
// @Param request body request.DiskPartitionRequest true "partition request"
|
||||
// @Success 200 {string} string "Partition created successfully"
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /hosts/disks/partition [post]
|
||||
// @x-panel-log {"bodyKeys":["device", "filesystem", "mountPoint"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"对磁盘 [device] 进行分区,文件系统 [filesystem],挂载点 [mountPoint]","formatEN":"Partition disk [device] with filesystem [filesystem], mount point [mountPoint]"}
|
||||
func (b *BaseApi) PartitionDisk(c *gin.Context) {
|
||||
var req request.DiskPartitionRequest
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result, err := diskService.PartitionDisk(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, result)
|
||||
}
|
||||
|
||||
// @Tags Disk Management
|
||||
// @Summary Mount disk
|
||||
// @Description Mount partition to specified mount point
|
||||
// @Accept json
|
||||
// @Param request body request.DiskMountRequest true "mount request"
|
||||
// @Success 200 {string} string "Disk mounted successfully"
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /hosts/disks/mount [post]
|
||||
// @x-panel-log {"bodyKeys":["device", "mountPoint"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"挂载磁盘 [device] 到 [mountPoint]","formatEN":"Mount disk [device] to [mountPoint]"}
|
||||
func (b *BaseApi) MountDisk(c *gin.Context) {
|
||||
var req request.DiskMountRequest
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := diskService.MountDisk(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Disk Management
|
||||
// @Summary Unmount disk
|
||||
// @Description Unmount partition from mount point
|
||||
// @Accept json
|
||||
// @Param request body request.DiskUnmountRequest true "unmount request"
|
||||
// @Success 200 {string} string "Disk unmounted successfully"
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /hosts/disks/unmount [post]
|
||||
// @x-panel-log {"bodyKeys":["device", "mountPoint"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"卸载磁盘 [device] 从 [mountPoint]","formatEN":"Unmount disk [device] from [mountPoint]"}
|
||||
func (b *BaseApi) UnmountDisk(c *gin.Context) {
|
||||
var req request.DiskUnmountRequest
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err := diskService.UnmountDisk(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.Success(c)
|
||||
}
|
||||
@@ -38,6 +38,7 @@ var (
|
||||
sshService = service.NewISSHService()
|
||||
firewallService = service.NewIFirewallService()
|
||||
monitorService = service.NewIMonitorService()
|
||||
systemService = service.NewISystemService()
|
||||
|
||||
deviceService = service.NewIDeviceService()
|
||||
fail2banService = service.NewIFail2BanService()
|
||||
@@ -70,4 +71,7 @@ var (
|
||||
websiteCAService = service.NewIWebsiteCAService()
|
||||
taskService = service.NewITaskService()
|
||||
groupService = service.NewIGroupService()
|
||||
alertService = service.NewIAlertService()
|
||||
|
||||
diskService = service.NewIDiskService()
|
||||
)
|
||||
|
||||
@@ -296,7 +296,7 @@ func (b *BaseApi) SaveContent(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /files/upload [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传文件 [path]","formatEN":"Upload file [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path", "file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传文件 [path]/[file]","formatEN":"Upload file [path]/[file]"}
|
||||
func (b *BaseApi) UploadFiles(c *gin.Context) {
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
@@ -880,7 +880,7 @@ func (b *BaseApi) GetPathByType(c *gin.Context) {
|
||||
// @Success 200 {object} dto.DiskInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mount [post]
|
||||
// @Router /files/mount [post]
|
||||
func (b *BaseApi) GetHostMount(c *gin.Context) {
|
||||
disks := fileService.GetHostMount()
|
||||
helper.SuccessWithData(c, disks)
|
||||
@@ -892,7 +892,7 @@ func (b *BaseApi) GetHostMount(c *gin.Context) {
|
||||
// @Success 200 {object} response.UserGroupResponse
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /user/group [post]
|
||||
// @Router /files/user/group [post]
|
||||
func (b *BaseApi) GetUsersAndGroups(c *gin.Context) {
|
||||
res, err := fileService.GetUsersAndGroups()
|
||||
if err != nil {
|
||||
|
||||
@@ -63,7 +63,7 @@ func (b *BaseApi) OperateFirewall(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := firewallService.OperateFirewall(req.Operation); err != nil {
|
||||
if err := firewallService.OperateFirewall(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /agent/groups [post]
|
||||
// @Router /groups [post]
|
||||
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建组 [name][type]","formatEN":"create group [name][type]"}
|
||||
func (b *BaseApi) CreateGroup(c *gin.Context) {
|
||||
var req dto.GroupCreate
|
||||
@@ -35,7 +35,7 @@ func (b *BaseApi) CreateGroup(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /agent/groups/del [post]
|
||||
// @Router /groups/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"groups","output_column":"name","output_value":"name"},{"input_column":"id","input_value":"id","isList":false,"db":"groups","output_column":"type","output_value":"type"}],"formatZH":"删除组 [type][name]","formatEN":"delete group [type][name]"}
|
||||
func (b *BaseApi) DeleteGroup(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
@@ -57,7 +57,7 @@ func (b *BaseApi) DeleteGroup(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /agent/groups/update [post]
|
||||
// @Router /groups/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新组 [name][type]","formatEN":"update group [name][type]"}
|
||||
func (b *BaseApi) UpdateGroup(c *gin.Context) {
|
||||
var req dto.GroupUpdate
|
||||
@@ -79,7 +79,7 @@ func (b *BaseApi) UpdateGroup(c *gin.Context) {
|
||||
// @Success 200 {array} dto.OperateByType
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /agent/groups/search [post]
|
||||
// @Router /groups/search [post]
|
||||
func (b *BaseApi) ListGroup(c *gin.Context) {
|
||||
var req dto.OperateByType
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
|
||||
@@ -116,7 +116,11 @@ func CheckBind(req interface{}, c *gin.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ErrResponse(ctx *gin.Context, code int) {
|
||||
ctx.JSON(code, nil)
|
||||
ctx.Abort()
|
||||
func GetParamInt32(paramName string, c *gin.Context) (int32, error) {
|
||||
idParam, ok := c.Params.Get(paramName)
|
||||
if !ok {
|
||||
return 0, errors.New("error id in path")
|
||||
}
|
||||
intNum, _ := strconv.Atoi(idParam)
|
||||
return int32(intNum), nil
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
// @Success 200 {object} response.HostToolRes
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/tool [post]
|
||||
// @Router /hosts/tool [post]
|
||||
func (b *BaseApi) GetToolStatus(c *gin.Context) {
|
||||
var req request.HostToolReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -35,7 +35,7 @@ func (b *BaseApi) GetToolStatus(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/tool/create [post]
|
||||
// @Router /hosts/tool/init [post]
|
||||
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 [type] 配置","formatEN":"create [type] config"}
|
||||
func (b *BaseApi) InitToolConfig(c *gin.Context) {
|
||||
var req request.HostToolCreate
|
||||
@@ -57,7 +57,7 @@ func (b *BaseApi) InitToolConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/tool/operate [post]
|
||||
// @Router /hosts/tool/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["operate","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] [type] ","formatEN":"[operate] [type]"}
|
||||
func (b *BaseApi) OperateTool(c *gin.Context) {
|
||||
var req request.HostToolReq
|
||||
@@ -79,7 +79,7 @@ func (b *BaseApi) OperateTool(c *gin.Context) {
|
||||
// @Success 200 {object} response.HostToolConfig
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/tool/config [post]
|
||||
// @Router /hosts/tool/config [post]
|
||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 主机工具配置文件 ","formatEN":"[operate] tool config"}
|
||||
func (b *BaseApi) OperateToolConfig(c *gin.Context) {
|
||||
var req request.HostToolConfig
|
||||
@@ -102,7 +102,7 @@ func (b *BaseApi) OperateToolConfig(c *gin.Context) {
|
||||
// @Success 200 {string} logContent
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/tool/log [post]
|
||||
// @Router /hosts/tool/log [post]
|
||||
func (b *BaseApi) GetToolLog(c *gin.Context) {
|
||||
var req request.HostToolLogReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -124,7 +124,7 @@ func (b *BaseApi) GetToolLog(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/tool/supervisor/process [post]
|
||||
// @Router /hosts/tool/supervisor/process [post]
|
||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 守护进程 ","formatEN":"[operate] process"}
|
||||
func (b *BaseApi) OperateProcess(c *gin.Context) {
|
||||
var req request.SupervisorProcessConfig
|
||||
@@ -146,7 +146,7 @@ func (b *BaseApi) OperateProcess(c *gin.Context) {
|
||||
// @Success 200 {object} response.SupervisorProcessConfig
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/tool/supervisor/process [get]
|
||||
// @Router /hosts/tool/supervisor/process [get]
|
||||
func (b *BaseApi) GetProcess(c *gin.Context) {
|
||||
configs, err := hostToolService.GetSupervisorProcessConfig()
|
||||
if err != nil {
|
||||
@@ -163,7 +163,7 @@ func (b *BaseApi) GetProcess(c *gin.Context) {
|
||||
// @Success 200 {string} content
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/tool/supervisor/process/file [post]
|
||||
// @Router /hosts/tool/supervisor/process/file [post]
|
||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] Supervisor 进程文件 ","formatEN":"[operate] Supervisor Process Config file"}
|
||||
func (b *BaseApi) GetProcessFile(c *gin.Context) {
|
||||
var req request.SupervisorProcessFileReq
|
||||
|
||||
@@ -9,14 +9,14 @@ import (
|
||||
// @Tags Container Image
|
||||
// @Summary Page images
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchWithPage true "request"
|
||||
// @Param request body dto.PageImage true "request"
|
||||
// @Produce json
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/image/search [post]
|
||||
func (b *BaseApi) SearchImage(c *gin.Context) {
|
||||
var req dto.SearchWithPage
|
||||
var req dto.PageImage
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -138,7 +138,7 @@ func (b *BaseApi) ImagePush(c *gin.Context) {
|
||||
// @Summary Delete image
|
||||
// @Accept json
|
||||
// @Param request body dto.BatchDelete true "request"
|
||||
// @Success 200 {object} dto.ContainerPruneReport
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/image/remove [post]
|
||||
@@ -149,13 +149,12 @@ func (b *BaseApi) ImageRemove(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
data, err := imageService.ImageRemove(req)
|
||||
if err != nil {
|
||||
if err := imageService.ImageRemove(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, data)
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Container Image
|
||||
|
||||
@@ -58,7 +58,7 @@ func (b *BaseApi) ListRepo(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/repo/status [get]
|
||||
// @Router /containers/repo/status [post]
|
||||
func (b *BaseApi) CheckRepoStatus(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -98,20 +98,20 @@ func (b *BaseApi) CreateRepo(c *gin.Context) {
|
||||
// @Tags Container Image-repo
|
||||
// @Summary Delete image repo
|
||||
// @Accept json
|
||||
// @Param request body dto.ImageRepoDelete true "request"
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/repo/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"image_repos","output_column":"name","output_value":"names"}],"formatZH":"删除镜像仓库 [names]","formatEN":"delete image repo [names]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_column":"name","output_value":"name"}],"formatZH":"删除镜像仓库 [name]","formatEN":"delete image repo [name]"}
|
||||
func (b *BaseApi) DeleteRepo(c *gin.Context) {
|
||||
var req dto.ImageRepoDelete
|
||||
var req dto.OperateByID
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := imageRepoService.BatchDelete(req); err != nil {
|
||||
if err := imageRepoService.Delete(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
// @Success 200 {object} response.McpServersRes
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mcp/search [post]
|
||||
// @Router /ai/mcp/search [post]
|
||||
func (b *BaseApi) PageMcpServers(c *gin.Context) {
|
||||
var req request.McpServerSearch
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -30,7 +30,7 @@ func (b *BaseApi) PageMcpServers(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mcp/server [post]
|
||||
// @Router /ai/mcp/server [post]
|
||||
func (b *BaseApi) CreateMcpServer(c *gin.Context) {
|
||||
var req request.McpServerCreate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -51,7 +51,7 @@ func (b *BaseApi) CreateMcpServer(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mcp/server/update [post]
|
||||
// @Router /ai/mcp/server/update [post]
|
||||
func (b *BaseApi) UpdateMcpServer(c *gin.Context) {
|
||||
var req request.McpServerUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -72,7 +72,7 @@ func (b *BaseApi) UpdateMcpServer(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mcp/server/del [post]
|
||||
// @Router /ai/mcp/server/del [post]
|
||||
func (b *BaseApi) DeleteMcpServer(c *gin.Context) {
|
||||
var req request.McpServerDelete
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -93,7 +93,7 @@ func (b *BaseApi) DeleteMcpServer(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mcp/server/op [post]
|
||||
// @Router /ai/mcp/server/op [post]
|
||||
func (b *BaseApi) OperateMcpServer(c *gin.Context) {
|
||||
var req request.McpServerOperate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -114,7 +114,7 @@ func (b *BaseApi) OperateMcpServer(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mcp/domain/bind [post]
|
||||
// @Router /ai/mcp/domain/bind [post]
|
||||
func (b *BaseApi) BindMcpDomain(c *gin.Context) {
|
||||
var req request.McpBindDomain
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -135,7 +135,7 @@ func (b *BaseApi) BindMcpDomain(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mcp/domain/update [post]
|
||||
// @Router /ai/mcp/domain/update [post]
|
||||
func (b *BaseApi) UpdateMcpBindDomain(c *gin.Context) {
|
||||
var req request.McpBindDomainUpdate
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -155,7 +155,7 @@ func (b *BaseApi) UpdateMcpBindDomain(c *gin.Context) {
|
||||
// @Success 200 {object} response.McpBindDomainRes
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /mcp/domain/get [get]
|
||||
// @Router /ai/mcp/domain/get [get]
|
||||
func (b *BaseApi) GetMcpBindDomain(c *gin.Context) {
|
||||
res, err := mcpServerService.GetBindDomain()
|
||||
if err != nil {
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/shirou/gopsutil/v3/net"
|
||||
"github.com/shirou/gopsutil/v4/disk"
|
||||
"github.com/shirou/gopsutil/v4/net"
|
||||
)
|
||||
|
||||
// @Tags Monitor
|
||||
|
||||
@@ -129,7 +129,7 @@ func (b *BaseApi) BuildNginx(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /openresty/module/update [post]
|
||||
// @Router /openresty/modules/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 OpenResty 模块","formatEN":"Update OpenResty module"}
|
||||
func (b *BaseApi) UpdateNginxModule(c *gin.Context) {
|
||||
var req request.NginxModuleUpdate
|
||||
@@ -157,3 +157,39 @@ func (b *BaseApi) GetNginxModules(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, modules)
|
||||
}
|
||||
|
||||
// @Tags OpenResty
|
||||
// @Summary Operate default HTTPs
|
||||
// @Accept json
|
||||
// @Param request body request.NginxOperateReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /openresty/https [post]
|
||||
func (b *BaseApi) OperateDefaultHTTPs(c *gin.Context) {
|
||||
var req request.NginxOperateReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := nginxService.OperateDefaultHTTPs(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags OpenResty
|
||||
// @Summary Get default HTTPs status
|
||||
// @Success 200 {object} response.NginxConfigRes
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /openresty/https [get]
|
||||
func (b *BaseApi) GetDefaultHTTPsStatus(c *gin.Context) {
|
||||
res, err := nginxService.GetDefaultHttpsStatus()
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
@@ -36,3 +36,24 @@ func (b *BaseApi) StopProcess(c *gin.Context) {
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Process
|
||||
// @Summary Get Process Info By PID
|
||||
// @Param pid path int true "PID"
|
||||
// @Success 200 {object} websocket.PsProcessData
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /process/{pid} [get]
|
||||
func (b *BaseApi) GetProcessInfoByPID(c *gin.Context) {
|
||||
pid, err := helper.GetParamInt32("pid", c)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
data, err := processService.GetProcessInfoByPID(pid)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func (b *BaseApi) DeleteRuntime(c *gin.Context) {
|
||||
// @Success 200 {array} dto.AppResource
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /installed/delete/check/:id [get]
|
||||
// @Router /runtimes/installed/delete/check/:id [get]
|
||||
func (b *BaseApi) DeleteRuntimeCheck(c *gin.Context) {
|
||||
runTimeId, err := helper.GetIntParamByKey(c, "id")
|
||||
if err != nil {
|
||||
@@ -459,7 +459,7 @@ func (b *BaseApi) GetSupervisorProcess(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /runtimes/supervisor/process/operate [post]
|
||||
// @Router /runtimes/supervisor/process [post]
|
||||
func (b *BaseApi) OperateSupervisorProcess(c *gin.Context) {
|
||||
var req request.PHPSupervisorProcessConfig
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -480,7 +480,7 @@ func (b *BaseApi) OperateSupervisorProcess(c *gin.Context) {
|
||||
// @Success 200 {string} content
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /runtimes/supervisor/process/file/operate [post]
|
||||
// @Router /runtimes/supervisor/process/file [post]
|
||||
func (b *BaseApi) OperateSupervisorProcessFile(c *gin.Context) {
|
||||
var req request.PHPSupervisorProcessFileReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -497,7 +497,7 @@ func (b *BaseApi) OperateSupervisorProcessFile(c *gin.Context) {
|
||||
// @Tags Runtime
|
||||
// @Summary Update PHP container config
|
||||
// @Accept json
|
||||
// @Param request body request.PHPContainerUpdate true "request"
|
||||
// @Param request body request.PHPContainerConfig true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
@@ -518,7 +518,7 @@ func (b *BaseApi) UpdatePHPContainer(c *gin.Context) {
|
||||
// @Summary Get PHP container config
|
||||
// @Accept json
|
||||
// @Param id path integer true "request"
|
||||
// @Success 200 {object} response.PHPContainerConfig
|
||||
// @Success 200 {object} request.PHPContainerConfig
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /runtimes/php/container/:id [get]
|
||||
@@ -535,3 +535,45 @@ func (b *BaseApi) GetPHPContainerConfig(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Update runtime remark
|
||||
// @Accept json
|
||||
// @Param request body request.RuntimeRemark true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /runtimes/remark [post]
|
||||
func (b *BaseApi) UpdateRuntimeRemark(c *gin.Context) {
|
||||
var req request.RuntimeRemark
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := runtimeService.UpdateRemark(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Get PHP runtime status
|
||||
// @Accept json
|
||||
// @Param id path integer true "request"
|
||||
// @Success 200 {object} map[string]interface{}
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /runtimes/php/fpm/status/:id [get]
|
||||
func (b *BaseApi) GetFPMStatus(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
data, err := runtimeService.GetFPMStatus(id)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
+51
-35
@@ -1,13 +1,12 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/ssh"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -71,6 +70,35 @@ func (b *BaseApi) LoadBaseDir(c *gin.Context) {
|
||||
helper.SuccessWithData(c, global.Dir.DataDir)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Load local conn
|
||||
// @Success 200 {object} dto.SSHConnData
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /settings/ssh/conn [get]
|
||||
func (b *BaseApi) LoadLocalConn(c *gin.Context) {
|
||||
connInfoInDB := settingService.GetSettingByKey("LocalSSHConn")
|
||||
if len(connInfoInDB) == 0 {
|
||||
helper.Success(c)
|
||||
return
|
||||
}
|
||||
var data dto.SSHConnData
|
||||
if err := json.Unmarshal([]byte(connInfoInDB), &data); err != nil {
|
||||
helper.Success(c)
|
||||
return
|
||||
}
|
||||
if len(data.Password) != 0 {
|
||||
data.Password = base64.StdEncoding.EncodeToString([]byte(data.Password))
|
||||
}
|
||||
if len(data.PrivateKey) != 0 {
|
||||
data.PrivateKey = base64.StdEncoding.EncodeToString([]byte(data.PrivateKey))
|
||||
}
|
||||
if len(data.PassPhrase) != 0 {
|
||||
data.PassPhrase = base64.StdEncoding.EncodeToString([]byte(data.PassPhrase))
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
func (b *BaseApi) CheckLocalConn(c *gin.Context) {
|
||||
_, err := loadLocalConn()
|
||||
helper.SuccessWithData(c, err == nil)
|
||||
@@ -87,6 +115,7 @@ func (b *BaseApi) CheckLocalConnByInfo(c *gin.Context) {
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, settingService.TestConnByInfo(req))
|
||||
}
|
||||
|
||||
@@ -96,51 +125,38 @@ func (b *BaseApi) CheckLocalConnByInfo(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /settings/ssh [post]
|
||||
func (b *BaseApi) SaveLocalConnInfo(c *gin.Context) {
|
||||
func (b *BaseApi) SaveLocalConn(c *gin.Context) {
|
||||
var req dto.SSHConnData
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, settingService.SaveConnInfo(req))
|
||||
|
||||
if err := settingService.SaveConnInfo(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
func loadLocalConn() (*ssh.SSHClient, error) {
|
||||
itemPath := ""
|
||||
currentInfo, _ := user.Current()
|
||||
if len(currentInfo.HomeDir) == 0 {
|
||||
itemPath = "/root/.ssh/id_ed25519_1panel"
|
||||
} else {
|
||||
itemPath = path.Join(currentInfo.HomeDir, ".ssh/id_ed25519_1panel")
|
||||
}
|
||||
if _, err := os.Stat(itemPath); err != nil {
|
||||
_ = sshService.GenerateSSH(dto.GenerateSSH{EncryptionMode: "ed25519", Name: "_1panel"})
|
||||
}
|
||||
|
||||
privateKey, _ := os.ReadFile(itemPath)
|
||||
connWithKey := ssh.ConnInfo{
|
||||
Addr: "127.0.0.1",
|
||||
User: "root",
|
||||
Port: 22,
|
||||
AuthMode: "key",
|
||||
PrivateKey: privateKey,
|
||||
}
|
||||
client, err := ssh.NewClient(connWithKey)
|
||||
if err == nil {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
connInfoInDB, err := settingService.GetSSHInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
connInfoInDB := settingService.GetSettingByKey("LocalSSHConn")
|
||||
if len(connInfoInDB) == 0 {
|
||||
return nil, errors.New("no such ssh conn info in db!")
|
||||
}
|
||||
var connInDB ssh.ConnInfo
|
||||
var connInDB model.LocalConnInfo
|
||||
if err := json.Unmarshal([]byte(connInfoInDB), &connInDB); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ssh.NewClient(connInDB)
|
||||
sshInfo := ssh.ConnInfo{
|
||||
Addr: connInDB.Addr,
|
||||
Port: int(connInDB.Port),
|
||||
User: connInDB.User,
|
||||
AuthMode: connInDB.AuthMode,
|
||||
Password: connInDB.Password,
|
||||
PrivateKey: []byte(connInDB.PrivateKey),
|
||||
PassPhrase: []byte(connInDB.PassPhrase),
|
||||
}
|
||||
return ssh.NewClient(sshInfo)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
|
||||
@@ -36,7 +36,7 @@ func (b *BaseApi) CreateSnapshot(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := snapshotService.SnapshotCreate(nil, req, 0, 0, 0); err != nil {
|
||||
if err := snapshotService.SnapshotCreate(nil, req, 0, 3); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func (b *BaseApi) CreateSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /settings/snapshot/recrete [post]
|
||||
// @Router /settings/snapshot/recreate [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"重试创建快照 [name]","formatEN":"recrete the snapshot [name]"}
|
||||
func (b *BaseApi) RecreateSnapshot(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
|
||||
+112
-21
@@ -1,6 +1,8 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -11,7 +13,7 @@ import (
|
||||
// @Success 200 {object} dto.SSHInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/ssh/search [post]
|
||||
// @Router /hosts/ssh/search [post]
|
||||
func (b *BaseApi) GetSSHInfo(c *gin.Context) {
|
||||
info, err := sshService.GetSSHInfo()
|
||||
if err != nil {
|
||||
@@ -28,7 +30,7 @@ func (b *BaseApi) GetSSHInfo(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/ssh/operate [post]
|
||||
// @Router /hosts/ssh/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] SSH ","formatEN":"[operation] SSH"}
|
||||
func (b *BaseApi) OperateSSH(c *gin.Context) {
|
||||
var req dto.Operate
|
||||
@@ -50,7 +52,7 @@ func (b *BaseApi) OperateSSH(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/ssh/update [post]
|
||||
// @Router /hosts/ssh/update [post]
|
||||
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置 [key] => [value]","formatEN":"update SSH setting [key] => [value]"}
|
||||
func (b *BaseApi) UpdateSSH(c *gin.Context) {
|
||||
var req dto.SSHUpdate
|
||||
@@ -72,7 +74,7 @@ func (b *BaseApi) UpdateSSH(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/conffile/update [post]
|
||||
// @Router /hosts/ssh/conffile/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置文件","formatEN":"update SSH conf"}
|
||||
func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
|
||||
var req dto.SSHConf
|
||||
@@ -90,19 +92,58 @@ func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
|
||||
// @Tags SSH
|
||||
// @Summary Generate host SSH secret
|
||||
// @Accept json
|
||||
// @Param request body dto.GenerateSSH true "request"
|
||||
// @Param request body dto.CreateRootCert true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/ssh/generate [post]
|
||||
// @Router /hosts/ssh/cert [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"生成 SSH 密钥 ","formatEN":"generate SSH secret"}
|
||||
func (b *BaseApi) GenerateSSH(c *gin.Context) {
|
||||
var req dto.GenerateSSH
|
||||
func (b *BaseApi) CreateRootCert(c *gin.Context) {
|
||||
var req dto.CreateRootCert
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if len(req.PassPhrase) != 0 {
|
||||
passPhrase, err := base64.StdEncoding.DecodeString(req.PassPhrase)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
req.PassPhrase = string(passPhrase)
|
||||
}
|
||||
if len(req.PrivateKey) != 0 {
|
||||
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
req.PrivateKey = string(privateKey)
|
||||
}
|
||||
if len(req.PublicKey) != 0 {
|
||||
publicKey, err := base64.StdEncoding.DecodeString(req.PublicKey)
|
||||
if err != nil {
|
||||
helper.BadRequest(c, err)
|
||||
return
|
||||
}
|
||||
req.PublicKey = string(publicKey)
|
||||
}
|
||||
|
||||
if err := sshService.GenerateSSH(req); err != nil {
|
||||
if err := sshService.CreateRootCert(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Sycn host SSH secret
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /hosts/ssh/cert/sync [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"同步 SSH 密钥 ","formatEN":"sync SSH secret"}
|
||||
func (b *BaseApi) SyncRootCert(c *gin.Context) {
|
||||
if err := sshService.SyncRootCert(); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
@@ -112,45 +153,95 @@ func (b *BaseApi) GenerateSSH(c *gin.Context) {
|
||||
// @Tags SSH
|
||||
// @Summary Load host SSH secret
|
||||
// @Accept json
|
||||
// @Param request body dto.GenerateLoad true "request"
|
||||
// @Success 200 {string} secret
|
||||
// @Param request body dto.SearchWithPage true "request"
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/ssh/secret [post]
|
||||
func (b *BaseApi) LoadSSHSecret(c *gin.Context) {
|
||||
var req dto.GenerateLoad
|
||||
// @Router /hosts/ssh/cert/search [post]
|
||||
func (b *BaseApi) SearchRootCert(c *gin.Context) {
|
||||
var req dto.SearchWithPage
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data, err := sshService.LoadSSHSecret(req.EncryptionMode)
|
||||
total, data, err := sshService.SearchRootCerts(req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Total: total,
|
||||
Items: data,
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Delete host SSH secret
|
||||
// @Accept json
|
||||
// @Param request body dto.ForceDelete true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /hosts/ssh/cert/delete [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除 SSH 密钥 ","formatEN":"delete SSH secret"}
|
||||
func (b *BaseApi) DeleteRootCert(c *gin.Context) {
|
||||
var req dto.ForceDelete
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := sshService.DeleteRootCerts(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host SSH logs
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchSSHLog true "request"
|
||||
// @Success 200 {object} dto.SSHLog
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/ssh/log [post]
|
||||
// @Router /hosts/ssh/log [post]
|
||||
func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
|
||||
var req dto.SearchSSHLog
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data, err := sshService.LoadLog(c, req)
|
||||
total, data, err := sshService.LoadLog(c, req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Total: total,
|
||||
Items: data,
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Export host SSH logs
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchSSHLog true "request"
|
||||
// @Success 200 {string} path
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /hosts/ssh/log/export [post]
|
||||
func (b *BaseApi) ExportSSHLogs(c *gin.Context) {
|
||||
var req dto.SearchSSHLog
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
tmpFile, err := sshService.ExportLog(c, req)
|
||||
if err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, tmpFile)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
@@ -158,7 +249,7 @@ func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
|
||||
// @Success 200 {string} conf
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /host/ssh/conf [get]
|
||||
// @Router /hosts/ssh/conf [get]
|
||||
func (b *BaseApi) LoadSSHConf(c *gin.Context) {
|
||||
data, err := sshService.LoadSSHConf()
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags Host
|
||||
// @Summary Check if a system component exists
|
||||
// @Accept json
|
||||
// @Param name query string true "Component name to check (e.g., rsync, docker)"
|
||||
// @Success 200 {object} response.ComponentInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /hosts/components/{name} [get]
|
||||
func (b *BaseApi) CheckComponentExistence(c *gin.Context) {
|
||||
name := c.Param("name")
|
||||
if name == "" {
|
||||
helper.BadRequest(c, errors.New("empty component name"))
|
||||
return
|
||||
}
|
||||
|
||||
info := systemService.IsComponentExist(name)
|
||||
helper.SuccessWithData(c, info)
|
||||
}
|
||||
@@ -89,8 +89,8 @@ func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
|
||||
var containerID string
|
||||
var initCmd []string
|
||||
switch source {
|
||||
case "redis":
|
||||
containerID, initCmd, err = loadRedisInitCmd(c)
|
||||
case "redis", "redis-cluster":
|
||||
containerID, initCmd, err = loadRedisInitCmd(c, source)
|
||||
case "ollama":
|
||||
containerID, initCmd, err = loadOllamaInitCmd(c)
|
||||
case "container":
|
||||
@@ -127,7 +127,7 @@ func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
|
||||
_ = wsConn.WriteControl(websocket.CloseMessage, nil, dt)
|
||||
}
|
||||
|
||||
func loadRedisInitCmd(c *gin.Context) (string, []string, error) {
|
||||
func loadRedisInitCmd(c *gin.Context, redisType string) (string, []string, error) {
|
||||
name := c.Query("name")
|
||||
from := c.Query("from")
|
||||
commands := []string{"exec", "-it"}
|
||||
@@ -136,7 +136,7 @@ func loadRedisInitCmd(c *gin.Context) (string, []string, error) {
|
||||
return "", nil, fmt.Errorf("no such database in db, err: %v", err)
|
||||
}
|
||||
if from == "local" {
|
||||
redisInfo, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Name: name, Type: "redis"})
|
||||
redisInfo, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Name: name, Type: redisType})
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("no such app in db, err: %v", err)
|
||||
}
|
||||
|
||||
@@ -527,7 +527,7 @@ func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /websites/proxy/file [post]
|
||||
// @Router /websites/proxies/file [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新反向代理文件 [domain]","formatEN":"Nginx conf proxy file update [domain]"}
|
||||
func (b *BaseApi) UpdateProxyConfigFile(c *gin.Context) {
|
||||
var req request.NginxProxyUpdate
|
||||
@@ -840,7 +840,7 @@ func (b *BaseApi) CreateLoadBalance(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /websites/lbs/delete [post]
|
||||
// @Router /websites/lbs/del [post]
|
||||
func (b *BaseApi) DeleteLoadBalance(c *gin.Context) {
|
||||
var req request.WebsiteLBDelete
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
@@ -953,7 +953,7 @@ func (b *BaseApi) GetProxyCache(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /websites/realip [post]
|
||||
// @Router /websites/realip/config [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改 [domain] 网站真实IP配置 ","formatEN":"Modify the real IP configuration of [domain] website"}
|
||||
func (b *BaseApi) SetRealIPConfig(c *gin.Context) {
|
||||
var req request.WebsiteRealIP
|
||||
@@ -1121,3 +1121,23 @@ func (b *BaseApi) OperateCrossSiteAccess(c *gin.Context) {
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Exec Composer
|
||||
// @Accept json
|
||||
// @Param request body request.ExecComposerReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /websites/exec/composer [post]
|
||||
func (b *BaseApi) ExecComposer(c *gin.Context) {
|
||||
var req request.ExecComposerReq
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := websiteService.ExecComposer(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
@@ -245,3 +246,15 @@ func (b *BaseApi) DownloadWebsiteSSL(c *gin.Context) {
|
||||
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(info.Name()))
|
||||
http.ServeContent(c.Writer, c.Request, info.Name(), info.ModTime(), file)
|
||||
}
|
||||
|
||||
func (b *BaseApi) ImportMasterSSL(c *gin.Context) {
|
||||
var req model.WebsiteSSL
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := websiteSSLService.ImportMasterSSL(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
+314
-4
@@ -1,10 +1,17 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CreateOrUpdateAlert struct {
|
||||
AlertTitle string `json:"alertTitle"`
|
||||
AlertType string `json:"alertType"`
|
||||
AlertCount uint `json:"alertCount"`
|
||||
EntryID uint `json:"entryID"`
|
||||
AlertTitle string `json:"alertTitle"`
|
||||
AlertType string `json:"alertType"`
|
||||
AlertMethod string `json:"alertMethod"`
|
||||
AlertCount uint `json:"alertCount"`
|
||||
EntryID uint `json:"entryID"`
|
||||
}
|
||||
|
||||
type AlertBase struct {
|
||||
@@ -18,3 +25,306 @@ type PushAlert struct {
|
||||
EntryID uint `json:"entryID"`
|
||||
Param string `json:"param"`
|
||||
}
|
||||
|
||||
type AlertSearch struct {
|
||||
PageInfo
|
||||
OrderBy string `json:"orderBy" validate:"required,oneof=created_at"`
|
||||
Order string `json:"order" validate:"required,oneof=null ascending descending"`
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Method string `json:"method"`
|
||||
}
|
||||
|
||||
type AlertDTO struct {
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Cycle uint `json:"cycle"`
|
||||
Count uint `json:"count"`
|
||||
Method string `json:"method"`
|
||||
Title string `json:"title"`
|
||||
Project string `json:"project"`
|
||||
Status string `json:"status"`
|
||||
SendCount uint `json:"sendCount"`
|
||||
AdvancedParams string `json:"advancedParams"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type AlertCreate struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
Cycle uint `json:"cycle"`
|
||||
Count uint `json:"count"`
|
||||
Method string `json:"method" validate:"required"`
|
||||
Title string `json:"title"`
|
||||
Project string `json:"project"`
|
||||
Status string `json:"status"`
|
||||
SendCount uint `json:"sendCount"`
|
||||
AdvancedParams string `json:"advancedParams"`
|
||||
}
|
||||
|
||||
type AlertUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type"`
|
||||
Cycle uint `json:"cycle"`
|
||||
Count uint `json:"count"`
|
||||
Method string `json:"method"`
|
||||
Title string `json:"title"`
|
||||
Project string `json:"project"`
|
||||
Status string `json:"status"`
|
||||
SendCount uint `json:"sendCount"`
|
||||
AdvancedParams string `json:"advancedParams"`
|
||||
}
|
||||
|
||||
type DeleteRequest struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type AlertUpdateStatus struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Status string `json:"status" validate:"required"`
|
||||
}
|
||||
|
||||
type DiskDTO struct {
|
||||
Path string `json:"path"`
|
||||
Type string `json:"type"`
|
||||
Device string `json:"device"`
|
||||
Total uint64 `json:"total"`
|
||||
Free uint64 `json:"free"`
|
||||
Used uint64 `json:"used"`
|
||||
UsedPercent float64 `json:"usedPercent"`
|
||||
|
||||
InodesTotal uint64 `json:"inodesTotal"`
|
||||
InodesUsed uint64 `json:"inodesUsed"`
|
||||
InodesFree uint64 `json:"inodesFree"`
|
||||
InodesUsedPercent float64 `json:"inodesUsedPercent"`
|
||||
}
|
||||
|
||||
type AlertLogSearch struct {
|
||||
PageInfo
|
||||
Count uint `json:"count"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type AlertLogDTO struct {
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Count uint `json:"count"`
|
||||
AlertId uint `json:"alertId"`
|
||||
AlertDetail AlertDetail `json:"alertDetail"`
|
||||
AlertRule AlertRule `json:"alertRule"`
|
||||
Status string `json:"status"`
|
||||
Method string `json:"method"`
|
||||
Message string `json:"message"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type AlertLogCreate struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
Count uint `json:"count" validate:"required"`
|
||||
AlertId uint `json:"alertId" validate:"required"`
|
||||
AlertDetail string `json:"alertDetail" validate:"required"`
|
||||
AlertRule string `json:"alertRule" validate:"required"`
|
||||
Status string `json:"status" validate:"required"`
|
||||
Method string `json:"method" validate:"required"`
|
||||
Message string `json:"message"`
|
||||
RecordId uint `json:"recordId"`
|
||||
LicenseId string `json:"licenseId" validate:"required"`
|
||||
}
|
||||
|
||||
type AlertLog struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type AlertDetail struct {
|
||||
LicenseId string `json:"licenseId"`
|
||||
Type string `json:"type"`
|
||||
SubType string `json:"subType"`
|
||||
Title string `json:"title"`
|
||||
Method string `json:"method"`
|
||||
LicenseCode string `json:"licenseCode"`
|
||||
DeviceId string `json:"deviceId"`
|
||||
Project string `json:"project"`
|
||||
Params []Param `json:"params"`
|
||||
Phone string `json:"phone"`
|
||||
}
|
||||
|
||||
type AlertRule struct {
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Cycle uint `json:"cycle"`
|
||||
Count uint `json:"count"`
|
||||
Method string `json:"method"`
|
||||
Title string `json:"title"`
|
||||
Project string `json:"project"`
|
||||
Status string `json:"status"`
|
||||
SendCount uint `json:"sendCount"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type Param struct {
|
||||
Index string `json:"index"`
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type ClamDTO struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type CronJobDTO struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type CronJobReq struct {
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type UpgradeInfo struct {
|
||||
TestVersion string `json:"testVersion"`
|
||||
NewVersion string `json:"newVersion"`
|
||||
LatestVersion string `json:"latestVersion"`
|
||||
ReleaseNote string `json:"releaseNote"`
|
||||
}
|
||||
|
||||
type AlertDiskInfo struct {
|
||||
Type string
|
||||
Mount string
|
||||
Device string
|
||||
}
|
||||
|
||||
type SyncResult struct {
|
||||
ID uint `json:"id"`
|
||||
LicenseID string `json:"licenseId"`
|
||||
SendStatus string `json:"sendStatus"`
|
||||
CreateTime string `json:"createTime"`
|
||||
UpdateTime string `json:"updateTime"`
|
||||
Remarks string `json:"remarks"`
|
||||
MsgCount int `json:"msgCount"`
|
||||
MsgCountMax int `json:"msgCountMax"`
|
||||
}
|
||||
|
||||
type QueryRequest struct {
|
||||
QueryIds []uint `json:"queryIds"`
|
||||
LicenseId string `json:"licenseId"`
|
||||
}
|
||||
|
||||
type AlertResponse struct {
|
||||
Result bool `json:"result"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type PushResult struct {
|
||||
RecordId uint `json:"recordId"`
|
||||
LicenseId string `json:"licenseId"`
|
||||
}
|
||||
|
||||
type UpdateOfflineAlertLog struct {
|
||||
ID uint `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
RecordId uint `json:"recordId"`
|
||||
LicenseId string `json:"licenseId"`
|
||||
}
|
||||
|
||||
type SyncOfflineAlertLogDTO struct {
|
||||
QueryRequest string `json:"queryRequest"`
|
||||
Ids []uint `json:"ids"`
|
||||
AlertLogs []model.AlertLog `json:"alertLogs"`
|
||||
LicenseId string `json:"licenseId"`
|
||||
}
|
||||
|
||||
type OfflineAlertResponse struct {
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type"`
|
||||
RemoteErr error `json:"remoteErr"`
|
||||
ResponseStruct AlertResponse `json:"responseStruct"`
|
||||
AlertLogs []model.AlertLog `json:"alertLogs"`
|
||||
Ids []uint `json:"ids"`
|
||||
LicenseId string `json:"licenseId"`
|
||||
}
|
||||
|
||||
type OfflineAlertLogDTO struct {
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Count uint `json:"count"`
|
||||
AlertId uint `json:"alertId"`
|
||||
AlertDetail string `json:"alertDetail"`
|
||||
AlertRule string `json:"alertRule"`
|
||||
Status string `json:"status"`
|
||||
Method string `json:"method"`
|
||||
Message string `json:"message"`
|
||||
RecordId uint `json:"recordId"`
|
||||
LicenseId string `json:"licenseId"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type OfflineQueryRequest struct {
|
||||
Ids []uint `json:"ids"`
|
||||
QueryIds []uint `json:"queryIds"`
|
||||
LicenseId string `json:"licenseId"`
|
||||
}
|
||||
|
||||
type AlertConfigUpdate struct {
|
||||
ID uint `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
Status string `json:"status"`
|
||||
Config string `json:"config"`
|
||||
}
|
||||
|
||||
type AlertConfigTest struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Sender string `json:"sender"`
|
||||
Password string `json:"password"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Encryption string `json:"encryption"` // "ssl" / "tls" / "none"
|
||||
Recipient string `json:"recipient"`
|
||||
}
|
||||
|
||||
type AlertSendTimeRange struct {
|
||||
NoticeAlert struct {
|
||||
SendTimeRange string `json:"sendTimeRange"`
|
||||
Type []string `json:"type"`
|
||||
} `json:"noticeAlert"`
|
||||
ResourceAlert struct {
|
||||
SendTimeRange string `json:"sendTimeRange"`
|
||||
Type []string `json:"type"`
|
||||
} `json:"resourceAlert"`
|
||||
}
|
||||
|
||||
type AlertCommonConfig struct {
|
||||
IsOffline string `json:"isOffline"`
|
||||
AlertSendTimeRange AlertSendTimeRange `json:"alertSendTimeRange"`
|
||||
}
|
||||
|
||||
type AlertSmsConfig struct {
|
||||
Phone string `json:"phone"`
|
||||
AlertDailyNum uint `json:"alertDailyNum"`
|
||||
}
|
||||
|
||||
type AlertEmailConfig struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Sender string `json:"sender"`
|
||||
Password string `json:"password"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Encryption string `json:"encryption"` // "ssl" / "tls" / "none"
|
||||
Recipient string `json:"recipient"`
|
||||
}
|
||||
|
||||
@@ -7,10 +7,11 @@ import (
|
||||
)
|
||||
|
||||
type AppDatabase struct {
|
||||
ServiceName string `json:"PANEL_DB_HOST"`
|
||||
DbName string `json:"PANEL_DB_NAME"`
|
||||
DbUser string `json:"PANEL_DB_USER"`
|
||||
Password string `json:"PANEL_DB_USER_PASSWORD"`
|
||||
ServiceName string `json:"PANEL_DB_HOST"`
|
||||
DbName string `json:"PANEL_DB_NAME"`
|
||||
DbUser string `json:"PANEL_DB_USER"`
|
||||
Password string `json:"PANEL_DB_USER_PASSWORD"`
|
||||
DatabaseName string `json:"DATABASE_NAME"`
|
||||
}
|
||||
|
||||
type AuthParam struct {
|
||||
@@ -126,6 +127,7 @@ type Locale struct {
|
||||
ZhHant string `json:"zh-hant" yaml:"zh-hant"`
|
||||
Zh string `json:"zh"`
|
||||
Ko string `json:"ko"`
|
||||
Tr string `json:"tr"`
|
||||
}
|
||||
|
||||
type AppForm struct {
|
||||
|
||||
@@ -53,8 +53,13 @@ type BackupOption struct {
|
||||
IsPublic bool `json:"isPublic"`
|
||||
}
|
||||
|
||||
type UploadForRecover struct {
|
||||
FilePath string `json:"filePath"`
|
||||
TargetDir string `json:"targetDir"`
|
||||
}
|
||||
|
||||
type CommonBackup struct {
|
||||
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql"`
|
||||
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster"`
|
||||
Name string `json:"name"`
|
||||
DetailName string `json:"detailName"`
|
||||
Secret string `json:"secret"`
|
||||
@@ -65,7 +70,7 @@ type CommonBackup struct {
|
||||
}
|
||||
type CommonRecover struct {
|
||||
DownloadAccountID uint `json:"downloadAccountID" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql"`
|
||||
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster"`
|
||||
Name string `json:"name"`
|
||||
DetailName string `json:"detailName"`
|
||||
File string `json:"file"`
|
||||
|
||||
+16
-9
@@ -30,16 +30,19 @@ type ClamInfo struct {
|
||||
Path string `json:"path"`
|
||||
InfectedStrategy string `json:"infectedStrategy"`
|
||||
InfectedDir string `json:"infectedDir"`
|
||||
LastHandleDate string `json:"lastHandleDate"`
|
||||
LastRecordStatus string `json:"lastRecordStatus"`
|
||||
LastRecordTime string `json:"lastRecordTime"`
|
||||
Spec string `json:"spec"`
|
||||
Description string `json:"description"`
|
||||
AlertCount uint `json:"alertCount"`
|
||||
AlertMethod string `json:"alertMethod"`
|
||||
}
|
||||
|
||||
type ClamLogSearch struct {
|
||||
PageInfo
|
||||
|
||||
ClamID uint `json:"clamID"`
|
||||
Status string `json:"status"`
|
||||
StartTime time.Time `json:"startTime"`
|
||||
EndTime time.Time `json:"endTime"`
|
||||
}
|
||||
@@ -55,13 +58,16 @@ type ClamFileReq struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type ClamLog struct {
|
||||
Name string `json:"name"`
|
||||
ScanDate string `json:"scanDate"`
|
||||
ScanTime string `json:"scanTime"`
|
||||
InfectedFiles string `json:"infectedFiles"`
|
||||
TotalError string `json:"totalError"`
|
||||
Status string `json:"status"`
|
||||
type ClamRecord struct {
|
||||
ID uint `json:"id"`
|
||||
TaskID string `json:"taskID"`
|
||||
StartTime time.Time `json:"startTime"`
|
||||
ScanTime string `json:"scanTime"`
|
||||
InfectedFiles string `json:"infectedFiles"`
|
||||
TotalError string `json:"totalError"`
|
||||
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type ClamCreate struct {
|
||||
@@ -74,6 +80,7 @@ type ClamCreate struct {
|
||||
Description string `json:"description"`
|
||||
AlertCount uint `json:"alertCount"`
|
||||
AlertTitle string `json:"alertTitle"`
|
||||
AlertMethod string `json:"alertMethod"`
|
||||
}
|
||||
|
||||
type ClamUpdate struct {
|
||||
@@ -87,6 +94,7 @@ type ClamUpdate struct {
|
||||
Description string `json:"description"`
|
||||
AlertCount uint `json:"alertCount"`
|
||||
AlertTitle string `json:"alertTitle"`
|
||||
AlertMethod string `json:"alertMethod"`
|
||||
}
|
||||
|
||||
type ClamUpdateStatus struct {
|
||||
@@ -95,7 +103,6 @@ type ClamUpdateStatus struct {
|
||||
}
|
||||
|
||||
type ClamDelete struct {
|
||||
RemoveRecord bool `json:"removeRecord"`
|
||||
RemoveInfected bool `json:"removeInfected"`
|
||||
Ids []uint `json:"ids" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ type OperationWithName struct {
|
||||
type OperateByID struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
}
|
||||
type OperateByIDs struct {
|
||||
IDs []uint `json:"ids"`
|
||||
}
|
||||
|
||||
type Operate struct {
|
||||
Operation string `json:"operation" validate:"required"`
|
||||
@@ -76,3 +79,8 @@ type ForceDelete struct {
|
||||
IDs []uint `json:"ids"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
}
|
||||
|
||||
type ChangeGroup struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
GroupID uint `json:"groupID" validate:"required"`
|
||||
}
|
||||
|
||||
+37
-27
@@ -39,6 +39,11 @@ type ContainerInfo struct {
|
||||
Websites []string `json:"websites"`
|
||||
}
|
||||
|
||||
type ContainerOptions struct {
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
type ContainerStatus struct {
|
||||
All uint `json:"all"`
|
||||
Created uint `json:"created"`
|
||||
@@ -102,10 +107,10 @@ type ContainerCreateByCommand struct {
|
||||
}
|
||||
|
||||
type ContainerUpgrade struct {
|
||||
TaskID string `json:"taskID"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Image string `json:"image" validate:"required"`
|
||||
ForcePull bool `json:"forcePull"`
|
||||
TaskID string `json:"taskID"`
|
||||
Names []string `json:"names" validate:"required"`
|
||||
Image string `json:"image" validate:"required"`
|
||||
ForcePull bool `json:"forcePull"`
|
||||
}
|
||||
|
||||
type ContainerListStats struct {
|
||||
@@ -164,18 +169,16 @@ type ContainerCommit struct {
|
||||
Comment string `json:"comment"`
|
||||
Author string `json:"author"`
|
||||
Pause bool `json:"pause"`
|
||||
|
||||
TaskID string `json:"taskID"`
|
||||
}
|
||||
|
||||
type ContainerPrune struct {
|
||||
TaskID string `json:"taskID"`
|
||||
PruneType string `json:"pruneType" validate:"required,oneof=container image volume network buildcache"`
|
||||
WithTagAll bool `json:"withTagAll"`
|
||||
}
|
||||
|
||||
type ContainerPruneReport struct {
|
||||
DeletedNumber int `json:"deletedNumber"`
|
||||
SpaceReclaimed int `json:"spaceReclaimed"`
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
@@ -206,11 +209,12 @@ type NetworkCreate struct {
|
||||
}
|
||||
|
||||
type Volume struct {
|
||||
Name string `json:"name"`
|
||||
Labels []string `json:"labels"`
|
||||
Driver string `json:"driver"`
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Name string `json:"name"`
|
||||
Labels []VolumeOption `json:"labels"`
|
||||
Driver string `json:"driver"`
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Options []VolumeOption `json:"options"`
|
||||
}
|
||||
type VolumeCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
@@ -218,22 +222,27 @@ type VolumeCreate struct {
|
||||
Options []string `json:"options"`
|
||||
Labels []string `json:"labels"`
|
||||
}
|
||||
|
||||
type VolumeOption struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
type BatchDelete struct {
|
||||
Force bool `json:"force"`
|
||||
Names []string `json:"names" validate:"required"`
|
||||
TaskID string `json:"taskID"`
|
||||
Force bool `json:"force"`
|
||||
Names []string `json:"names" validate:"required"`
|
||||
}
|
||||
|
||||
type ComposeInfo struct {
|
||||
Name string `json:"name"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
ContainerNumber int `json:"containerNumber"`
|
||||
ConfigFile string `json:"configFile"`
|
||||
Workdir string `json:"workdir"`
|
||||
Path string `json:"path"`
|
||||
Containers []ComposeContainer `json:"containers"`
|
||||
Env []string `json:"env"`
|
||||
Name string `json:"name"`
|
||||
CreatedAt string `json:"createdAt"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
ContainerCount int `json:"containerCount"`
|
||||
RunningCount int `json:"runningCount"`
|
||||
ConfigFile string `json:"configFile"`
|
||||
Workdir string `json:"workdir"`
|
||||
Path string `json:"path"`
|
||||
Containers []ComposeContainer `json:"containers"`
|
||||
Env []string `json:"env"`
|
||||
}
|
||||
type ComposeContainer struct {
|
||||
ContainerID string `json:"containerID"`
|
||||
@@ -253,8 +262,9 @@ type ComposeCreate struct {
|
||||
type ComposeOperation struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Path string `json:"path"`
|
||||
Operation string `json:"operation" validate:"required,oneof=up start stop down delete"`
|
||||
Operation string `json:"operation" validate:"required,oneof=up start restart stop down delete"`
|
||||
WithFile bool `json:"withFile"`
|
||||
Force bool `josn:"force"`
|
||||
}
|
||||
type ComposeUpdate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
|
||||
+91
-31
@@ -6,9 +6,10 @@ import (
|
||||
|
||||
type PageCronjob struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
OrderBy string `json:"orderBy" validate:"required,oneof=name status createdAt"`
|
||||
Order string `json:"order" validate:"required,oneof=null ascending descending"`
|
||||
Info string `json:"info"`
|
||||
GroupIDs []uint `json:"groupIDs"`
|
||||
OrderBy string `json:"orderBy" validate:"required,oneof=name status createdAt"`
|
||||
Order string `json:"order" validate:"required,oneof=null ascending descending"`
|
||||
}
|
||||
|
||||
type CronjobSpec struct {
|
||||
@@ -19,6 +20,7 @@ type CronjobOperate struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
GroupID uint `json:"groupID"`
|
||||
SpecCustom bool `json:"specCustom"`
|
||||
Spec string `json:"spec" validate:"required"`
|
||||
|
||||
@@ -29,25 +31,33 @@ type CronjobOperate struct {
|
||||
ContainerName string `json:"containerName"`
|
||||
User string `json:"user"`
|
||||
|
||||
ScriptID uint `json:"scriptID"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBType string `json:"dbType"`
|
||||
DBName string `json:"dbName"`
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
ScriptID uint `json:"scriptID"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBType string `json:"dbType"`
|
||||
DBName string `json:"dbName"`
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
SnapshotRule SnapshotRule `json:"snapshotRule"`
|
||||
|
||||
SourceAccountIDs string `json:"sourceAccountIDs"`
|
||||
DownloadAccountID uint `json:"downloadAccountID"`
|
||||
RetainCopies int `json:"retainCopies" validate:"number,min=1"`
|
||||
RetryTimes int `json:"retryTimes" validate:"number,min=0"`
|
||||
Timeout uint `json:"timeout" validate:"number,min=1"`
|
||||
IgnoreErr bool `json:"ignoreErr"`
|
||||
Secret string `json:"secret"`
|
||||
|
||||
AlertCount uint `json:"alertCount"`
|
||||
AlertTitle string `json:"alertTitle"`
|
||||
AlertCount uint `json:"alertCount"`
|
||||
AlertTitle string `json:"alertTitle"`
|
||||
AlertMethod string `json:"alertMethod"`
|
||||
}
|
||||
|
||||
type SnapshotRule struct {
|
||||
WithImage bool `json:"withImage"`
|
||||
IgnoreAppIDs []uint `json:"ignoreAppIDs"`
|
||||
}
|
||||
|
||||
type CronjobUpdateStatus struct {
|
||||
@@ -55,11 +65,6 @@ type CronjobUpdateStatus struct {
|
||||
Status string `json:"status" validate:"required"`
|
||||
}
|
||||
|
||||
type CronjobDownload struct {
|
||||
RecordID uint `json:"recordID" validate:"required"`
|
||||
BackupAccountID uint `json:"backupAccountID" validate:"required"`
|
||||
}
|
||||
|
||||
type CronjobClean struct {
|
||||
IsDelete bool `json:"isDelete"`
|
||||
CleanData bool `json:"cleanData"`
|
||||
@@ -77,6 +82,7 @@ type CronjobInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
GroupID uint `json:"groupID"`
|
||||
SpecCustom bool `json:"specCustom"`
|
||||
Spec string `json:"spec"`
|
||||
|
||||
@@ -87,18 +93,20 @@ type CronjobInfo struct {
|
||||
ContainerName string `json:"containerName"`
|
||||
User string `json:"user"`
|
||||
|
||||
ScriptID uint `json:"scriptID"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBType string `json:"dbType"`
|
||||
DBName string `json:"dbName"`
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
RetainCopies int `json:"retainCopies"`
|
||||
RetryTimes int `json:"retryTimes"`
|
||||
Timeout uint `json:"timeout"`
|
||||
ScriptID uint `json:"scriptID"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBType string `json:"dbType"`
|
||||
DBName string `json:"dbName"`
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
RetainCopies int `json:"retainCopies"`
|
||||
RetryTimes int `json:"retryTimes"`
|
||||
Timeout uint `json:"timeout"`
|
||||
IgnoreErr bool `json:"ignoreErr"`
|
||||
SnapshotRule SnapshotRule `json:"snapshotRule"`
|
||||
|
||||
SourceAccounts []string `json:"sourceAccounts"`
|
||||
DownloadAccount string `json:"downloadAccount"`
|
||||
@@ -113,6 +121,58 @@ type CronjobInfo struct {
|
||||
AlertCount uint `json:"alertCount"`
|
||||
}
|
||||
|
||||
type CronjobImport struct {
|
||||
Cronjobs []CronjobTrans `json:"cronjobs"`
|
||||
}
|
||||
type CronjobTrans struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
GroupID uint `json:"groupID"`
|
||||
SpecCustom bool `json:"specCustom"`
|
||||
Spec string `json:"spec"`
|
||||
|
||||
Executor string `json:"executor"`
|
||||
ScriptMode string `json:"scriptMode"`
|
||||
Script string `json:"script"`
|
||||
Command string `json:"command"`
|
||||
ContainerName string `json:"containerName"`
|
||||
User string `json:"user"`
|
||||
URL string `json:"url"`
|
||||
|
||||
ScriptName string `json:"scriptName"`
|
||||
Apps []TransHelper `json:"apps"`
|
||||
Websites []string `json:"websites"`
|
||||
DBType string `json:"dbType"`
|
||||
DBNames []TransHelper `json:"dbName"`
|
||||
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
|
||||
RetainCopies uint64 `json:"retainCopies"`
|
||||
RetryTimes uint `json:"retryTimes"`
|
||||
Timeout uint `json:"timeout"`
|
||||
IgnoreErr bool `json:"ignoreErr"`
|
||||
SnapshotRule SnapshotTransHelper `json:"snapshotRule"`
|
||||
Secret string `json:"secret"`
|
||||
|
||||
SourceAccounts []string `json:"sourceAccounts"`
|
||||
DownloadAccount string `json:"downloadAccount"`
|
||||
|
||||
AlertCount uint `json:"alertCount"`
|
||||
AlertTitle string `json:"alertTitle"`
|
||||
AlertMethod string `json:"alertMethod"`
|
||||
}
|
||||
type TransHelper struct {
|
||||
Name string `json:"name"`
|
||||
DetailName string `json:"detailName"`
|
||||
}
|
||||
type SnapshotTransHelper struct {
|
||||
WithImage bool `json:"withImage"`
|
||||
IgnoreApps []TransHelper `json:"ignoreApps"`
|
||||
}
|
||||
|
||||
type ScriptOptions struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
|
||||
@@ -23,9 +23,24 @@ type DashboardBase struct {
|
||||
CPULogicalCores int `json:"cpuLogicalCores"`
|
||||
CPUModelName string `json:"cpuModelName"`
|
||||
|
||||
QuickJumps []QuickJump `json:"quickJump"`
|
||||
CurrentInfo DashboardCurrent `json:"currentInfo"`
|
||||
}
|
||||
|
||||
type ChangeQuicks struct {
|
||||
Quicks []QuickJump `json:"quicks"`
|
||||
}
|
||||
|
||||
type QuickJump struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Title string `json:"title"`
|
||||
Detail string `json:"detail"`
|
||||
Recommend int `json:"recommend"`
|
||||
IsShow bool `json:"isShow"`
|
||||
Router string `json:"router"`
|
||||
}
|
||||
|
||||
type OsInfo struct {
|
||||
OS string `json:"os"`
|
||||
Platform string `json:"platform"`
|
||||
@@ -74,8 +89,11 @@ type DashboardCurrent struct {
|
||||
CPUTotal int `json:"cpuTotal"`
|
||||
|
||||
MemoryTotal uint64 `json:"memoryTotal"`
|
||||
MemoryAvailable uint64 `json:"memoryAvailable"`
|
||||
MemoryUsed uint64 `json:"memoryUsed"`
|
||||
MemoryFree uint64 `json:"memoryFree"`
|
||||
MemoryShard uint64 `json:"memoryShard"`
|
||||
MemoryCache uint64 `json:"memoryCache"`
|
||||
MemoryAvailable uint64 `json:"memoryAvailable"`
|
||||
MemoryUsedPercent float64 `json:"memoryUsedPercent"`
|
||||
|
||||
SwapMemoryTotal uint64 `json:"swapMemoryTotal"`
|
||||
|
||||
@@ -4,14 +4,14 @@ import "time"
|
||||
|
||||
// common
|
||||
type DBConfUpdateByFile struct {
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis mysql-cluster postgresql-cluster redis-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
File string `json:"file"`
|
||||
}
|
||||
type ChangeDBInfo struct {
|
||||
ID uint `json:"id"`
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis mysql-cluster postgresql-cluster redis-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Value string `json:"value" validate:"required"`
|
||||
}
|
||||
@@ -74,19 +74,19 @@ type BindUser struct {
|
||||
|
||||
type MysqlLoadDB struct {
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
}
|
||||
|
||||
type MysqlDBDeleteCheck struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
}
|
||||
|
||||
type MysqlDBDelete struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
@@ -153,7 +153,7 @@ type MysqlVariables struct {
|
||||
}
|
||||
|
||||
type MysqlVariablesUpdate struct {
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
Variables []MysqlVariablesUpdateHelper `json:"variables"`
|
||||
}
|
||||
@@ -174,6 +174,7 @@ type RedisConfUpdate struct {
|
||||
Timeout string `json:"timeout"`
|
||||
Maxclients string `json:"maxclients"`
|
||||
Maxmemory string `json:"maxmemory"`
|
||||
DBType string `json:"dbType" validate:"required,oneof=redis redis-cluster"`
|
||||
}
|
||||
type RedisConfPersistenceUpdate struct {
|
||||
Database string `json:"database" validate:"required"`
|
||||
@@ -181,6 +182,7 @@ type RedisConfPersistenceUpdate struct {
|
||||
Appendonly string `json:"appendonly"`
|
||||
Appendfsync string `json:"appendfsync"`
|
||||
Save string `json:"save"`
|
||||
DBType string `json:"dbType" validate:"required,oneof=redis redis-cluster"`
|
||||
}
|
||||
|
||||
type RedisConf struct {
|
||||
@@ -258,6 +260,7 @@ type DatabaseInfo struct {
|
||||
ClientCert string `json:"clientCert"`
|
||||
SkipVerify bool `json:"skipVerify"`
|
||||
|
||||
Timeout uint `json:"timeout"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
@@ -293,6 +296,7 @@ type DatabaseCreate struct {
|
||||
ClientCert string `json:"clientCert"`
|
||||
SkipVerify bool `json:"skipVerify"`
|
||||
|
||||
Timeout uint `json:"timeout"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
@@ -311,6 +315,7 @@ type DatabaseUpdate struct {
|
||||
ClientCert string `json:"clientCert"`
|
||||
SkipVerify bool `json:"skipVerify"`
|
||||
|
||||
Timeout uint `json:"timeout"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
@@ -319,3 +324,13 @@ type DatabaseDelete struct {
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
}
|
||||
|
||||
type LoadRedisStatus struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
}
|
||||
|
||||
type DBResource struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
@@ -60,26 +60,20 @@ type PostgresqlPrivileges struct {
|
||||
|
||||
type PostgresqlLoadDB struct {
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Type string `json:"type" validate:"required,oneof=postgresql"`
|
||||
Type string `json:"type" validate:"required,oneof=postgresql postgresql-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
}
|
||||
|
||||
type PostgresqlDBDeleteCheck struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=postgresql"`
|
||||
Type string `json:"type" validate:"required,oneof=postgresql postgresql-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
}
|
||||
|
||||
type PostgresqlDBDelete struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=postgresql"`
|
||||
Type string `json:"type" validate:"required,oneof=postgresql postgresql-cluster"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
}
|
||||
|
||||
type PostgresqlConfUpdateByFile struct {
|
||||
Type string `json:"type" validate:"required,oneof=postgresql mariadb"`
|
||||
Database string `json:"database" validate:"required"`
|
||||
File string `json:"file"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package dto
|
||||
|
||||
type LsblkDevice struct {
|
||||
Name string `json:"name"`
|
||||
Size string `json:"size"`
|
||||
Type string `json:"type"`
|
||||
MountPoint *string `json:"mountpoint"`
|
||||
FsType *string `json:"fstype"`
|
||||
Model *string `json:"model"`
|
||||
Serial string `json:"serial"`
|
||||
Tran string `json:"tran"`
|
||||
Rota bool `json:"rota"`
|
||||
Children []LsblkDevice `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
type LsblkOutput struct {
|
||||
BlockDevices []LsblkDevice `json:"blockdevices"`
|
||||
}
|
||||
|
||||
type DiskFormatRequest struct {
|
||||
Device string `json:"device" `
|
||||
Filesystem string `json:"filesystem" `
|
||||
Label string `json:"label,omitempty" `
|
||||
QuickFormat bool `json:"quickFormat,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dto
|
||||
|
||||
type LogFileRes struct {
|
||||
Lines []string `json:"lines"`
|
||||
IsEndOfFile bool `json:"isEndOfFile"`
|
||||
TotalPages int `json:"totalPages"`
|
||||
TotalLines int `json:"totalLines"`
|
||||
}
|
||||
@@ -17,7 +17,8 @@ type RuleSearch struct {
|
||||
}
|
||||
|
||||
type FirewallOperation struct {
|
||||
Operation string `json:"operation" validate:"required,oneof=start stop restart disablePing enablePing"`
|
||||
Operation string `json:"operation" validate:"required,oneof=start stop restart disablePing enablePing"`
|
||||
WithDockerRestart bool `json:"withDockerRestart"`
|
||||
}
|
||||
|
||||
type PortRuleOperate struct {
|
||||
|
||||
@@ -2,12 +2,19 @@ package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type PageImage struct {
|
||||
PageInfo
|
||||
Name string `json:"name"`
|
||||
OrderBy string `json:"orderBy" validate:"required,oneof=size tags createdAt isUsed"`
|
||||
Order string `json:"order" validate:"required,oneof=null ascending descending"`
|
||||
}
|
||||
|
||||
type ImageInfo struct {
|
||||
ID string `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
IsUsed bool `json:"isUsed"`
|
||||
Tags []string `json:"tags"`
|
||||
Size string `json:"size"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
|
||||
type ImageLoad struct {
|
||||
|
||||
@@ -6,8 +6,8 @@ type ImageRepoCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
Protocol string `json:"protocol"`
|
||||
Username string `json:"username" validate:"max=256"`
|
||||
Password string `json:"password" validate:"max=256"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Auth bool `json:"auth"`
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ type ImageRepoUpdate struct {
|
||||
ID uint `json:"id"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
Protocol string `json:"protocol"`
|
||||
Username string `json:"username" validate:"max=256"`
|
||||
Password string `json:"password" validate:"max=256"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Auth bool `json:"auth"`
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ type AppContainerConfig struct {
|
||||
WebUI string `json:"webUI"`
|
||||
Type string `json:"type"`
|
||||
SpecifyIP string `json:"specifyIP"`
|
||||
RestartPolicy string `json:"restartPolicy" validate:"omitempty,oneof=always unless-stopped no on-failure"`
|
||||
}
|
||||
|
||||
type AppInstalledSearch struct {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package request
|
||||
|
||||
type DiskPartitionRequest struct {
|
||||
Device string `json:"device" validate:"required"`
|
||||
Filesystem string `json:"filesystem" validate:"required,oneof=ext4 xfs"`
|
||||
Label string `json:"label"`
|
||||
AutoMount bool `json:"autoMount"`
|
||||
MountPoint string `json:"mountPoint" validate:"required"`
|
||||
}
|
||||
|
||||
type DiskMountRequest struct {
|
||||
Device string `json:"device" validate:"required"`
|
||||
MountPoint string `json:"mountPoint" validate:"required"`
|
||||
Filesystem string `json:"filesystem" validate:"required,oneof=ext4 xfs"`
|
||||
AutoMount bool `json:"autoMount"`
|
||||
}
|
||||
|
||||
type DiskUnmountRequest struct {
|
||||
MountPoint string `json:"mountPoint" validate:"required"`
|
||||
}
|
||||
@@ -92,11 +92,12 @@ type FileWget struct {
|
||||
}
|
||||
|
||||
type FileMove struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
OldPaths []string `json:"oldPaths" validate:"required"`
|
||||
NewPath string `json:"newPath" validate:"required"`
|
||||
Name string `json:"name"`
|
||||
Cover bool `json:"cover"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
OldPaths []string `json:"oldPaths" validate:"required"`
|
||||
NewPath string `json:"newPath" validate:"required"`
|
||||
Name string `json:"name"`
|
||||
Cover bool `json:"cover"`
|
||||
CoverPaths []string `json:"coverPaths"`
|
||||
}
|
||||
|
||||
type FileDownload struct {
|
||||
|
||||
@@ -33,6 +33,7 @@ type SupervisorProcessConfig struct {
|
||||
Dir string `json:"dir"`
|
||||
Numprocs string `json:"numprocs"`
|
||||
AutoRestart string `json:"autoRestart"`
|
||||
AutoStart string `json:"autoStart"`
|
||||
}
|
||||
|
||||
type SupervisorProcessFileReq struct {
|
||||
|
||||
@@ -9,15 +9,18 @@ type McpServerSearch struct {
|
||||
}
|
||||
|
||||
type McpServerCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Command string `json:"command" validate:"required"`
|
||||
Environments []Environment `json:"environments"`
|
||||
Volumes []Volume `json:"volumes"`
|
||||
Port int `json:"port" validate:"required"`
|
||||
ContainerName string `json:"containerName"`
|
||||
BaseURL string `json:"baseUrl"`
|
||||
SsePath string `json:"ssePath"`
|
||||
HostIP string `json:"hostIP"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Command string `json:"command" validate:"required"`
|
||||
Environments []Environment `json:"environments"`
|
||||
Volumes []Volume `json:"volumes"`
|
||||
Port int `json:"port" validate:"required"`
|
||||
ContainerName string `json:"containerName"`
|
||||
BaseURL string `json:"baseUrl"`
|
||||
SsePath string `json:"ssePath"`
|
||||
HostIP string `json:"hostIP"`
|
||||
StreamableHttpPath string `json:"streamableHttpPath"`
|
||||
OutputTransport string `json:"outputTransport" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
}
|
||||
|
||||
type McpServerUpdate struct {
|
||||
|
||||
@@ -81,8 +81,8 @@ type NginxCommonReq struct {
|
||||
|
||||
type NginxAntiLeechUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Extends string `json:"extends" validate:"required"`
|
||||
Return string `json:"return" validate:"required"`
|
||||
Extends string `json:"extends"`
|
||||
Return string `json:"return"`
|
||||
Enable bool `json:"enable" `
|
||||
ServerNames []string `json:"serverNames"`
|
||||
Cache bool `json:"cache"`
|
||||
@@ -126,3 +126,7 @@ type NginxModuleUpdate struct {
|
||||
Enable bool `json:"enable"`
|
||||
Params string `json:"params"`
|
||||
}
|
||||
|
||||
type NginxOperateReq struct {
|
||||
Operate string `json:"operate" validate:"required,oneof=enable disable"`
|
||||
}
|
||||
|
||||
@@ -12,15 +12,17 @@ type RuntimeSearch struct {
|
||||
}
|
||||
|
||||
type RuntimeCreate struct {
|
||||
AppDetailID uint `json:"appDetailId"`
|
||||
Name string `json:"name"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Resource string `json:"resource"`
|
||||
Image string `json:"image"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
AppDetailID uint `json:"appDetailId"`
|
||||
Name string `json:"name"`
|
||||
Resource string `json:"resource"`
|
||||
Image string `json:"image"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
Remark string `json:"remark"`
|
||||
|
||||
Params map[string]interface{} `json:"params"`
|
||||
NodeConfig
|
||||
}
|
||||
|
||||
@@ -53,14 +55,16 @@ type RuntimeDelete struct {
|
||||
}
|
||||
|
||||
type RuntimeUpdate struct {
|
||||
Name string `json:"name"`
|
||||
ID uint `json:"id"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Image string `json:"image"`
|
||||
Version string `json:"version"`
|
||||
Rebuild bool `json:"rebuild"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
Name string `json:"name"`
|
||||
ID uint `json:"id"`
|
||||
Image string `json:"image"`
|
||||
Version string `json:"version"`
|
||||
Rebuild bool `json:"rebuild"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
Remark string `json:"remark"`
|
||||
|
||||
Params map[string]interface{} `json:"params"`
|
||||
NodeConfig
|
||||
}
|
||||
|
||||
@@ -131,3 +135,8 @@ type PHPContainerConfig struct {
|
||||
Environments []Environment `json:"environments"`
|
||||
Volumes []Volume `json:"volumes"`
|
||||
}
|
||||
|
||||
type RuntimeRemark struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ type WebsiteCreate struct {
|
||||
TaskID string `json:"taskID"`
|
||||
ParentWebsiteID uint `json:"parentWebsiteID"`
|
||||
|
||||
SiteDir string `json:"siteDir"`
|
||||
|
||||
RuntimeConfig
|
||||
FtpConfig
|
||||
DataBaseConfig
|
||||
@@ -150,21 +152,22 @@ type WebsiteDomainDelete struct {
|
||||
}
|
||||
|
||||
type WebsiteHTTPSOp struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Enable bool `json:"enable"`
|
||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
PrivateKeyPath string `json:"privateKeyPath"`
|
||||
CertificatePath string `json:"certificatePath"`
|
||||
ImportType string `json:"importType"`
|
||||
HttpConfig string `json:"httpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||
SSLProtocol []string `json:"SSLProtocol"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
Hsts bool `json:"hsts"`
|
||||
HttpsPorts []int `json:"httpsPorts"`
|
||||
Http3 bool `json:"http3"`
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Enable bool `json:"enable"`
|
||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
PrivateKeyPath string `json:"privateKeyPath"`
|
||||
CertificatePath string `json:"certificatePath"`
|
||||
ImportType string `json:"importType"`
|
||||
HttpConfig string `json:"httpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||
SSLProtocol []string `json:"SSLProtocol"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
Hsts bool `json:"hsts"`
|
||||
HstsIncludeSubDomains bool `json:"hstsIncludeSubDomains"`
|
||||
HttpsPorts []int `json:"httpsPorts"`
|
||||
Http3 bool `json:"http3"`
|
||||
}
|
||||
|
||||
type WebsiteNginxUpdate struct {
|
||||
@@ -201,22 +204,24 @@ type WebsiteUpdateDirPermission struct {
|
||||
}
|
||||
|
||||
type WebsiteProxyConfig struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
Enable bool `json:"enable" `
|
||||
Cache bool `json:"cache" `
|
||||
CacheTime int `json:"cacheTime" `
|
||||
CacheUnit string `json:"cacheUnit"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Modifier string `json:"modifier"`
|
||||
Match string `json:"match" validate:"required"`
|
||||
ProxyPass string `json:"proxyPass" validate:"required"`
|
||||
ProxyHost string `json:"proxyHost" validate:"required"`
|
||||
Content string `json:"content"`
|
||||
FilePath string `json:"filePath"`
|
||||
Replaces map[string]string `json:"replaces"`
|
||||
SNI bool `json:"sni"`
|
||||
ProxySSLName string `json:"proxySSLName"`
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
Enable bool `json:"enable" `
|
||||
Cache bool `json:"cache" `
|
||||
CacheTime int `json:"cacheTime"`
|
||||
CacheUnit string `json:"cacheUnit"`
|
||||
ServerCacheTime int `json:"serverCacheTime"`
|
||||
ServerCacheUnit string `json:"serverCacheUnit"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Modifier string `json:"modifier"`
|
||||
Match string `json:"match" validate:"required"`
|
||||
ProxyPass string `json:"proxyPass" validate:"required"`
|
||||
ProxyHost string `json:"proxyHost" validate:"required"`
|
||||
Content string `json:"content"`
|
||||
FilePath string `json:"filePath"`
|
||||
Replaces map[string]string `json:"replaces"`
|
||||
SNI bool `json:"sni"`
|
||||
ProxySSLName string `json:"proxySSLName"`
|
||||
}
|
||||
|
||||
type WebsiteProxyReq struct {
|
||||
@@ -281,8 +286,8 @@ type WebsiteRealIP struct {
|
||||
|
||||
type ChangeDatabase struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
DatabaseID uint `json:"databaseID" validate:"required"`
|
||||
DatabaseType string `json:"databaseType" validate:"required"`
|
||||
DatabaseID uint `json:"databaseID" `
|
||||
DatabaseType string `json:"databaseType" `
|
||||
}
|
||||
|
||||
type WebsiteProxyDel struct {
|
||||
@@ -294,3 +299,13 @@ type CrossSiteAccessOp struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Operation string `json:"operation" validate:"required,oneof=Enable Disable"`
|
||||
}
|
||||
|
||||
type ExecComposerReq struct {
|
||||
Command string `json:"command" validate:"required"`
|
||||
ExtCommand string `json:"extCommand"`
|
||||
Mirror string `json:"mirror" validate:"required"`
|
||||
Dir string `json:"dir" validate:"required"`
|
||||
User string `json:"user" validate:"required"`
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
TaskID string `json:"taskID" validate:"required"`
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ type WebsiteSSLSearch struct {
|
||||
dto.PageInfo
|
||||
AcmeAccountID string `json:"acmeAccountID"`
|
||||
Domain string `json:"domain"`
|
||||
OrderBy string `json:"orderBy" validate:"required,oneof=expire_date"`
|
||||
Order string `json:"order" validate:"required,oneof=null ascending descending"`
|
||||
}
|
||||
|
||||
type WebsiteSSLCreate struct {
|
||||
@@ -27,6 +29,8 @@ type WebsiteSSLCreate struct {
|
||||
Nameserver2 string `json:"nameserver2"`
|
||||
ExecShell bool `json:"execShell"`
|
||||
Shell string `json:"shell"`
|
||||
PushNode bool `json:"pushNode"`
|
||||
Nodes string `json:"nodes"`
|
||||
}
|
||||
|
||||
type WebsiteDNSReq struct {
|
||||
@@ -105,6 +109,8 @@ type WebsiteSSLUpdate struct {
|
||||
Nameserver2 string `json:"nameserver2"`
|
||||
ExecShell bool `json:"execShell"`
|
||||
Shell string `json:"shell"`
|
||||
PushNode bool `json:"pushNode"`
|
||||
Nodes string `json:"nodes"`
|
||||
}
|
||||
|
||||
type WebsiteSSLUpload struct {
|
||||
|
||||
@@ -66,6 +66,7 @@ type AppInstalledCheck struct {
|
||||
InstallPath string `json:"installPath"`
|
||||
HttpPort int `json:"httpPort"`
|
||||
HttpsPort int `json:"httpsPort"`
|
||||
WebsiteDir string `json:"websiteDir"`
|
||||
}
|
||||
|
||||
type AppDetailDTO struct {
|
||||
@@ -129,6 +130,19 @@ type AppInstallDTO struct {
|
||||
Container string `json:"container"`
|
||||
}
|
||||
|
||||
type AppInstallInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
HttpPort int `json:"HttpPort"`
|
||||
Container string `json:"container"`
|
||||
ComposePath string `json:"composePath"`
|
||||
|
||||
Env map[string]interface{} `json:"env"`
|
||||
}
|
||||
|
||||
type DatabaseConn struct {
|
||||
Status string `json:"status"`
|
||||
Username string `json:"username"`
|
||||
@@ -158,6 +172,7 @@ type AppParam struct {
|
||||
ShowValue string `json:"showValue"`
|
||||
Required bool `json:"required"`
|
||||
Multiple bool `json:"multiple"`
|
||||
Label dto.Locale `json:"label"`
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
|
||||
@@ -6,5 +6,5 @@ type AppIgnoreUpgradeDTO struct {
|
||||
AppDetailID uint `json:"appDetailID"`
|
||||
Scope string `json:"scope"`
|
||||
Version string `json:"version"`
|
||||
Icon string `json:"icon"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package response
|
||||
|
||||
type DiskInfo struct {
|
||||
DiskBasicInfo
|
||||
Partitions []DiskBasicInfo `json:"partitions"`
|
||||
}
|
||||
|
||||
type DiskBasicInfo struct {
|
||||
Device string `json:"device"`
|
||||
Size string `json:"size"`
|
||||
Model string `json:"model"`
|
||||
DiskType string `json:"diskType"`
|
||||
IsRemovable bool `json:"isRemovable"`
|
||||
IsSystem bool `json:"isSystem"`
|
||||
Filesystem string `json:"filesystem"`
|
||||
Used string `json:"used"`
|
||||
Avail string `json:"avail"`
|
||||
UsePercent int `json:"usePercent"`
|
||||
MountPoint string `json:"mountPoint"`
|
||||
IsMounted bool `json:"isMounted"`
|
||||
Serial string `json:"serial"`
|
||||
}
|
||||
|
||||
type CompleteDiskInfo struct {
|
||||
Disks []DiskInfo `json:"disks"`
|
||||
UnpartitionedDisks []DiskBasicInfo `json:"unpartitionedDisks"`
|
||||
SystemDisk *DiskInfo `json:"systemDisk"`
|
||||
TotalDisks int `json:"totalDisks"`
|
||||
TotalCapacity int64 `json:"totalCapacity"`
|
||||
}
|
||||
|
||||
type MountInfo struct {
|
||||
Device string `json:"device"`
|
||||
MountPoint string `json:"mountPoint"`
|
||||
Filesystem string `json:"filesystem"`
|
||||
Options string `json:"options"`
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||
)
|
||||
|
||||
type FileInfo struct {
|
||||
@@ -37,11 +38,13 @@ type FileWgetRes struct {
|
||||
}
|
||||
|
||||
type FileLineContent struct {
|
||||
Content string `json:"content"`
|
||||
End bool `json:"end"`
|
||||
Path string `json:"path"`
|
||||
Total int `json:"total"`
|
||||
Lines []string `json:"lines"`
|
||||
End bool `json:"end"`
|
||||
Path string `json:"path"`
|
||||
Total int `json:"total"`
|
||||
TaskStatus string `json:"taskStatus"`
|
||||
Lines []string `json:"lines"`
|
||||
Scope string `json:"scope"`
|
||||
TotalLines int `json:"totalLines"`
|
||||
}
|
||||
|
||||
type FileExist struct {
|
||||
@@ -53,6 +56,7 @@ type ExistFileInfo struct {
|
||||
Path string `json:"path"`
|
||||
Size int64 `json:"size"`
|
||||
ModTime time.Time `json:"modTime"`
|
||||
IsDir bool `json:"isDir"`
|
||||
}
|
||||
|
||||
type UserInfo struct {
|
||||
|
||||
@@ -31,6 +31,7 @@ type SupervisorProcessConfig struct {
|
||||
Msg string `json:"msg"`
|
||||
Status []ProcessStatus `json:"status"`
|
||||
AutoRestart string `json:"autoRestart"`
|
||||
AutoStart string `json:"autoStart"`
|
||||
}
|
||||
|
||||
type ProcessStatus struct {
|
||||
|
||||
@@ -80,3 +80,7 @@ type NginxBuildConfig struct {
|
||||
Mirror string `json:"mirror"`
|
||||
Modules []NginxModule `json:"modules"`
|
||||
}
|
||||
|
||||
type NginxConfigRes struct {
|
||||
Https bool `json:"https"`
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ type RuntimeDTO struct {
|
||||
Volumes []request.Volume `json:"volumes"`
|
||||
ContainerStatus string `json:"containerStatus"`
|
||||
Container string `json:"container"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type PackageScripts struct {
|
||||
@@ -53,6 +54,7 @@ func NewRuntimeDTO(runtime model.Runtime) RuntimeDTO {
|
||||
Port: runtime.Port,
|
||||
Path: runtime.GetPath(),
|
||||
Container: runtime.ContainerName,
|
||||
Remark: runtime.Remark,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,3 +78,8 @@ type PHPExtensionRes struct {
|
||||
Extensions []string `json:"extensions"`
|
||||
SupportExtensions []SupportExtension `json:"supportExtensions"`
|
||||
}
|
||||
|
||||
type FpmStatusItem struct {
|
||||
Key string `json:"key"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package response
|
||||
|
||||
type ComponentInfo struct {
|
||||
Exists bool `json:"exists"`
|
||||
Version string `json:"version"`
|
||||
Path string `json:"path"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
@@ -37,6 +37,7 @@ type WebsiteRes struct {
|
||||
ChildSites []string `json:"childSites"`
|
||||
RuntimeType string `json:"runtimeType"`
|
||||
Favorite bool `json:"favorite"`
|
||||
IPV6 bool `json:"IPV6"`
|
||||
}
|
||||
|
||||
type WebsiteOption struct {
|
||||
@@ -64,6 +65,7 @@ type WebsiteHTTPS struct {
|
||||
SSLProtocol []string `json:"SSLProtocol"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
Hsts bool `json:"hsts"`
|
||||
HstsIncludeSubDomains bool `json:"hstsIncludeSubDomains"`
|
||||
HttpsPorts []int `json:"httpsPorts"`
|
||||
HttpsPort string `json:"httpsPort"`
|
||||
Http3 bool `json:"http3"`
|
||||
|
||||
@@ -23,8 +23,6 @@ type SettingInfo struct {
|
||||
AppStoreSyncStatus string `json:"appStoreSyncStatus"`
|
||||
|
||||
FileRecycleBin string `json:"fileRecycleBin"`
|
||||
|
||||
SnapshotIgnore string `json:"snapshotIgnore"`
|
||||
}
|
||||
|
||||
type SettingUpdate struct {
|
||||
|
||||
@@ -18,16 +18,20 @@ type SnapshotCreate struct {
|
||||
Description string `json:"description" validate:"max=256"`
|
||||
Secret string `json:"secret"`
|
||||
InterruptStep string `json:"interruptStep"`
|
||||
Timeout uint `json:"timeout"`
|
||||
|
||||
AppData []DataTree `json:"appData"`
|
||||
BackupData []DataTree `json:"backupData"`
|
||||
PanelData []DataTree `json:"panelData"`
|
||||
|
||||
WithDockerConf bool `json:"withDockerConf"`
|
||||
WithMonitorData bool `json:"withMonitorData"`
|
||||
WithLoginLog bool `json:"withLoginLog"`
|
||||
WithOperationLog bool `json:"withOperationLog"`
|
||||
WithSystemLog bool `json:"withSystemLog"`
|
||||
WithTaskLog bool `json:"withTaskLog"`
|
||||
|
||||
IgnoreFiles []string `json:"ignoreFiles"`
|
||||
}
|
||||
|
||||
type SnapshotData struct {
|
||||
@@ -35,11 +39,13 @@ type SnapshotData struct {
|
||||
BackupData []DataTree `json:"backupData"`
|
||||
PanelData []DataTree `json:"panelData"`
|
||||
|
||||
WithMonitorData bool `json:"withMonitorData"`
|
||||
WithLoginLog bool `json:"withLoginLog"`
|
||||
WithOperationLog bool `json:"withOperationLog"`
|
||||
WithSystemLog bool `json:"withSystemLog"`
|
||||
WithTaskLog bool `json:"withTaskLog"`
|
||||
WithDockerConf bool `json:"withDockerConf"`
|
||||
WithMonitorData bool `json:"withMonitorData"`
|
||||
WithLoginLog bool `json:"withLoginLog"`
|
||||
WithOperationLog bool `json:"withOperationLog"`
|
||||
WithSystemLog bool `json:"withSystemLog"`
|
||||
WithTaskLog bool `json:"withTaskLog"`
|
||||
IgnoreFiles []string `json:"ignoreFiles"`
|
||||
}
|
||||
type DataTree struct {
|
||||
ID string `json:"id"`
|
||||
|
||||
+18
-9
@@ -19,12 +19,27 @@ type SSHInfo struct {
|
||||
PubkeyAuthentication string `json:"pubkeyAuthentication"`
|
||||
PermitRootLogin string `json:"permitRootLogin"`
|
||||
UseDNS string `json:"useDNS"`
|
||||
CurrentUser string `json:"currentUser"`
|
||||
}
|
||||
|
||||
type GenerateSSH struct {
|
||||
EncryptionMode string `json:"encryptionMode" validate:"required,oneof=rsa ed25519 ecdsa dsa"`
|
||||
Password string `json:"password"`
|
||||
type CreateRootCert struct {
|
||||
Name string `json:"name"`
|
||||
Mode string `json:"mode"`
|
||||
EncryptionMode string `json:"encryptionMode" validate:"required,oneof=rsa ed25519 ecdsa dsa"`
|
||||
PassPhrase string `json:"passPhrase"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
type RootCert struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Name string `json:"name"`
|
||||
EncryptionMode string `json:"encryptionMode"`
|
||||
PassPhrase string `json:"passPhrase"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type GenerateLoad struct {
|
||||
@@ -39,12 +54,6 @@ type SearchSSHLog struct {
|
||||
Info string `json:"info"`
|
||||
Status string `json:"Status" validate:"required,oneof=Success Failed All"`
|
||||
}
|
||||
type SSHLog struct {
|
||||
Logs []SSHHistory `json:"logs"`
|
||||
TotalCount int `json:"totalCount"`
|
||||
SuccessfulCount int `json:"successfulCount"`
|
||||
FailedCount int `json:"failedCount"`
|
||||
}
|
||||
|
||||
type SSHHistory struct {
|
||||
Date time.Time `json:"date"`
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package model
|
||||
|
||||
type Alert struct {
|
||||
BaseModel
|
||||
|
||||
Title string `gorm:"type:varchar(256);not null" json:"title"`
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Cycle uint `gorm:"type:integer;not null" json:"cycle"`
|
||||
Count uint `gorm:"type:integer;not null" json:"count"`
|
||||
Project string `gorm:"type:varchar(64)" json:"project"`
|
||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||
Method string `gorm:"type:varchar(64);not null" json:"method"`
|
||||
SendCount uint `gorm:"type:integer" json:"sendCount"`
|
||||
AdvancedParams string `gorm:"type:longText" json:"advancedParam"`
|
||||
}
|
||||
|
||||
type AlertTask struct {
|
||||
BaseModel
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Quota string `gorm:"type:varchar(64)" json:"quota"`
|
||||
QuotaType string `gorm:"type:varchar(64)" json:"quotaType"`
|
||||
Method string `gorm:"type:varchar(64);not null;default:'sms'" json:"method"`
|
||||
}
|
||||
|
||||
type AlertLog struct {
|
||||
BaseModel
|
||||
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||
AlertId uint `gorm:"type:integer;not null" json:"alertId"`
|
||||
AlertDetail string `gorm:"type:varchar(256);not null" json:"alertDetail"`
|
||||
AlertRule string `gorm:"type:varchar(256);not null" json:"alertRule"`
|
||||
Count uint `gorm:"type:integer;not null" json:"count"`
|
||||
Message string `gorm:"type:varchar(256);" json:"message"`
|
||||
RecordId uint `gorm:"type:integer;" json:"recordId"`
|
||||
LicenseId string `gorm:"type:varchar(256);not null;" json:"licenseId" `
|
||||
Method string `gorm:"type:varchar(64);not null;default:'sms'" json:"method"`
|
||||
}
|
||||
|
||||
type AlertConfig struct {
|
||||
BaseModel
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Title string `gorm:"type:varchar(64);not null" json:"title"`
|
||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||
Config string `gorm:"type:varchar(256);not null" json:"config"`
|
||||
}
|
||||
|
||||
type LoginLog struct {
|
||||
BaseModel
|
||||
IP string `json:"ip"`
|
||||
Address string `json:"address"`
|
||||
Agent string `json:"agent"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
@@ -4,3 +4,13 @@ type AppLauncher struct {
|
||||
BaseModel
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
type QuickJump struct {
|
||||
BaseModel
|
||||
Name string `json:"name"`
|
||||
Title string `json:"title"`
|
||||
Detail string `json:"detail"`
|
||||
Recommend int `json:"recommend"`
|
||||
IsShow bool `json:"isShow"`
|
||||
Router string `json:"router"`
|
||||
}
|
||||
|
||||
+18
-1
@@ -1,14 +1,31 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Clam struct {
|
||||
BaseModel
|
||||
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
Status string `json:"status"`
|
||||
Path string `gorm:"not null" json:"path"`
|
||||
InfectedStrategy string `json:"infectedStrategy"`
|
||||
InfectedDir string `json:"infectedDir"`
|
||||
Spec string `json:"spec"`
|
||||
EntryID int `json:"entryID"`
|
||||
Description string `json:"description"`
|
||||
|
||||
Status string `json:"status"`
|
||||
IsExecuting bool `json:"isExecuting"`
|
||||
}
|
||||
|
||||
type ClamRecord struct {
|
||||
BaseModel
|
||||
|
||||
ClamID uint `json:"clamID"`
|
||||
TaskID string `json:"taskID"`
|
||||
StartTime time.Time `json:"startTime"`
|
||||
ScanTime string `json:"scanTime"`
|
||||
InfectedFiles string `json:"infectedFiles"`
|
||||
TotalError string `json:"totalError"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// BackupAccounts ---> SourceAccountIDs
|
||||
// BackupAccounts ---> DownloadAccountID
|
||||
type Cronjob struct {
|
||||
BaseModel
|
||||
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
Type string `gorm:"not null" json:"type"`
|
||||
GroupID uint `json:"groupID"`
|
||||
SpecCustom bool `json:"specCustom"`
|
||||
Spec string `gorm:"not null" json:"spec"`
|
||||
|
||||
@@ -29,18 +28,21 @@ type Cronjob struct {
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
SnapshotRule string `json:"snapshotRule"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
|
||||
SourceAccountIDs string `json:"sourceAccountIDs"`
|
||||
DownloadAccountID uint `json:"downloadAccountID"`
|
||||
RetryTimes uint `json:"retryTimes"`
|
||||
Timeout uint `json:"timeout"`
|
||||
IgnoreErr bool `json:"ignoreErr"`
|
||||
RetainCopies uint64 `json:"retainCopies"`
|
||||
|
||||
Status string `json:"status"`
|
||||
EntryIDs string `json:"entryIDs"`
|
||||
Records []JobRecords `json:"records"`
|
||||
Secret string `json:"secret"`
|
||||
IsExecuting bool `json:"isExecuting"`
|
||||
Status string `json:"status"`
|
||||
EntryIDs string `json:"entryIDs"`
|
||||
Records []JobRecords `json:"records"`
|
||||
Secret string `json:"secret"`
|
||||
}
|
||||
|
||||
type JobRecords struct {
|
||||
|
||||
@@ -18,5 +18,6 @@ type Database struct {
|
||||
ClientCert string `json:"clientCert"`
|
||||
SkipVerify bool `json:"skipVerify"`
|
||||
|
||||
Timeout uint `json:"timeout"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
@@ -2,17 +2,20 @@ package model
|
||||
|
||||
type McpServer struct {
|
||||
BaseModel
|
||||
Name string `json:"name"`
|
||||
DockerCompose string `json:"dockerCompose"`
|
||||
Command string `json:"command"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Message string `json:"message"`
|
||||
Port int `json:"port"`
|
||||
Status string `json:"status"`
|
||||
Env string `json:"env"`
|
||||
BaseURL string `json:"baseUrl"`
|
||||
SsePath string `json:"ssePath"`
|
||||
WebsiteID int `json:"websiteID"`
|
||||
Dir string `json:"dir"`
|
||||
HostIP string `json:"hostIP"`
|
||||
Name string `json:"name"`
|
||||
DockerCompose string `json:"dockerCompose"`
|
||||
Command string `json:"command"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Message string `json:"message"`
|
||||
Port int `json:"port"`
|
||||
Status string `json:"status"`
|
||||
Env string `json:"env"`
|
||||
BaseURL string `json:"baseUrl"`
|
||||
SsePath string `json:"ssePath"`
|
||||
WebsiteID int `json:"websiteID"`
|
||||
Dir string `json:"dir"`
|
||||
HostIP string `json:"hostIP"`
|
||||
StreamableHttpPath string `json:"streamableHttpPath"`
|
||||
OutputTransport string `json:"outputTransport"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ type Runtime struct {
|
||||
Message string `json:"message"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func (r *Runtime) GetComposePath() string {
|
||||
|
||||
@@ -15,3 +15,13 @@ type NodeInfo struct {
|
||||
ServerCrt string `json:"serverCrt"`
|
||||
ServerKey string `json:"serverKey"`
|
||||
}
|
||||
|
||||
type LocalConnInfo struct {
|
||||
Addr string `json:"addr"`
|
||||
Port uint `json:"port"`
|
||||
User string `json:"user"`
|
||||
AuthMode string `json:"authMode"`
|
||||
Password string `json:"password"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
PassPhrase string `json:"passPhrase"`
|
||||
}
|
||||
|
||||
@@ -10,19 +10,23 @@ type Snapshot struct {
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
Version string `json:"version"`
|
||||
Timeout uint `json:"timeout"`
|
||||
|
||||
TaskID string `json:"taskID"`
|
||||
TaskRecoverID string `json:"taskRecoverID"`
|
||||
TaskRollbackID string `json:"taskRollbackID"`
|
||||
|
||||
AppData string `json:"appData"`
|
||||
PanelData string `json:"panelData"`
|
||||
BackupData string `json:"backupData"`
|
||||
AppData string `json:"appData"`
|
||||
PanelData string `json:"panelData"`
|
||||
BackupData string `json:"backupData"`
|
||||
|
||||
WithDockerConf bool `json:"withDockerConf"`
|
||||
WithMonitorData bool `json:"withMonitorData"`
|
||||
WithLoginLog bool `json:"withLoginLog"`
|
||||
WithOperationLog bool `json:"withOperationLog"`
|
||||
WithSystemLog bool `json:"withSystemLog"`
|
||||
WithTaskLog bool `json:"withTaskLog"`
|
||||
IgnoreFiles string `json:"ignoreFiles"`
|
||||
|
||||
InterruptStep string `json:"interruptStep"`
|
||||
RecoverStatus string `json:"recoverStatus"`
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package model
|
||||
|
||||
type RootCert struct {
|
||||
BaseModel
|
||||
Name string `json:"name" gorm:"not null;"`
|
||||
EncryptionMode string `json:"encryptionMode"`
|
||||
PassPhrase string `json:"passPhrase"`
|
||||
PublicKeyPath string `json:"publicKeyPath"`
|
||||
PrivateKeyPath string `json:"privateKeyPath"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
@@ -36,6 +36,9 @@ type WebsiteSSL struct {
|
||||
DisableCNAME bool `json:"disableCNAME"`
|
||||
ExecShell bool `json:"execShell"`
|
||||
Shell string `json:"shell"`
|
||||
MasterSSLID uint `json:"masterSslId"`
|
||||
Nodes string `json:"nodes"`
|
||||
PushNode bool `json:"pushNode"`
|
||||
|
||||
AcmeAccount WebsiteAcmeAccount `json:"acmeAccount" gorm:"-:migration"`
|
||||
DnsAccount WebsiteDnsAccount `json:"dnsAccount" gorm:"-:migration"`
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"google.golang.org/genproto/googleapis/type/date"
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AlertRepo struct{}
|
||||
|
||||
type IAlertRepo interface {
|
||||
WithByType(alertType string) DBOption
|
||||
WithByStatusIn(status []string) DBOption
|
||||
WithByProject(project string) DBOption
|
||||
WithByCount(count uint) DBOption
|
||||
WithByAlertId(alertId uint) DBOption
|
||||
WithByCreateAt(date *date.Date) DBOption
|
||||
WithByLicenseId(licenseId string) DBOption
|
||||
WithByRecordId(recordId uint) DBOption
|
||||
WithByMethod(method string) DBOption
|
||||
|
||||
Create(alert *model.Alert) error
|
||||
Get(opts ...DBOption) (model.Alert, error)
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.Alert, error)
|
||||
List(opts ...DBOption) ([]model.Alert, error)
|
||||
Delete(opts ...DBOption) error
|
||||
Save(alert *model.Alert) error
|
||||
Update(maps map[string]interface{}, opts ...DBOption) error
|
||||
|
||||
GetLog(opts ...DBOption) (model.AlertLog, error)
|
||||
CreateLog(alertLog *model.AlertLog) error
|
||||
PageLog(limit, offset int, opts ...DBOption) (int64, []model.AlertLog, error)
|
||||
ListLog(opts ...DBOption) ([]model.AlertLog, error)
|
||||
UpdateLog(id uint, maps map[string]interface{}) error
|
||||
BatchUpdateLogBy(maps map[string]interface{}, opts ...DBOption) error
|
||||
DeleteLog(opts ...DBOption) error
|
||||
CleanAlertLogs() error
|
||||
|
||||
CreateAlertTask(alertTaskBase *model.AlertTask) error
|
||||
DeleteAlertTask(opts ...DBOption) error
|
||||
GetAlertTask(opts ...DBOption) (model.AlertTask, error)
|
||||
LoadTaskCount(alertType string, project string, method string) (uint, uint, error)
|
||||
GetTaskLog(alertType string, alertId uint) (time.Time, error)
|
||||
GetLicensePushCount(method string) (uint, error)
|
||||
|
||||
GetConfig(opts ...DBOption) (model.AlertConfig, error)
|
||||
AlertConfigList(opts ...DBOption) ([]model.AlertConfig, error)
|
||||
UpdateAlertConfig(maps map[string]interface{}, opts ...DBOption) error
|
||||
CreateAlertConfig(config *model.AlertConfig) error
|
||||
DeleteAlertConfig(opts ...DBOption) error
|
||||
|
||||
SyncAll(data []model.AlertConfig) error
|
||||
}
|
||||
|
||||
func NewIAlertRepo() IAlertRepo {
|
||||
return &AlertRepo{}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByType(alertType string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`type` = ?", alertType)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByStatusIn(status []string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("status in (?)", status)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByCount(count uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("count = ?", count)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByProject(project string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("project = ?", project)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByAlertId(alertId uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("alert_id = ?", alertId)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByLicenseId(licenseId string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("license_id = ?", licenseId)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByRecordId(recordId uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("record_id = ?", recordId)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByMethod(method string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("method = ?", method)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) WithByCreateAt(createAt *date.Date) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("DATE(created_at) = DATE(?)", createAt)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AlertRepo) Create(alert *model.Alert) error {
|
||||
return global.AlertDB.Model(&model.Alert{}).Create(alert).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) Save(alert *model.Alert) error {
|
||||
return global.AlertDB.Save(alert).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) Get(opts ...DBOption) (model.Alert, error) {
|
||||
var alert model.Alert
|
||||
db, _ := getAlertDB(opts...)
|
||||
err := db.First(&alert).Error
|
||||
return alert, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) Page(page, size int, opts ...DBOption) (int64, []model.Alert, error) {
|
||||
var alerts []model.Alert
|
||||
alertDb, _ := getAlertDB(opts...)
|
||||
db := alertDb.Model(&model.Alert{})
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&alerts).Error
|
||||
return count, alerts, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) List(opts ...DBOption) ([]model.Alert, error) {
|
||||
var alert []model.Alert
|
||||
db, _ := getAlertDB(opts...)
|
||||
err := db.Find(&alert).Error
|
||||
return alert, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) Update(maps map[string]interface{}, opts ...DBOption) error {
|
||||
db, _ := getAlertDB(opts...)
|
||||
return db.Model(&model.Alert{}).Updates(maps).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) Delete(opts ...DBOption) error {
|
||||
db, _ := getAlertDB(opts...)
|
||||
return db.Delete(&model.Alert{}).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) GetLog(opts ...DBOption) (model.AlertLog, error) {
|
||||
var alertLog model.AlertLog
|
||||
db, _ := getAlertDB(opts...)
|
||||
err := db.First(&alertLog).Error
|
||||
return alertLog, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) CreateLog(log *model.AlertLog) error {
|
||||
return global.AlertDB.Model(&model.AlertLog{}).Create(&log).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) UpdateLog(id uint, maps map[string]interface{}) error {
|
||||
return global.AlertDB.Model(&model.AlertLog{}).Where("id = ?", id).Updates(maps).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) BatchUpdateLogBy(maps map[string]interface{}, opts ...DBOption) error {
|
||||
db, _ := getAlertDB(opts...)
|
||||
if len(opts) == 0 {
|
||||
db = db.Where("1=1")
|
||||
}
|
||||
return db.Model(&model.AlertLog{}).Updates(&maps).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) PageLog(page, size int, opts ...DBOption) (int64, []model.AlertLog, error) {
|
||||
var alerts []model.AlertLog
|
||||
db := global.AlertDB.Model(&model.AlertLog{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Order("created_at desc").Count(&count)
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&alerts).Error
|
||||
return count, alerts, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) ListLog(opts ...DBOption) ([]model.AlertLog, error) {
|
||||
var alertLog []model.AlertLog
|
||||
db, _ := getAlertDB(opts...)
|
||||
err := db.Find(&alertLog).Error
|
||||
return alertLog, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) DeleteLog(opts ...DBOption) error {
|
||||
db, _ := getAlertDB(opts...)
|
||||
return db.Delete(&model.AlertLog{}).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) CleanAlertLogs() error {
|
||||
return global.AlertDB.Where("1 = 1").Delete(&model.AlertLog{}).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) CreateAlertTask(alertTaskBase *model.AlertTask) error {
|
||||
return global.AlertDB.Model(&model.AlertTask{}).Create(&alertTaskBase).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) DeleteAlertTask(opts ...DBOption) error {
|
||||
db, _ := getAlertDB(opts...)
|
||||
return db.Delete(&model.AlertTask{}).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) GetAlertTask(opts ...DBOption) (model.AlertTask, error) {
|
||||
var data model.AlertTask
|
||||
db, _ := getAlertDB(opts...)
|
||||
err := db.First(&data).Error
|
||||
return data, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) LoadTaskCount(alertType string, project string, method string) (uint, uint, error) {
|
||||
var (
|
||||
todayCount int64
|
||||
totalCount int64
|
||||
)
|
||||
_ = global.AlertDB.Model(&model.AlertTask{}).Where("type = ? AND quota_type = ? AND method = ?", alertType, project, method).Count(&totalCount).Error
|
||||
|
||||
now := time.Now()
|
||||
todayMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||
tomorrowMidnight := todayMidnight.Add(24 * time.Hour)
|
||||
err := global.AlertDB.Model(&model.AlertTask{}).Where("type = ? AND quota_type = ? AND method = ? AND created_at > ? AND created_at < ?", alertType, project, method, todayMidnight, tomorrowMidnight).Count(&todayCount).Error
|
||||
return uint(todayCount), uint(totalCount), err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) GetTaskLog(alertType string, alertId uint) (time.Time, error) {
|
||||
var newDate time.Time
|
||||
status := []string{constant.AlertSuccess, constant.AlertPushSuccess, constant.AlertSyncError, constant.AlertPushing}
|
||||
now := time.Now()
|
||||
todayMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||
tomorrowMidnight := todayMidnight.Add(24 * time.Hour)
|
||||
err := global.AlertDB.Model(&model.AlertLog{}).
|
||||
Where("type = ? AND alert_id = ? AND status in ? AND created_at > ? AND created_at < ?", alertType, alertId, status, todayMidnight, tomorrowMidnight).
|
||||
Order("created_at DESC").
|
||||
Limit(1).
|
||||
Pluck("created_at", &newDate).Error
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
if newDate.IsZero() {
|
||||
return time.Time{}, nil
|
||||
}
|
||||
|
||||
return newDate, nil
|
||||
}
|
||||
|
||||
func getAlertDB(opts ...DBOption) (*gorm.DB, error) {
|
||||
var db *gorm.DB
|
||||
db = global.AlertDB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func (a *AlertRepo) GetLicensePushCount(method string) (uint, error) {
|
||||
var (
|
||||
todayCount int64
|
||||
)
|
||||
now := time.Now()
|
||||
todayMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
|
||||
tomorrowMidnight := todayMidnight.Add(24 * time.Hour)
|
||||
err := global.AlertDB.Model(&model.AlertTask{}).Where("created_at > ? AND created_at < ? AND method = ?", todayMidnight, tomorrowMidnight, method).Count(&todayCount).Error
|
||||
return uint(todayCount), err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) AlertConfigList(opts ...DBOption) ([]model.AlertConfig, error) {
|
||||
var config []model.AlertConfig
|
||||
db, _ := getAlertDB(opts...)
|
||||
err := db.Find(&config).Error
|
||||
return config, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) UpdateAlertConfig(maps map[string]interface{}, opts ...DBOption) error {
|
||||
db, _ := getAlertDB(opts...)
|
||||
return db.Model(&model.AlertConfig{}).Updates(maps).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) CreateAlertConfig(config *model.AlertConfig) error {
|
||||
return global.AlertDB.Model(&model.AlertConfig{}).Create(config).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) DeleteAlertConfig(opts ...DBOption) error {
|
||||
db, _ := getAlertDB(opts...)
|
||||
return db.Delete(&model.AlertConfig{}).Error
|
||||
}
|
||||
|
||||
func (a *AlertRepo) GetConfig(opts ...DBOption) (model.AlertConfig, error) {
|
||||
var alertConfig model.AlertConfig
|
||||
db, _ := getAlertDB(opts...)
|
||||
err := db.First(&alertConfig).Error
|
||||
return alertConfig, err
|
||||
}
|
||||
|
||||
func (a *AlertRepo) SyncAll(data []model.AlertConfig) error {
|
||||
tx := global.AlertDB.Begin()
|
||||
var oldConfigs []model.AlertConfig
|
||||
_ = tx.Find(&oldConfigs).Error
|
||||
oldConfigMap := make(map[string]uint)
|
||||
for _, item := range oldConfigs {
|
||||
oldConfigMap[item.Type] = item.ID
|
||||
}
|
||||
for _, item := range data {
|
||||
if val, ok := oldConfigMap[item.Type]; ok {
|
||||
item.ID = val
|
||||
delete(oldConfigMap, item.Type)
|
||||
} else {
|
||||
item.ID = 0
|
||||
}
|
||||
if err := tx.Model(model.AlertConfig{}).Where("id = ?", item.ID).Save(&item).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, val := range oldConfigMap {
|
||||
if err := tx.Where("id = ?", val).Delete(&model.AlertConfig{}).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
}
|
||||
+18
-1
@@ -33,6 +33,8 @@ type IAppRepo interface {
|
||||
BatchDelete(ctx context.Context, apps []model.App) error
|
||||
DeleteByIDs(ctx context.Context, ids []uint) error
|
||||
DeleteBy(opts ...DBOption) error
|
||||
|
||||
GetTopRecomment() ([]string, error)
|
||||
}
|
||||
|
||||
func NewIAppRepo() IAppRepo {
|
||||
@@ -44,7 +46,7 @@ func (a AppRepo) WithByLikeName(name string) DBOption {
|
||||
if len(name) == 0 {
|
||||
return g
|
||||
}
|
||||
return g.Where("name like ? or short_desc_zh like ? or short_desc_en like ?", "%"+name+"%", "%"+name+"%", "%"+name+"%")
|
||||
return g.Where("name like ? or description like ? or short_desc_zh like ? or short_desc_en like ?", "%"+name+"%", "%"+name+"%", "%"+name+"%", "%"+name+"%")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +125,21 @@ func (a AppRepo) GetBy(opts ...DBOption) ([]model.App, error) {
|
||||
return apps, nil
|
||||
}
|
||||
|
||||
func (a AppRepo) GetTopRecomment() ([]string, error) {
|
||||
var (
|
||||
apps []model.App
|
||||
names []string
|
||||
)
|
||||
db := getDb().Model(&model.App{})
|
||||
if err := db.Order("recommend asc").Limit(6).Find(&apps).Error; err != nil {
|
||||
return names, err
|
||||
}
|
||||
for _, item := range apps {
|
||||
names = append(names, item.Key)
|
||||
}
|
||||
return names, nil
|
||||
}
|
||||
|
||||
func (a AppRepo) BatchCreate(ctx context.Context, apps []model.App) error {
|
||||
return getTx(ctx).Omit(clause.Associations).Create(&apps).Error
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ type AppIgnoreUpgradeRepo struct {
|
||||
|
||||
type IAppIgnoreUpgradeRepo interface {
|
||||
WithScope(scope string) DBOption
|
||||
WithAppID(appID uint) DBOption
|
||||
List(opts ...DBOption) ([]model.AppIgnoreUpgrade, error)
|
||||
Create(appIgnoreUpgrade *model.AppIgnoreUpgrade) error
|
||||
Delete(opts ...DBOption) error
|
||||
@@ -26,6 +27,12 @@ func (a AppIgnoreUpgradeRepo) WithScope(scope string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppIgnoreUpgradeRepo) WithAppID(appID uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_id = ?", appID)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppIgnoreUpgradeRepo) List(opts ...DBOption) ([]model.AppIgnoreUpgrade, error) {
|
||||
var appIgnoreUpgradeList []model.AppIgnoreUpgrade
|
||||
err := getDb(opts...).Find(&appIgnoreUpgradeList).Error
|
||||
|
||||
@@ -36,6 +36,7 @@ type IAppInstallRepo interface {
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.AppInstall, error)
|
||||
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
|
||||
LoadBaseInfo(key string, name string) (*RootInfo, error)
|
||||
LoadInstallAppByKeyAndName(key string, name string) (*model.AppInstall, error)
|
||||
GetFirstByCtx(ctx context.Context, opts ...DBOption) (model.AppInstall, error)
|
||||
}
|
||||
|
||||
@@ -206,17 +207,17 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
|
||||
return nil, err
|
||||
}
|
||||
switch app.Key {
|
||||
case "mysql", "mariadb":
|
||||
case "mysql", "mariadb", constant.AppMysqlCluster:
|
||||
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
case "redis":
|
||||
case "redis", constant.AppRedisCluster:
|
||||
password, ok := envMap["PANEL_REDIS_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
case "mongodb", constant.AppPostgresql:
|
||||
case "mongodb", constant.AppPostgresql, constant.AppPostgresqlCluster:
|
||||
user, ok := envMap["PANEL_DB_ROOT_USER"].(string)
|
||||
if ok {
|
||||
info.UserName = user
|
||||
@@ -246,3 +247,23 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
|
||||
info.Status = appInstall.Status
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) LoadInstallAppByKeyAndName(key string, name string) (*model.AppInstall, error) {
|
||||
var (
|
||||
app model.App
|
||||
appInstall model.AppInstall
|
||||
)
|
||||
if err := global.DB.Where("key = ?", key).First(&app).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(name) == 0 {
|
||||
if err := global.DB.Where("app_id = ?", app.ID).First(&appInstall).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if err := global.DB.Where("app_id = ? AND name = ?", app.ID, name).First(&appInstall).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &appInstall, nil
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@ type ILauncherRepo interface {
|
||||
Create(launcher *model.AppLauncher) error
|
||||
Save(launcher *model.AppLauncher) error
|
||||
Delete(opts ...DBOption) error
|
||||
|
||||
GetQuickJump(opts ...DBOption) (model.QuickJump, error)
|
||||
ListQuickJump(withAll bool) []model.QuickJump
|
||||
UpdateQuicks(quicks []model.QuickJump) error
|
||||
}
|
||||
|
||||
func NewILauncherRepo() ILauncherRepo {
|
||||
@@ -57,3 +61,45 @@ func (u *LauncherRepo) Delete(opts ...DBOption) error {
|
||||
}
|
||||
return db.Delete(&model.AppLauncher{}).Error
|
||||
}
|
||||
|
||||
func (u *LauncherRepo) GetQuickJump(opts ...DBOption) (model.QuickJump, error) {
|
||||
var launcher model.QuickJump
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&launcher).Error
|
||||
return launcher, err
|
||||
}
|
||||
func (u *LauncherRepo) ListQuickJump(withAll bool) []model.QuickJump {
|
||||
var quicks []model.QuickJump
|
||||
if withAll {
|
||||
_ = global.DB.Find(&quicks).Error
|
||||
} else {
|
||||
_ = global.DB.Where("is_show = ?", true).Find(&quicks).Error
|
||||
}
|
||||
if !withAll && len(quicks) == 0 {
|
||||
return []model.QuickJump{
|
||||
{Name: "Website", Title: "menu.website", Recommend: 10, IsShow: true, Router: "/websites"},
|
||||
{Name: "Database", Title: "menu.database", Recommend: 30, IsShow: true, Router: "/databases"},
|
||||
{Name: "Cronjob", Title: "menu.cronjob", Recommend: 50, IsShow: true, Router: "/cronjobs"},
|
||||
{Name: "AppInstalled", Title: "home.appInstalled", Recommend: 70, IsShow: true, Router: "/apps/installed"},
|
||||
}
|
||||
}
|
||||
|
||||
return quicks
|
||||
}
|
||||
func (u *LauncherRepo) UpdateQuicks(quicks []model.QuickJump) error {
|
||||
tx := global.DB.Begin()
|
||||
for _, item := range quicks {
|
||||
if err := tx.Model(&model.QuickJump{}).Where("id = ?", item.ID).Updates(map[string]interface{}{
|
||||
"is_show": item.IsShow,
|
||||
"detail": item.Detail,
|
||||
}).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -17,8 +17,10 @@ type IAppTagRepo interface {
|
||||
GetByAppId(appId uint) ([]model.AppTag, error)
|
||||
GetByTagIds(tagIds []uint) ([]model.AppTag, error)
|
||||
DeleteBy(ctx context.Context, opts ...DBOption) error
|
||||
GetFirst(ctx context.Context, opts ...DBOption) (*model.AppTag, error)
|
||||
|
||||
WithByTagID(tagID uint) DBOption
|
||||
WithByAppID(appId uint) DBOption
|
||||
}
|
||||
|
||||
func NewIAppTagRepo() IAppTagRepo {
|
||||
@@ -31,6 +33,12 @@ func (a AppTagRepo) WithByTagID(tagID uint) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppTagRepo) WithByAppID(appId uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_id = ?", appId)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppTagRepo) BatchCreate(ctx context.Context, tags []*model.AppTag) error {
|
||||
return getTx(ctx).Create(&tags).Error
|
||||
}
|
||||
@@ -62,3 +70,12 @@ func (a AppTagRepo) GetByTagIds(tagIds []uint) ([]model.AppTag, error) {
|
||||
func (a AppTagRepo) DeleteBy(ctx context.Context, opts ...DBOption) error {
|
||||
return getTx(ctx, opts...).Delete(&model.AppTag{}).Error
|
||||
}
|
||||
|
||||
func (a AppTagRepo) GetFirst(ctx context.Context, opts ...DBOption) (*model.AppTag, error) {
|
||||
var appTag model.AppTag
|
||||
if err := getTx(ctx, opts...).First(&appTag).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &appTag, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ClamRepo struct{}
|
||||
@@ -14,6 +19,14 @@ type IClamRepo interface {
|
||||
Delete(opts ...DBOption) error
|
||||
Get(opts ...DBOption) (model.Clam, error)
|
||||
List(opts ...DBOption) ([]model.Clam, error)
|
||||
|
||||
WithByClamID(id uint) DBOption
|
||||
ListRecord(opts ...DBOption) ([]model.ClamRecord, error)
|
||||
RecordFirst(id uint) (model.ClamRecord, error)
|
||||
DeleteRecord(opts ...DBOption) error
|
||||
StartRecords(clamID uint) model.ClamRecord
|
||||
EndRecords(record model.ClamRecord, status, message string)
|
||||
PageRecords(page, size int, opts ...DBOption) (int64, []model.ClamRecord, error)
|
||||
}
|
||||
|
||||
func NewIClamRepo() IClamRepo {
|
||||
@@ -67,3 +80,69 @@ func (u *ClamRepo) Delete(opts ...DBOption) error {
|
||||
}
|
||||
return db.Delete(&model.Clam{}).Error
|
||||
}
|
||||
|
||||
func (c *ClamRepo) WithByClamID(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("clam_id = ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *ClamRepo) ListRecord(opts ...DBOption) ([]model.ClamRecord, error) {
|
||||
var record []model.ClamRecord
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.Find(&record).Error
|
||||
return record, err
|
||||
}
|
||||
|
||||
func (u *ClamRepo) RecordFirst(id uint) (model.ClamRecord, error) {
|
||||
var record model.ClamRecord
|
||||
err := global.DB.Where("clam_id = ?", id).Order("created_at desc").First(&record).Error
|
||||
return record, err
|
||||
}
|
||||
|
||||
func (u *ClamRepo) PageRecords(page, size int, opts ...DBOption) (int64, []model.ClamRecord, error) {
|
||||
var records []model.ClamRecord
|
||||
db := global.DB.Model(&model.ClamRecord{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Order("created_at desc").Limit(size).Offset(size * (page - 1)).Find(&records).Error
|
||||
return count, records, err
|
||||
}
|
||||
func (u *ClamRepo) StartRecords(clamID uint) model.ClamRecord {
|
||||
var record model.ClamRecord
|
||||
record.StartTime = time.Now()
|
||||
record.ClamID = clamID
|
||||
record.TaskID = uuid.New().String()
|
||||
record.Status = constant.StatusWaiting
|
||||
if err := global.DB.Create(&record).Error; err != nil {
|
||||
global.LOG.Errorf("create record status failed, err: %v", err)
|
||||
}
|
||||
_ = u.Update(clamID, map[string]interface{}{"is_executing": true})
|
||||
return record
|
||||
}
|
||||
func (u *ClamRepo) EndRecords(record model.ClamRecord, status, message string) {
|
||||
upMap := make(map[string]interface{})
|
||||
upMap["status"] = status
|
||||
upMap["message"] = message
|
||||
upMap["task_id"] = record.TaskID
|
||||
upMap["scan_time"] = record.ScanTime
|
||||
upMap["infected_files"] = record.InfectedFiles
|
||||
upMap["total_error"] = record.TotalError
|
||||
if err := global.DB.Model(&model.ClamRecord{}).Where("id = ?", record.ID).Updates(upMap).Error; err != nil {
|
||||
global.LOG.Errorf("update record status failed, err: %v", err)
|
||||
}
|
||||
_ = u.Update(record.ClamID, map[string]interface{}{"is_executing": false})
|
||||
}
|
||||
func (u *ClamRepo) DeleteRecord(opts ...DBOption) error {
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
return db.Delete(&model.ClamRecord{}).Error
|
||||
}
|
||||
|
||||
@@ -104,6 +104,15 @@ func WithByDate(startTime, endTime time.Time) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WithByGroups(groupIDs []uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
if len(groupIDs) == 0 {
|
||||
return g
|
||||
}
|
||||
return g.Where("group_id in (?)", groupIDs)
|
||||
}
|
||||
}
|
||||
|
||||
func WithByCreatedAt(startTime, endTime time.Time) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("created_at > ? AND created_at < ?", startTime, endTime)
|
||||
|
||||
@@ -29,9 +29,10 @@ type ICronjobRepo interface {
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
DeleteRecord(opts ...DBOption) error
|
||||
StartRecords(cronjobID uint, targetPath, cronjobType string) model.JobRecords
|
||||
StartRecords(cronjobID uint) model.JobRecords
|
||||
UpdateRecords(id uint, vars map[string]interface{}) error
|
||||
EndRecords(record model.JobRecords, status, message, records string)
|
||||
AddFailedRecord(cronjobID uint, message string)
|
||||
PageRecords(page, size int, opts ...DBOption) (int64, []model.JobRecords, error)
|
||||
}
|
||||
|
||||
@@ -143,7 +144,7 @@ func (c *CronjobRepo) WithByRecordDropID(id int) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *CronjobRepo) StartRecords(cronjobID uint, targetPath, cronjobType string) model.JobRecords {
|
||||
func (u *CronjobRepo) StartRecords(cronjobID uint) model.JobRecords {
|
||||
var record model.JobRecords
|
||||
record.StartTime = time.Now()
|
||||
record.CronjobID = cronjobID
|
||||
@@ -152,6 +153,7 @@ func (u *CronjobRepo) StartRecords(cronjobID uint, targetPath, cronjobType strin
|
||||
if err := global.DB.Create(&record).Error; err != nil {
|
||||
global.LOG.Errorf("create record status failed, err: %v", err)
|
||||
}
|
||||
_ = u.Update(cronjobID, map[string]interface{}{"is_executing": true})
|
||||
return record
|
||||
}
|
||||
func (u *CronjobRepo) EndRecords(record model.JobRecords, status, message, records string) {
|
||||
@@ -165,6 +167,17 @@ func (u *CronjobRepo) EndRecords(record model.JobRecords, status, message, recor
|
||||
if err := global.DB.Model(&model.JobRecords{}).Where("id = ?", record.ID).Updates(errMap).Error; err != nil {
|
||||
global.LOG.Errorf("update record status failed, err: %v", err)
|
||||
}
|
||||
_ = u.Update(record.CronjobID, map[string]interface{}{"is_executing": false})
|
||||
}
|
||||
func (u *CronjobRepo) AddFailedRecord(cronjobID uint, message string) {
|
||||
var record model.JobRecords
|
||||
record.StartTime = time.Now()
|
||||
record.CronjobID = cronjobID
|
||||
record.Status = constant.StatusFailed
|
||||
record.Message = message
|
||||
if err := global.DB.Create(&record).Error; err != nil {
|
||||
global.LOG.Errorf("create record status failed, err: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *CronjobRepo) Save(id uint, cronjob model.Cronjob) error {
|
||||
|
||||
@@ -3,6 +3,7 @@ package repo
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
|
||||
)
|
||||
|
||||
type HostRepo struct{}
|
||||
@@ -13,6 +14,14 @@ type IHostRepo interface {
|
||||
SaveFirewallRecord(firewall *model.Firewall) error
|
||||
DeleteFirewallRecordByID(id uint) error
|
||||
DeleteFirewallRecord(fType, port, protocol, address, strategy string) error
|
||||
|
||||
SyncCert(data []model.RootCert) error
|
||||
GetCert(opts ...DBOption) (model.RootCert, error)
|
||||
PageCert(limit, offset int, opts ...DBOption) (int64, []model.RootCert, error)
|
||||
ListCert(opts ...DBOption) ([]model.RootCert, error)
|
||||
CreateCert(cert *model.RootCert) error
|
||||
UpdateCert(id uint, vars map[string]interface{}) error
|
||||
DeleteCert(opts ...DBOption) error
|
||||
}
|
||||
|
||||
func NewIHostRepo() IHostRepo {
|
||||
@@ -63,3 +72,82 @@ func (h *HostRepo) DeleteFirewallRecordByID(id uint) error {
|
||||
func (h *HostRepo) DeleteFirewallRecord(fType, port, protocol, address, strategy string) error {
|
||||
return global.DB.Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", fType, port, protocol, address, strategy).Delete(&model.Firewall{}).Error
|
||||
}
|
||||
|
||||
func (u *HostRepo) GetCert(opts ...DBOption) (model.RootCert, error) {
|
||||
var cert model.RootCert
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&cert).Error
|
||||
return cert, err
|
||||
}
|
||||
|
||||
func (u *HostRepo) PageCert(page, size int, opts ...DBOption) (int64, []model.RootCert, error) {
|
||||
var ops []model.RootCert
|
||||
db := global.DB.Model(&model.RootCert{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&ops).Error
|
||||
return count, ops, err
|
||||
}
|
||||
|
||||
func (u *HostRepo) ListCert(opts ...DBOption) ([]model.RootCert, error) {
|
||||
var ops []model.RootCert
|
||||
db := global.DB.Model(&model.RootCert{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Find(&ops).Error
|
||||
return ops, err
|
||||
}
|
||||
|
||||
func (u *HostRepo) CreateCert(cert *model.RootCert) error {
|
||||
return global.DB.Create(cert).Error
|
||||
}
|
||||
|
||||
func (u *HostRepo) UpdateCert(id uint, vars map[string]interface{}) error {
|
||||
return global.DB.Model(&model.RootCert{}).Where("id = ?", id).Updates(vars).Error
|
||||
}
|
||||
|
||||
func (u *HostRepo) DeleteCert(opts ...DBOption) error {
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
return db.Delete(&model.RootCert{}).Error
|
||||
}
|
||||
|
||||
func (u *HostRepo) SyncCert(data []model.RootCert) error {
|
||||
tx := global.DB.Begin()
|
||||
var oldCerts []model.RootCert
|
||||
_ = tx.Where("1 = ?", 1).Find(&oldCerts).Error
|
||||
oldCertsMap := make(map[string]uint)
|
||||
for _, item := range oldCerts {
|
||||
oldCertsMap[item.Name] = item.ID
|
||||
}
|
||||
for _, item := range data {
|
||||
if _, ok := oldCertsMap[item.Name]; ok {
|
||||
delete(oldCertsMap, item.Name)
|
||||
continue
|
||||
}
|
||||
item.PassPhrase, _ = encrypt.StringEncrypt("<UN-SET>")
|
||||
if err := tx.Model(model.RootCert{}).Create(&item).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, val := range oldCertsMap {
|
||||
if err := tx.Where("id = ?", val).Delete(&model.RootCert{}).Error; err != nil {
|
||||
tx.Rollback()
|
||||
return err
|
||||
}
|
||||
}
|
||||
tx.Commit()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ type IRuntimeRepo interface {
|
||||
WithNotId(id uint) DBOption
|
||||
WithStatus(status string) DBOption
|
||||
WithDetailId(id uint) DBOption
|
||||
WithDetailIdsIn(ids []uint) DBOption
|
||||
WithPort(port int) DBOption
|
||||
WithNormalStatus(status string) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
|
||||
@@ -55,6 +56,12 @@ func (r *RuntimeRepo) WithDetailId(id uint) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) WithDetailIdsIn(ids []uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_detail_id in(?) ", ids)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) WithNotId(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id != ?", id)
|
||||
|
||||
@@ -19,6 +19,7 @@ type ITagRepo interface {
|
||||
DeleteByID(ctx context.Context, id uint) error
|
||||
Create(ctx context.Context, tag *model.Tag) error
|
||||
Save(ctx context.Context, tag *model.Tag) error
|
||||
GetByKey(key string) (*model.Tag, error)
|
||||
}
|
||||
|
||||
func NewITagRepo() ITagRepo {
|
||||
@@ -41,6 +42,14 @@ func (t TagRepo) All() ([]model.Tag, error) {
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
func (t TagRepo) GetByKey(key string) (*model.Tag, error) {
|
||||
var tag model.Tag
|
||||
if err := getDb().Where("key = ?", key).First(&tag).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &tag, nil
|
||||
}
|
||||
|
||||
func (t TagRepo) GetByIds(ids []uint) ([]model.Tag, error) {
|
||||
var tags []model.Tag
|
||||
if err := getDb().Where("id in (?)", ids).Find(&tags).Error; err != nil {
|
||||
|
||||
@@ -19,6 +19,8 @@ type IWebsiteRepo interface {
|
||||
WithRuntimeID(runtimeID uint) DBOption
|
||||
WithParentID(websiteID uint) DBOption
|
||||
WithType(websiteType string) DBOption
|
||||
WithDBType(dbType string) DBOption
|
||||
WithDBID(dbID uint) DBOption
|
||||
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.Website, error)
|
||||
List(opts ...DBOption) ([]model.Website, error)
|
||||
@@ -100,6 +102,18 @@ func (w *WebsiteRepo) WithType(websiteType string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WebsiteRepo) WithDBType(dbType string) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("db_type = ?", dbType)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WebsiteRepo) WithDBID(dbID uint) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("db_id = ?", dbID)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WebsiteRepo) Page(page, size int, opts ...DBOption) (int64, []model.Website, error) {
|
||||
var websites []model.Website
|
||||
db := getDb(opts...).Model(&model.Website{})
|
||||
|
||||
@@ -17,6 +17,7 @@ type ISSLRepo interface {
|
||||
WithByDnsAccountId(dnsAccountId uint) DBOption
|
||||
WithByCAID(caID uint) DBOption
|
||||
WithByDomain(domain string) DBOption
|
||||
WithByMasterSSLID(sslID uint) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.WebsiteSSL, error)
|
||||
GetFirst(opts ...DBOption) (*model.WebsiteSSL, error)
|
||||
List(opts ...DBOption) ([]model.WebsiteSSL, error)
|
||||
@@ -52,12 +53,19 @@ func (w WebsiteSSLRepo) WithByCAID(caID uint) DBOption {
|
||||
return db.Where("ca_id = ?", caID)
|
||||
}
|
||||
}
|
||||
|
||||
func (w WebsiteSSLRepo) WithByDomain(domain string) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("primary_domain Like ? or domains Like ?", "%"+domain+"%", "%"+domain+"%")
|
||||
}
|
||||
}
|
||||
|
||||
func (w WebsiteSSLRepo) WithByMasterSSLID(sslID uint) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("master_ssl_id = ?", sslID)
|
||||
}
|
||||
}
|
||||
|
||||
func (w WebsiteSSLRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebsiteSSL, error) {
|
||||
var sslList []model.WebsiteSSL
|
||||
db := getDb(opts...).Model(&model.WebsiteSSL{})
|
||||
|
||||
@@ -0,0 +1,555 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/copier"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/email"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
|
||||
"github.com/shirou/gopsutil/v4/disk"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AlertService struct{}
|
||||
|
||||
type IAlertService interface {
|
||||
PageAlert(req dto.AlertSearch) (int64, []dto.AlertDTO, error)
|
||||
GetAlerts() ([]dto.AlertDTO, error)
|
||||
CreateAlert(create dto.AlertCreate) error
|
||||
UpdateAlert(req dto.AlertUpdate) error
|
||||
DeleteAlert(id uint) error
|
||||
GetAlert(id uint) (dto.AlertDTO, error)
|
||||
UpdateStatus(id uint, status string) error
|
||||
ExternalUpdateAlert(req dto.AlertCreate) error
|
||||
|
||||
GetDisks() ([]dto.DiskDTO, error)
|
||||
PageAlertLogs(req dto.AlertLogSearch) (int64, []dto.AlertLogDTO, error)
|
||||
CleanAlertLogs() error
|
||||
GetClams() ([]dto.ClamDTO, error)
|
||||
GetCronJobs(req dto.CronJobReq) ([]dto.CronJobDTO, error)
|
||||
|
||||
GetAlertConfig() ([]model.AlertConfig, error)
|
||||
UpdateAlertConfig(req dto.AlertConfigUpdate) error
|
||||
DeleteAlertConfig(id uint) error
|
||||
TestAlertConfig(req dto.AlertConfigTest) (bool, error)
|
||||
}
|
||||
|
||||
func NewIAlertService() IAlertService {
|
||||
return &AlertService{}
|
||||
}
|
||||
|
||||
func (a AlertService) PageAlert(search dto.AlertSearch) (int64, []dto.AlertDTO, error) {
|
||||
var (
|
||||
opts []repo.DBOption
|
||||
result []dto.AlertDTO
|
||||
)
|
||||
if search.Status != "" {
|
||||
opts = append(opts, repo.WithByStatus(search.Status))
|
||||
}
|
||||
if search.Type != "" {
|
||||
opts = append(opts, alertRepo.WithByType(search.Type))
|
||||
}
|
||||
opts = append(opts, repo.WithOrderBy("created_at desc"))
|
||||
|
||||
total, alerts, err := alertRepo.Page(search.Page, search.PageSize, opts...)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
for _, item := range alerts {
|
||||
|
||||
result = append(result, dto.AlertDTO{
|
||||
ID: item.ID,
|
||||
Type: item.Type,
|
||||
Cycle: item.Cycle,
|
||||
Count: item.Count,
|
||||
Method: item.Method,
|
||||
Title: item.Title,
|
||||
Project: item.Project,
|
||||
Status: item.Status,
|
||||
SendCount: item.SendCount,
|
||||
AdvancedParams: item.AdvancedParams,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
return total, result, err
|
||||
}
|
||||
|
||||
func (a AlertService) GetAlerts() ([]dto.AlertDTO, error) {
|
||||
var (
|
||||
opts []repo.DBOption
|
||||
result []dto.AlertDTO
|
||||
)
|
||||
opts = append(opts, repo.WithByStatus(constant.AlertEnable))
|
||||
alerts, err := alertRepo.List(opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range alerts {
|
||||
|
||||
result = append(result, dto.AlertDTO{
|
||||
ID: item.ID,
|
||||
Type: item.Type,
|
||||
Cycle: item.Cycle,
|
||||
Count: item.Count,
|
||||
Method: item.Method,
|
||||
Title: item.Title,
|
||||
Project: item.Project,
|
||||
Status: item.Status,
|
||||
SendCount: item.SendCount,
|
||||
AdvancedParams: item.AdvancedParams,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (a AlertService) CreateAlert(create dto.AlertCreate) error {
|
||||
var alertID uint
|
||||
var alertInfo model.Alert
|
||||
if create.Project != "" {
|
||||
alertInfo, _ := alertRepo.Get(alertRepo.WithByType(create.Type), alertRepo.WithByProject(create.Project))
|
||||
alertID = alertInfo.ID
|
||||
} else {
|
||||
alertInfo, _ := alertRepo.Get(alertRepo.WithByType(create.Type))
|
||||
alertID = alertInfo.ID
|
||||
}
|
||||
|
||||
if alertID != 0 {
|
||||
var upAlert dto.AlertUpdate
|
||||
if err := copier.Copy(&upAlert, &create); err != nil {
|
||||
return buserr.WithErr("ErrStructTransform", err)
|
||||
}
|
||||
upAlert.ID = alertID
|
||||
err := a.UpdateAlert(upAlert)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
alertInfo.Status = constant.AlertEnable
|
||||
if err := copier.Copy(&alertInfo, &create); err != nil {
|
||||
return buserr.WithErr("ErrStructTransform", err)
|
||||
}
|
||||
|
||||
if err := alertRepo.Create(&alertInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
NewIAlertTaskHelper().InitTask(alertInfo.Type)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AlertService) UpdateAlert(req dto.AlertUpdate) error {
|
||||
|
||||
upMap := make(map[string]interface{})
|
||||
upMap["id"] = req.ID
|
||||
upMap["type"] = req.Type
|
||||
upMap["cycle"] = req.Cycle
|
||||
upMap["count"] = req.Count
|
||||
upMap["method"] = req.Method
|
||||
upMap["title"] = req.Title
|
||||
upMap["project"] = req.Project
|
||||
upMap["status"] = req.Status
|
||||
upMap["send_count"] = req.SendCount
|
||||
upMap["advanced_params"] = req.AdvancedParams
|
||||
|
||||
if err := alertRepo.Update(upMap, repo.WithByID(req.ID)); err != nil {
|
||||
return err
|
||||
}
|
||||
NewIAlertTaskHelper().InitTask(req.Type)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AlertService) DeleteAlert(id uint) error {
|
||||
alertInfo, _ := alertRepo.Get(repo.WithByID(id))
|
||||
if alertInfo.ID == 0 {
|
||||
return buserr.New("ErrRecordNotFound")
|
||||
}
|
||||
err := alertRepo.Delete(repo.WithByID(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
alerts, err := a.GetAlerts()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(alerts) > 0 {
|
||||
NewIAlertTaskHelper().InitTask(alertInfo.Type)
|
||||
} else {
|
||||
NewIAlertTaskHelper().StopTask()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AlertService) GetAlert(id uint) (dto.AlertDTO, error) {
|
||||
var res dto.AlertDTO
|
||||
alertInfo, err := alertRepo.Get(repo.WithByID(id))
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
_ = copier.Copy(&res, &alertInfo)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (a AlertService) UpdateStatus(id uint, status string) error {
|
||||
alertInfo, _ := alertRepo.Get(repo.WithByID(id))
|
||||
if alertInfo.ID == 0 {
|
||||
return buserr.New("ErrRecordNotFound")
|
||||
}
|
||||
err := alertRepo.Update(map[string]interface{}{"status": status}, repo.WithByID(alertInfo.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
alerts, err := a.GetAlerts()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(alerts) > 0 {
|
||||
NewIAlertTaskHelper().InitTask(alertInfo.Type)
|
||||
} else {
|
||||
NewIAlertTaskHelper().StopTask()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AlertService) GetDisks() ([]dto.DiskDTO, error) {
|
||||
var disks []dto.DiskDTO
|
||||
excludes := map[string]struct{}{
|
||||
"/mnt/cdrom": {}, "/boot": {}, "/boot/efi": {}, "/dev": {}, "/dev/shm": {},
|
||||
"/run/lock": {}, "/run": {}, "/run/shm": {}, "/run/user": {},
|
||||
}
|
||||
stdout, err := executeDiskCommand()
|
||||
if err != nil {
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
lines := strings.Split(stdout, "\n")
|
||||
var mounts []dto.AlertDiskInfo
|
||||
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 7 {
|
||||
continue
|
||||
}
|
||||
mountPoint := strings.Join(fields[6:], " ")
|
||||
if shouldExclude(fields, mountPoint, excludes) {
|
||||
continue
|
||||
}
|
||||
mounts = append(mounts, dto.AlertDiskInfo{Type: fields[1], Device: fields[0], Mount: mountPoint})
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
mu sync.Mutex
|
||||
)
|
||||
wg.Add(len(mounts))
|
||||
for i := 0; i < len(mounts); i++ {
|
||||
go func(timeoutCh <-chan time.Time, mount dto.AlertDiskInfo) {
|
||||
defer wg.Done()
|
||||
|
||||
var itemData dto.DiskDTO
|
||||
itemData.Path = mount.Mount
|
||||
itemData.Type = mount.Type
|
||||
itemData.Device = mount.Device
|
||||
select {
|
||||
case <-timeoutCh:
|
||||
mu.Lock()
|
||||
disks = append(disks, itemData)
|
||||
mu.Unlock()
|
||||
global.LOG.Errorf("load disk info from %s failed, err: timeout", mount.Mount)
|
||||
default:
|
||||
state, err := disk.Usage(mount.Mount)
|
||||
if err != nil {
|
||||
mu.Lock()
|
||||
disks = append(disks, itemData)
|
||||
mu.Unlock()
|
||||
global.LOG.Errorf("load disk info from %s failed, err: %v", mount.Mount, err)
|
||||
return
|
||||
}
|
||||
itemData.Total = state.Total
|
||||
itemData.Free = state.Free
|
||||
itemData.Used = state.Used
|
||||
itemData.UsedPercent = state.UsedPercent
|
||||
itemData.InodesTotal = state.InodesTotal
|
||||
itemData.InodesUsed = state.InodesUsed
|
||||
itemData.InodesFree = state.InodesFree
|
||||
itemData.InodesUsedPercent = state.InodesUsedPercent
|
||||
mu.Lock()
|
||||
disks = append(disks, itemData)
|
||||
mu.Unlock()
|
||||
}
|
||||
}(time.After(5*time.Second), mounts[i])
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
sort.Slice(disks, func(i, j int) bool {
|
||||
return disks[i].Path < disks[j].Path
|
||||
})
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
func executeDiskCommand() (string, error) {
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(2 * time.Second))
|
||||
stdout, err := cmdMgr.RunWithStdoutBashC("df -hT -P | grep '/' | grep -v tmpfs | grep -v 'snap/core' | grep -v udev")
|
||||
if err != nil {
|
||||
cmdMgr2 := cmd.NewCommandMgr(cmd.WithTimeout(1 * time.Second))
|
||||
stdout, err = cmdMgr2.RunWithStdoutBashC("df -lhT -P | grep '/' | grep -v tmpfs | grep -v 'snap/core' | grep -v udev")
|
||||
}
|
||||
return stdout, err
|
||||
}
|
||||
|
||||
func shouldExclude(fields []string, mountPoint string, excludes map[string]struct{}) bool {
|
||||
if strings.HasPrefix(mountPoint, "/snap") || len(strings.Split(mountPoint, "/")) > 10 {
|
||||
return true
|
||||
}
|
||||
if strings.TrimSpace(fields[1]) == "tmpfs" {
|
||||
return true
|
||||
}
|
||||
if strings.Contains(fields[2], "K") {
|
||||
return true
|
||||
}
|
||||
if strings.Contains(mountPoint, "docker") {
|
||||
return true
|
||||
}
|
||||
_, excluded := excludes[mountPoint]
|
||||
return excluded
|
||||
}
|
||||
|
||||
func (a AlertService) PageAlertLogs(search dto.AlertLogSearch) (int64, []dto.AlertLogDTO, error) {
|
||||
var (
|
||||
opts []repo.DBOption
|
||||
result []dto.AlertLogDTO
|
||||
)
|
||||
if search.Status != "" {
|
||||
opts = append(opts, repo.WithByStatus(search.Status))
|
||||
}
|
||||
if search.Count != 0 {
|
||||
opts = append(opts, alertRepo.WithByCount(search.Count))
|
||||
}
|
||||
opts = append(opts, repo.WithOrderBy("created_at desc"))
|
||||
|
||||
total, alerts, err := alertRepo.PageLog(search.Page, search.PageSize, opts...)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
for _, item := range alerts {
|
||||
alertLogDTO, err := a.parseAlertLog(item)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
result = append(result, alertLogDTO)
|
||||
}
|
||||
|
||||
return total, result, err
|
||||
}
|
||||
|
||||
func (a AlertService) parseAlertLog(item model.AlertLog) (dto.AlertLogDTO, error) {
|
||||
var alertDetail dto.AlertDetail
|
||||
var alertRule dto.AlertRule
|
||||
|
||||
if err := unmarshalAlertInfo(item.AlertDetail, &alertDetail); err != nil {
|
||||
return dto.AlertLogDTO{}, err
|
||||
}
|
||||
if err := unmarshalAlertInfo(item.AlertRule, &alertRule); err != nil {
|
||||
return dto.AlertLogDTO{}, err
|
||||
}
|
||||
return dto.AlertLogDTO{
|
||||
ID: item.ID,
|
||||
Count: item.Count,
|
||||
Type: item.Type,
|
||||
Status: item.Status,
|
||||
Method: item.Method,
|
||||
Message: item.Message,
|
||||
AlertId: item.AlertId,
|
||||
AlertDetail: alertDetail,
|
||||
AlertRule: alertRule,
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func unmarshalAlertInfo(data string, v interface{}) error {
|
||||
if err := json.Unmarshal([]byte(data), v); err != nil {
|
||||
return fmt.Errorf("unmarshal alert info vars failed, err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AlertService) CleanAlertLogs() error {
|
||||
return alertRepo.CleanAlertLogs()
|
||||
}
|
||||
|
||||
func (a AlertService) GetClams() ([]dto.ClamDTO, error) {
|
||||
var clams []dto.ClamDTO
|
||||
clamList, err := clamRepo.List()
|
||||
|
||||
for _, clam := range clamList {
|
||||
var clamDTO dto.ClamDTO
|
||||
clamDTO.ID = clam.ID
|
||||
clamDTO.Name = clam.Name
|
||||
clamDTO.Path = clam.Path
|
||||
clamDTO.Status = clam.Status
|
||||
clamDTO.UpdatedAt = clam.UpdatedAt
|
||||
clamDTO.CreatedAt = clam.CreatedAt
|
||||
clams = append(clams, clamDTO)
|
||||
}
|
||||
return clams, err
|
||||
}
|
||||
|
||||
func (a AlertService) GetCronJobs(req dto.CronJobReq) ([]dto.CronJobDTO, error) {
|
||||
var cronJobs []dto.CronJobDTO
|
||||
var (
|
||||
opts []repo.DBOption
|
||||
)
|
||||
if req.Status != "" {
|
||||
opts = append(opts, repo.WithByStatus(req.Status))
|
||||
}
|
||||
if req.Type != "" {
|
||||
opts = append(opts, repo.WithByType(req.Type))
|
||||
}
|
||||
cronjobList, err := cronjobRepo.List(opts...)
|
||||
|
||||
for _, cronJob := range cronjobList {
|
||||
var cronJobDTO dto.CronJobDTO
|
||||
cronJobDTO.ID = cronJob.ID
|
||||
cronJobDTO.Name = cronJob.Name
|
||||
cronJobDTO.Status = cronJob.Status
|
||||
cronJobDTO.Type = cronJob.Type
|
||||
cronJobDTO.UpdatedAt = cronJob.UpdatedAt
|
||||
cronJobDTO.CreatedAt = cronJob.CreatedAt
|
||||
cronJobs = append(cronJobs, cronJobDTO)
|
||||
}
|
||||
return cronJobs, err
|
||||
}
|
||||
|
||||
func (a AlertService) GetAlertConfig() ([]model.AlertConfig, error) {
|
||||
var (
|
||||
opts []repo.DBOption
|
||||
configs []model.AlertConfig
|
||||
)
|
||||
opts = append(opts, repo.WithByStatus(constant.AlertEnable))
|
||||
configs, err := alertRepo.AlertConfigList(opts...)
|
||||
return configs, err
|
||||
}
|
||||
|
||||
func (a AlertService) UpdateAlertConfig(req dto.AlertConfigUpdate) error {
|
||||
if req.ID != 0 {
|
||||
upMap := make(map[string]interface{})
|
||||
upMap["id"] = req.ID
|
||||
upMap["type"] = req.Type
|
||||
upMap["title"] = req.Title
|
||||
upMap["status"] = req.Status
|
||||
upMap["config"] = req.Config
|
||||
if err := alertRepo.UpdateAlertConfig(upMap, repo.WithByID(req.ID)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
var alertConfig model.AlertConfig
|
||||
if err := copier.Copy(&alertConfig, &req); err != nil {
|
||||
return buserr.WithErr("ErrStructTransform", err)
|
||||
}
|
||||
if err := alertRepo.CreateAlertConfig(&alertConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a AlertService) DeleteAlertConfig(id uint) error {
|
||||
return alertRepo.DeleteAlertConfig(repo.WithByID(id))
|
||||
}
|
||||
|
||||
func (a AlertService) TestAlertConfig(req dto.AlertConfigTest) (bool, error) {
|
||||
cfg := email.SMTPConfig{
|
||||
Host: req.Host,
|
||||
Port: req.Port,
|
||||
Username: req.Sender,
|
||||
Password: req.Password,
|
||||
From: fmt.Sprintf("%s <%s>", req.DisplayName, req.Sender),
|
||||
Encryption: req.Encryption,
|
||||
Recipient: req.Recipient,
|
||||
}
|
||||
|
||||
msg := email.EmailMessage{
|
||||
Subject: i18n.GetMsgByKey("TestAlertTitle"),
|
||||
Body: i18n.GetMsgByKey("TestAlert"),
|
||||
IsHTML: false,
|
||||
}
|
||||
transport := xpack.LoadRequestTransport()
|
||||
if err := email.SendMail(cfg, msg, transport); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (a AlertService) ExternalUpdateAlert(updateAlert dto.AlertCreate) error {
|
||||
upMap := make(map[string]interface{})
|
||||
var newStatus string
|
||||
if updateAlert.SendCount == 0 {
|
||||
newStatus = constant.AlertDisable
|
||||
} else {
|
||||
newStatus = constant.AlertEnable
|
||||
upMap["send_count"] = updateAlert.SendCount
|
||||
if updateAlert.Method != "" {
|
||||
upMap["method"] = updateAlert.Method
|
||||
}
|
||||
}
|
||||
upMap["status"] = newStatus
|
||||
|
||||
alertInfo, _ := alertRepo.Get(
|
||||
alertRepo.WithByType(updateAlert.Type),
|
||||
alertRepo.WithByProject(updateAlert.Project),
|
||||
)
|
||||
|
||||
if alertInfo.ID > 0 {
|
||||
shouldUpdate := false
|
||||
|
||||
if alertInfo.Status != newStatus {
|
||||
shouldUpdate = true
|
||||
}
|
||||
if val, ok := upMap["send_count"]; ok && val != alertInfo.SendCount {
|
||||
shouldUpdate = true
|
||||
}
|
||||
if val, ok := upMap["method"]; ok && val != "" && val != alertInfo.Method {
|
||||
shouldUpdate = true
|
||||
}
|
||||
|
||||
if shouldUpdate {
|
||||
if err := alertRepo.Update(
|
||||
upMap,
|
||||
alertRepo.WithByProject(updateAlert.Project),
|
||||
alertRepo.WithByType(updateAlert.Type),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if updateAlert.Method != "" && updateAlert.Title != "" {
|
||||
updateAlert.Status = newStatus
|
||||
if err := a.CreateAlert(updateAlert); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,889 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
alertUtil "github.com/1Panel-dev/1Panel/agent/utils/alert"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/common"
|
||||
versionUtil "github.com/1Panel-dev/1Panel/agent/utils/version"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
|
||||
"github.com/shirou/gopsutil/v4/cpu"
|
||||
"github.com/shirou/gopsutil/v4/disk"
|
||||
"github.com/shirou/gopsutil/v4/load"
|
||||
"github.com/shirou/gopsutil/v4/mem"
|
||||
"github.com/shirou/gopsutil/v4/net"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
ResourceAlertInterval = 30
|
||||
CheckIntervalSec = 3
|
||||
LoadCheckIntervalMin = 5
|
||||
)
|
||||
|
||||
type AlertTaskHelper struct {
|
||||
DiskIO chan []disk.IOCountersStat
|
||||
NetIO chan []net.IOCountersStat
|
||||
}
|
||||
|
||||
type IAlertTaskHelper interface {
|
||||
StopTask()
|
||||
StartTask()
|
||||
ResetTask()
|
||||
InitTask(alertType string)
|
||||
}
|
||||
|
||||
var cpuLoad1, cpuLoad5, cpuLoad15 []float64
|
||||
var memoryLoad1, memoryLoad5, memoryLoad15 []float64
|
||||
|
||||
var baseTypes = map[string]bool{"ssl": true, "siteEndTime": true, "panelPwdEndTime": true, "panelUpdate": true}
|
||||
var resourceTypes = map[string]bool{"cpu": true, "memory": true, "disk": true, "load": true, "panelLogin": true, "sshLogin": true, "nodeException": true, "licenseException": true}
|
||||
|
||||
func NewIAlertTaskHelper() IAlertTaskHelper {
|
||||
return &AlertTaskHelper{
|
||||
DiskIO: make(chan []disk.IOCountersStat, 1),
|
||||
NetIO: make(chan []net.IOCountersStat, 1),
|
||||
}
|
||||
}
|
||||
func (m *AlertTaskHelper) StartTask() {
|
||||
baseAlert, resourceAlert := m.getClassifiedAlerts()
|
||||
if len(baseAlert) == 0 && len(resourceAlert) == 0 {
|
||||
return
|
||||
}
|
||||
handleBaseAlerts(baseAlert)
|
||||
handleResourceAlerts(resourceAlert)
|
||||
}
|
||||
|
||||
func (m *AlertTaskHelper) StopTask() {
|
||||
stopBaseJob()
|
||||
stopResourceJob()
|
||||
}
|
||||
|
||||
func (m *AlertTaskHelper) ResetTask() {
|
||||
m.StopTask()
|
||||
m.StartTask()
|
||||
}
|
||||
|
||||
func (m *AlertTaskHelper) InitTask(alertType string) {
|
||||
resetAlertState(alertType)
|
||||
if baseTypes[alertType] {
|
||||
stopBaseJob()
|
||||
} else if resourceTypes[alertType] {
|
||||
stopResourceJob()
|
||||
}
|
||||
m.StartTask()
|
||||
}
|
||||
|
||||
func resetAlertState(alertType string) {
|
||||
switch alertType {
|
||||
case "cpu":
|
||||
cpuLoad1 = []float64{}
|
||||
cpuLoad5 = []float64{}
|
||||
cpuLoad15 = []float64{}
|
||||
case "memory":
|
||||
memoryLoad1 = []float64{}
|
||||
memoryLoad5 = []float64{}
|
||||
memoryLoad15 = []float64{}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *AlertTaskHelper) getClassifiedAlerts() (baseAlerts, resourceAlerts []dto.AlertDTO) {
|
||||
alertList, _ := NewIAlertService().GetAlerts()
|
||||
for _, alert := range alertList {
|
||||
if baseTypes[alert.Type] {
|
||||
baseAlerts = append(baseAlerts, alert)
|
||||
} else if resourceTypes[alert.Type] {
|
||||
resourceAlerts = append(resourceAlerts, alert)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func handleBaseAlerts(baseAlerts []dto.AlertDTO) {
|
||||
if len(baseAlerts) == 0 {
|
||||
stopResourceJob()
|
||||
return
|
||||
}
|
||||
if global.AlertBaseJobID == 0 {
|
||||
baseTask(baseAlerts)
|
||||
jobID, err := global.Cron.AddFunc("*/30 * * * *", func() {
|
||||
baseTask(baseAlerts)
|
||||
})
|
||||
if err != nil {
|
||||
global.LOG.Errorf("alert base job start failed: %v", err)
|
||||
return
|
||||
}
|
||||
global.AlertBaseJobID = jobID
|
||||
global.LOG.Info("start alert base job")
|
||||
}
|
||||
}
|
||||
|
||||
func handleResourceAlerts(resourceAlerts []dto.AlertDTO) {
|
||||
if len(resourceAlerts) == 0 {
|
||||
stopResourceJob()
|
||||
return
|
||||
}
|
||||
if global.AlertResourceJobID == 0 {
|
||||
jobID, err := global.Cron.AddFunc("*/1 * * * *", func() {
|
||||
resourceTask(resourceAlerts)
|
||||
})
|
||||
if err != nil {
|
||||
global.LOG.Errorf("alert resource job start failed: %v", err)
|
||||
return
|
||||
}
|
||||
global.AlertResourceJobID = jobID
|
||||
global.LOG.Info("start alert resource job")
|
||||
}
|
||||
}
|
||||
|
||||
func stopBaseJob() {
|
||||
if global.AlertBaseJobID != 0 {
|
||||
global.Cron.Remove(global.AlertBaseJobID)
|
||||
global.AlertBaseJobID = 0
|
||||
global.LOG.Info("stop alert base job")
|
||||
}
|
||||
}
|
||||
|
||||
func stopResourceJob() {
|
||||
if global.AlertResourceJobID != 0 {
|
||||
global.Cron.Remove(global.AlertResourceJobID)
|
||||
global.AlertResourceJobID = 0
|
||||
global.LOG.Info("stop alert resource job")
|
||||
}
|
||||
}
|
||||
|
||||
func baseTask(baseAlert []dto.AlertDTO) {
|
||||
for _, alert := range baseAlert {
|
||||
if !alertUtil.CheckSendTimeRange(alert.Type) {
|
||||
continue
|
||||
}
|
||||
switch alert.Type {
|
||||
case "ssl":
|
||||
loadSSLInfo(alert)
|
||||
case "siteEndTime":
|
||||
loadWebsiteInfo(alert)
|
||||
case "panelPwdEndTime":
|
||||
if global.IsMaster {
|
||||
loadPanelPwd(alert)
|
||||
}
|
||||
case "panelUpdate":
|
||||
if global.IsMaster {
|
||||
loadPanelUpdate(alert)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resourceTask(resourceAlert []dto.AlertDTO) {
|
||||
minute := time.Now().Minute()
|
||||
for _, alert := range resourceAlert {
|
||||
if !alertUtil.CheckSendTimeRange(alert.Type) {
|
||||
continue
|
||||
}
|
||||
execute := minute%LoadCheckIntervalMin == 0
|
||||
switch alert.Type {
|
||||
case "cpu":
|
||||
loadCPUUsage(alert)
|
||||
case "memory":
|
||||
loadMemUsage(alert)
|
||||
case "load":
|
||||
loadLoadInfo(alert)
|
||||
case "disk":
|
||||
loadDiskUsage(alert)
|
||||
case "panelLogin":
|
||||
loadPanelLogin(alert)
|
||||
case "sshLogin":
|
||||
loadSSHLogin(alert)
|
||||
case "nodeException":
|
||||
if execute && global.IsMaster {
|
||||
loadNodeException(alert)
|
||||
}
|
||||
case "licenseException":
|
||||
if execute && global.IsMaster {
|
||||
loadLicenseException(alert)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadSSLInfo(alert dto.AlertDTO) {
|
||||
opts := getRepoOptionsByProject(alert.Project)
|
||||
sslList, _ := repo.NewISSLRepo().List(opts...)
|
||||
if len(sslList) == 0 {
|
||||
return
|
||||
}
|
||||
daysDiffMap, projectMap := calculateSSLExpiryDays(sslList, alert.Cycle)
|
||||
projectJSON := serializeAndSortProjects(projectMap)
|
||||
if projectJSON == "" || len(daysDiffMap) == 0 {
|
||||
return
|
||||
}
|
||||
sender := NewAlertSender(alert, projectJSON)
|
||||
for daysDiff, domains := range daysDiffMap {
|
||||
domainStr := strings.Join(domains, ",")
|
||||
params := createAlertBaseParams(strconv.Itoa(len(domains)), strconv.Itoa(daysDiff))
|
||||
sender.Send(domainStr, params)
|
||||
}
|
||||
}
|
||||
|
||||
func loadWebsiteInfo(alert dto.AlertDTO) {
|
||||
opts := getRepoOptionsByProject(alert.Project)
|
||||
websiteList, _ := websiteRepo.List(opts...)
|
||||
if len(websiteList) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
daysDiffMap, projectMap := calculateWebsiteExpiryDays(websiteList, alert.Cycle)
|
||||
projectJSON := serializeAndSortProjects(projectMap)
|
||||
if projectJSON == "" || len(daysDiffMap) == 0 {
|
||||
return
|
||||
}
|
||||
sender := NewAlertSender(alert, projectJSON)
|
||||
for daysDiff, domains := range daysDiffMap {
|
||||
domainStr := strings.Join(domains, ",")
|
||||
params := createAlertBaseParams(strconv.Itoa(len(domains)), strconv.Itoa(daysDiff))
|
||||
sender.Send(domainStr, params)
|
||||
}
|
||||
}
|
||||
|
||||
func loadPanelPwd(alert dto.AlertDTO) {
|
||||
// only master alert
|
||||
expDays, err := getSettingValue("ExpirationDays")
|
||||
if err != nil || expDays == "0" {
|
||||
global.LOG.Info("panel password expiration setting not enabled, skip")
|
||||
return
|
||||
}
|
||||
|
||||
expTimeStr, err := getSettingValue("ExpirationTime")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
expTime, _ := time.Parse(constant.DateTimeLayout, expTimeStr)
|
||||
daysDiff := calculateDaysDifference(expTime)
|
||||
if daysDiff >= 0 && int(alert.Cycle) >= daysDiff {
|
||||
params := createAlertPwdParams(strconv.Itoa(daysDiff))
|
||||
sender := NewAlertSender(alert, expTimeStr)
|
||||
sender.Send(strconv.Itoa(daysDiff), params)
|
||||
}
|
||||
}
|
||||
|
||||
func loadPanelUpdate(alert dto.AlertDTO) {
|
||||
// only master alert
|
||||
info, err := versionUtil.GetUpgradeVersionInfo()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting version info: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
version := getValidVersion(info)
|
||||
if version == "" {
|
||||
return
|
||||
}
|
||||
|
||||
sender := NewAlertSender(alert, version)
|
||||
sender.Send(version, []dto.Param{})
|
||||
}
|
||||
|
||||
// 获取 CPU 使用率数据并发送到通道
|
||||
func loadCPUUsage(alert dto.AlertDTO) {
|
||||
percent, err := cpu.Percent(time.Duration(CheckIntervalSec)*time.Second, false)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting cpu usage, err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(percent) > 0 {
|
||||
var usageLoad *[]float64
|
||||
var threshold int
|
||||
|
||||
switch alert.Cycle {
|
||||
case 1:
|
||||
usageLoad = &cpuLoad1
|
||||
threshold = 1
|
||||
case 5:
|
||||
usageLoad = &cpuLoad5
|
||||
threshold = 5
|
||||
case 15:
|
||||
usageLoad = &cpuLoad15
|
||||
threshold = 15
|
||||
}
|
||||
shouldSendResourceAlert(alert, percent[0], usageLoad, threshold)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取内存使用情况数据并发送到通道
|
||||
func loadMemUsage(alert dto.AlertDTO) {
|
||||
memStat, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting memory usage, err: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
percent := memStat.UsedPercent
|
||||
var memoryLoad *[]float64
|
||||
var threshold int
|
||||
|
||||
switch alert.Cycle {
|
||||
case 1:
|
||||
memoryLoad = &memoryLoad1
|
||||
threshold = 1
|
||||
case 5:
|
||||
memoryLoad = &memoryLoad5
|
||||
threshold = 5
|
||||
case 15:
|
||||
memoryLoad = &memoryLoad15
|
||||
threshold = 15
|
||||
}
|
||||
shouldSendResourceAlert(alert, percent, memoryLoad, threshold)
|
||||
}
|
||||
|
||||
// 获取系统负载数据并发送到通道
|
||||
func loadLoadInfo(alert dto.AlertDTO) {
|
||||
avgStat, err := load.Avg()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting load usage, err: %v", err)
|
||||
return
|
||||
}
|
||||
var loadValue float64
|
||||
CPUTotal, _ := cpu.Counts(true)
|
||||
switch alert.Cycle {
|
||||
case 1:
|
||||
loadValue = avgStat.Load1 / (float64(CPUTotal*2) * 0.75) * 100
|
||||
case 5:
|
||||
loadValue = avgStat.Load5 / (float64(CPUTotal*2) * 0.75) * 100
|
||||
case 15:
|
||||
loadValue = avgStat.Load15 / (float64(CPUTotal*2) * 0.75) * 100
|
||||
default:
|
||||
return
|
||||
}
|
||||
if loadValue < float64(alert.Count) {
|
||||
return
|
||||
}
|
||||
newDate, err := alertRepo.GetTaskLog(alert.Type, alert.ID)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("task log record not found, err: %v", err)
|
||||
}
|
||||
if isAlertDue(newDate) {
|
||||
sendResourceAlert(alert, loadValue)
|
||||
}
|
||||
}
|
||||
|
||||
func loadDiskUsage(alert dto.AlertDTO) {
|
||||
newDate, err := alertRepo.GetTaskLog(alert.Type, alert.ID)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("record not found, err: %v", err)
|
||||
return
|
||||
}
|
||||
if isAlertDue(newDate) {
|
||||
if strings.Contains(alert.Project, "all") {
|
||||
err = processAllDisks(alert)
|
||||
} else {
|
||||
err = processSingleDisk(alert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadPanelLogin(alert dto.AlertDTO) {
|
||||
count, isAlert, err := alertUtil.CountRecentFailedLoginLogs(alert.Cycle, alert.Count)
|
||||
alertType := alert.Type
|
||||
quota := strconv.Itoa(count)
|
||||
quotaType := strconv.Itoa(int(alert.Cycle))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("Failed to count recent failed login logs: %v", err)
|
||||
}
|
||||
if isAlert {
|
||||
alertType = "panelLogin"
|
||||
quota = strconv.Itoa(count)
|
||||
quotaType = "panelLogin"
|
||||
params := []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "cycle",
|
||||
Value: "",
|
||||
},
|
||||
{
|
||||
Index: "2",
|
||||
Key: "project",
|
||||
Value: "",
|
||||
},
|
||||
}
|
||||
sendAlerts(alert, alertType, quota, quotaType, params)
|
||||
}
|
||||
|
||||
whitelist := strings.Split(strings.TrimSpace(alert.AdvancedParams), "\n")
|
||||
records, err := alertUtil.FindRecentSuccessLoginsNotInWhitelist(30, whitelist)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("Failed to check recent failed ip login logs: %v", err)
|
||||
}
|
||||
if len(records) > 0 {
|
||||
quota = strings.Join(func() []string {
|
||||
var ips []string
|
||||
for _, r := range records {
|
||||
ips = append(ips, r.IP)
|
||||
}
|
||||
return ips
|
||||
}(), "\n")
|
||||
alertType = "panelIpLogin"
|
||||
quotaType = "panelIpLogin"
|
||||
params := []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "cycle",
|
||||
Value: "",
|
||||
},
|
||||
{
|
||||
Index: "2",
|
||||
Key: "project",
|
||||
Value: " IP ",
|
||||
},
|
||||
}
|
||||
sendAlerts(alert, alertType, quota, quotaType, params)
|
||||
}
|
||||
}
|
||||
|
||||
func loadSSHLogin(alert dto.AlertDTO) {
|
||||
count, isAlert, err := alertUtil.CountRecentFailedSSHLog(alert.Cycle, alert.Count)
|
||||
alertType := alert.Type
|
||||
quota := strconv.Itoa(count)
|
||||
quotaType := strconv.Itoa(int(alert.Cycle))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("Failed to count recent failed ssh login logs: %v", err)
|
||||
}
|
||||
if isAlert {
|
||||
alertType = "sshLogin"
|
||||
quota = strconv.Itoa(count)
|
||||
quotaType = "sshLogin"
|
||||
params := []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "cycle",
|
||||
Value: " SSH ",
|
||||
},
|
||||
{
|
||||
Index: "2",
|
||||
Key: "project",
|
||||
Value: "",
|
||||
},
|
||||
}
|
||||
sendAlerts(alert, alertType, quota, quotaType, params)
|
||||
}
|
||||
whitelist := strings.Split(strings.TrimSpace(alert.AdvancedParams), "\n")
|
||||
records, err := alertUtil.FindRecentSuccessLoginNotInWhitelist(30, whitelist)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("Failed to check recent failed ip ssh login logs: %v", err)
|
||||
}
|
||||
if len(records) > 0 {
|
||||
quota = strings.Join(records, "\n")
|
||||
alertType = "sshIpLogin"
|
||||
quotaType = "sshIpLogin"
|
||||
params := []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "cycle",
|
||||
Value: " SSH ",
|
||||
},
|
||||
{
|
||||
Index: "2",
|
||||
Key: "project",
|
||||
Value: " IP ",
|
||||
},
|
||||
}
|
||||
sendAlerts(alert, alertType, quota, quotaType, params)
|
||||
}
|
||||
}
|
||||
|
||||
func loadNodeException(alert dto.AlertDTO) {
|
||||
// only master alert
|
||||
failCount, err := xpack.GetNodeErrorAlert()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting node, err: %s", err)
|
||||
return
|
||||
}
|
||||
if failCount > 0 {
|
||||
quotaType := "node-error"
|
||||
params := []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "cycle",
|
||||
Value: strconv.Itoa(int(failCount)),
|
||||
},
|
||||
}
|
||||
newDate, err := alertRepo.GetTaskLog(alert.Type, alert.ID)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("record not found, err: %v", err)
|
||||
return
|
||||
}
|
||||
if isAlertDue(newDate) {
|
||||
sender := NewAlertSender(alert, quotaType)
|
||||
sender.ResourceSend(strconv.Itoa(int(failCount)), params)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func loadLicenseException(alert dto.AlertDTO) {
|
||||
// only master alert
|
||||
failCount, err := xpack.GetLicenseErrorAlert()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting license, err: %s", err)
|
||||
return
|
||||
}
|
||||
if failCount > 0 {
|
||||
quotaType := "license-error"
|
||||
params := []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "cycle",
|
||||
Value: strconv.Itoa(int(failCount)),
|
||||
},
|
||||
}
|
||||
newDate, err := alertRepo.GetTaskLog(alert.Type, alert.ID)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("record not found, err: %v", err)
|
||||
return
|
||||
}
|
||||
if isAlertDue(newDate) {
|
||||
sender := NewAlertSender(alert, quotaType)
|
||||
sender.ResourceSend(strconv.Itoa(int(failCount)), params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendAlerts(alert dto.AlertDTO, alertType, quota, quotaType string, params []dto.Param) {
|
||||
methods := strings.Split(alert.Method, ",")
|
||||
newDate, err := alertRepo.GetTaskLog(alertType, alert.ID)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("task log record not found, err: %v", err)
|
||||
}
|
||||
if newDate.IsZero() || calculateMinutesDifference(newDate) > ResourceAlertInterval {
|
||||
for _, m := range methods {
|
||||
m = strings.TrimSpace(m)
|
||||
switch m {
|
||||
case constant.SMS:
|
||||
if !alertUtil.CheckSMSSendLimit(constant.SMS) {
|
||||
continue
|
||||
}
|
||||
todayCount, isValid := canSendAlertToday(alertType, quotaType, alert.SendCount, constant.SMS)
|
||||
if !isValid {
|
||||
continue
|
||||
}
|
||||
create := dto.AlertLogCreate{
|
||||
Type: alertType,
|
||||
AlertId: alert.ID,
|
||||
Count: todayCount + 1,
|
||||
}
|
||||
_ = xpack.CreateSMSAlertLog(alertType, alert, create, quotaType, params, constant.SMS)
|
||||
alertUtil.CreateNewAlertTask(quota, alertType, quotaType, constant.SMS)
|
||||
global.LOG.Infof("%s alert sms push successful", alertType)
|
||||
|
||||
case constant.Email:
|
||||
todayCount, isValid := canSendAlertToday(alertType, quotaType, alert.SendCount, constant.Email)
|
||||
if !isValid {
|
||||
continue
|
||||
}
|
||||
create := dto.AlertLogCreate{
|
||||
Type: alertType,
|
||||
AlertId: alert.ID,
|
||||
Count: todayCount + 1,
|
||||
}
|
||||
alertInfo := alert
|
||||
alertInfo.Type = alertType
|
||||
create.AlertRule = alertUtil.ProcessAlertRule(alert)
|
||||
create.AlertDetail = alertUtil.ProcessAlertDetail(alertInfo, quotaType, params, constant.Email)
|
||||
transport := xpack.LoadRequestTransport()
|
||||
_ = alertUtil.CreateEmailAlertLog(create, alertInfo, params, transport)
|
||||
alertUtil.CreateNewAlertTask(quota, alertType, quotaType, constant.Email)
|
||||
global.LOG.Infof("%s alert email push successful", alertType)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
func getRepoOptionsByProject(project string) []repo.DBOption {
|
||||
var opts []repo.DBOption
|
||||
if project != "all" {
|
||||
itemID, _ := strconv.Atoi(project)
|
||||
opts = append(opts, repo.WithByID(uint(itemID)))
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func serializeAndSortProjects(projectMap map[uint][]time.Time) string {
|
||||
if len(projectMap) == 0 {
|
||||
return ""
|
||||
}
|
||||
keys := make([]int, 0, len(projectMap))
|
||||
for k := range projectMap {
|
||||
keys = append(keys, int(k))
|
||||
}
|
||||
sort.Ints(keys)
|
||||
projectJSON, err := json.Marshal(projectMap)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("Failed to serialize projectMap: %v", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(projectJSON)
|
||||
}
|
||||
|
||||
func calculateSSLExpiryDays(sslList []model.WebsiteSSL, cycle uint) (map[int][]string, map[uint][]time.Time) {
|
||||
currentDate := time.Now()
|
||||
daysDiffMap := make(map[int][]string)
|
||||
projectMap := make(map[uint][]time.Time)
|
||||
|
||||
for _, ssl := range sslList {
|
||||
daysDiff := int(ssl.ExpireDate.Sub(currentDate).Hours() / 24)
|
||||
if daysDiff > 0 && int(cycle) >= daysDiff {
|
||||
daysDiffMap[daysDiff] = append(daysDiffMap[daysDiff], ssl.PrimaryDomain)
|
||||
projectMap[ssl.ID] = append(projectMap[ssl.ID], ssl.ExpireDate)
|
||||
}
|
||||
}
|
||||
return daysDiffMap, projectMap
|
||||
}
|
||||
|
||||
func calculateWebsiteExpiryDays(websites []model.Website, cycle uint) (map[int][]string, map[uint][]time.Time) {
|
||||
currentDate := time.Now()
|
||||
daysDiffMap := make(map[int][]string)
|
||||
projectMap := make(map[uint][]time.Time)
|
||||
|
||||
for _, website := range websites {
|
||||
daysDiff := int(website.ExpireDate.Sub(currentDate).Hours() / 24)
|
||||
if daysDiff > 0 && int(cycle) >= daysDiff {
|
||||
daysDiffMap[daysDiff] = append(daysDiffMap[daysDiff], website.PrimaryDomain)
|
||||
projectMap[website.ID] = append(projectMap[website.ID], website.ExpireDate)
|
||||
}
|
||||
}
|
||||
return daysDiffMap, projectMap
|
||||
}
|
||||
|
||||
func getSettingValue(key string) (string, error) {
|
||||
var setting model.Setting
|
||||
if err := global.CoreDB.Model(&model.Setting{}).Where("key = ?", key).First(&setting).Error; err != nil {
|
||||
global.LOG.Errorf("load %s from db setting failed: %v", key, err)
|
||||
return "", err
|
||||
}
|
||||
return setting.Value, nil
|
||||
}
|
||||
|
||||
func getValidVersion(info *dto.UpgradeInfo) string {
|
||||
if info.NewVersion != "" {
|
||||
return info.NewVersion
|
||||
} else if info.TestVersion != "" {
|
||||
return info.TestVersion
|
||||
} else if info.LatestVersion != "" {
|
||||
return info.LatestVersion
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func shouldSendResourceAlert(alert dto.AlertDTO, currentUsage float64, usageLoad *[]float64, threshold int) {
|
||||
newDate, err := alertRepo.GetTaskLog(alert.Type, alert.ID)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("record not found, err: %v", err)
|
||||
}
|
||||
if isAlertDue(newDate) {
|
||||
*usageLoad = append(*usageLoad, currentUsage)
|
||||
if len(*usageLoad) > threshold {
|
||||
*usageLoad = (*usageLoad)[1:]
|
||||
}
|
||||
if len(*usageLoad) == threshold {
|
||||
avgUsage := average(*usageLoad)
|
||||
if avgUsage >= float64(alert.Count) {
|
||||
sendResourceAlert(alert, avgUsage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func isAlertDue(lastAlertTime time.Time) bool {
|
||||
if lastAlertTime.IsZero() {
|
||||
return true
|
||||
}
|
||||
return calculateMinutesDifference(lastAlertTime) > ResourceAlertInterval
|
||||
}
|
||||
|
||||
func sendResourceAlert(alert dto.AlertDTO, value float64) {
|
||||
valueStr := common.FormatPercent(value)
|
||||
module := getModuleName(alert.Type)
|
||||
params := createAlertAvgParams(strconv.Itoa(int(alert.Cycle)), module, valueStr)
|
||||
sender := NewAlertSender(alert, strconv.Itoa(int(alert.Cycle)))
|
||||
sender.ResourceSend(valueStr, params)
|
||||
}
|
||||
|
||||
func getModuleName(alertType string) string {
|
||||
var module string
|
||||
switch alertType {
|
||||
case "cpu":
|
||||
module = " CPU "
|
||||
case "memory":
|
||||
module = "内存"
|
||||
case "load":
|
||||
module = "负载"
|
||||
default:
|
||||
}
|
||||
return module
|
||||
}
|
||||
|
||||
func canSendAlertToday(alertType, quotaType string, sendCount uint, method string) (uint, bool) {
|
||||
todayCount, _, err := alertRepo.LoadTaskCount(alertType, quotaType, method)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting task info, err: %v", err)
|
||||
return todayCount, false
|
||||
}
|
||||
if todayCount >= sendCount {
|
||||
return todayCount, false
|
||||
}
|
||||
|
||||
return todayCount, true
|
||||
}
|
||||
|
||||
func average(arr []float64) float64 {
|
||||
total := 0.0
|
||||
for _, v := range arr {
|
||||
total += v
|
||||
}
|
||||
return total / float64(len(arr))
|
||||
}
|
||||
|
||||
func createAlertBaseParams(project, cycle string) []dto.Param {
|
||||
return []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "project",
|
||||
Value: project,
|
||||
},
|
||||
{
|
||||
Index: "2",
|
||||
Key: "cycle",
|
||||
Value: cycle,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createAlertPwdParams(cycle string) []dto.Param {
|
||||
return []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "cycle",
|
||||
Value: cycle,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createAlertAvgParams(cycle, module, count string) []dto.Param {
|
||||
return []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "cycle",
|
||||
Value: cycle,
|
||||
},
|
||||
{
|
||||
Index: "2",
|
||||
Key: "module",
|
||||
Value: module,
|
||||
},
|
||||
{
|
||||
Index: "3",
|
||||
Key: "count",
|
||||
Value: count,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func createAlertDiskParams(project, count string) []dto.Param {
|
||||
return []dto.Param{
|
||||
{
|
||||
Index: "1",
|
||||
Key: "project",
|
||||
Value: project,
|
||||
},
|
||||
{
|
||||
Index: "2",
|
||||
Key: "count",
|
||||
Value: count,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func processAllDisks(alert dto.AlertDTO) error {
|
||||
diskList, err := NewIAlertService().GetDisks()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting disk list, err: %v", err)
|
||||
return err
|
||||
}
|
||||
for _, item := range diskList {
|
||||
if success, err := checkAndCreateDiskAlert(alert, item.Path); err == nil && success {
|
||||
global.LOG.Infof("disk alert pushed successfully for %s", item.Path)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processSingleDisk(alert dto.AlertDTO) error {
|
||||
success, err := checkAndCreateDiskAlert(alert, alert.Project)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if success {
|
||||
global.LOG.Infof("disk alert pushed successfully for %s", alert.Project)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkAndCreateDiskAlert(alert dto.AlertDTO, path string) (bool, error) {
|
||||
usageStat, err := disk.Usage(path)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting disk usage for %s, err: %v", path, err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
usedTotal, usedStr := calculateUsedTotal(alert.Cycle, usageStat)
|
||||
commonTotal := float64(alert.Count)
|
||||
if alert.Cycle == 1 {
|
||||
commonTotal *= 1024 * 1024 * 1024
|
||||
}
|
||||
if usedTotal < commonTotal {
|
||||
return false, nil
|
||||
}
|
||||
global.LOG.Infof("disk「 %s 」usage: %s", path, usedStr)
|
||||
params := createAlertDiskParams(path, usedStr)
|
||||
sender := NewAlertSender(alert, alert.Project)
|
||||
sender.ResourceSend(path, params)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func calculateUsedTotal(cycle uint, usageStat *disk.UsageStat) (float64, string) {
|
||||
if cycle == 1 {
|
||||
return float64(usageStat.Used), common.FormatBytes(usageStat.Used)
|
||||
}
|
||||
return usageStat.UsedPercent, common.FormatPercent(usageStat.UsedPercent)
|
||||
}
|
||||
|
||||
func calculateDaysDifference(expirationTime time.Time) int {
|
||||
currentDate := time.Now()
|
||||
formattedTime := currentDate.Format(constant.DateTimeLayout)
|
||||
parsedTime, _ := time.Parse(constant.DateTimeLayout, formattedTime)
|
||||
timeGap := expirationTime.Sub(parsedTime).Milliseconds()
|
||||
if timeGap < 0 {
|
||||
return -1
|
||||
}
|
||||
daysDifference := int(math.Floor(float64(timeGap) / (3600 * 1000 * 24)))
|
||||
return daysDifference
|
||||
}
|
||||
|
||||
func calculateMinutesDifference(newDate time.Time) int {
|
||||
now := time.Now()
|
||||
if newDate.After(now) {
|
||||
return -1
|
||||
}
|
||||
minutesDifference := int(now.Sub(newDate).Minutes())
|
||||
return minutesDifference
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
alertUtil "github.com/1Panel-dev/1Panel/agent/utils/alert"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type AlertSender struct {
|
||||
alert dto.AlertDTO
|
||||
quotaType string
|
||||
}
|
||||
|
||||
func NewAlertSender(alert dto.AlertDTO, quotaType string) *AlertSender {
|
||||
return &AlertSender{
|
||||
alert: alert,
|
||||
quotaType: quotaType,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AlertSender) Send(quota string, params []dto.Param) {
|
||||
methods := strings.Split(s.alert.Method, ",")
|
||||
for _, method := range methods {
|
||||
method = strings.TrimSpace(method)
|
||||
switch method {
|
||||
case constant.SMS:
|
||||
s.sendSMS(quota, params)
|
||||
case constant.Email:
|
||||
s.sendEmail(quota, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AlertSender) ResourceSend(quota string, params []dto.Param) {
|
||||
methods := strings.Split(s.alert.Method, ",")
|
||||
for _, method := range methods {
|
||||
method = strings.TrimSpace(method)
|
||||
switch method {
|
||||
case constant.SMS:
|
||||
s.sendResourceSMS(quota, params)
|
||||
case constant.Email:
|
||||
s.sendResourceEmail(quota, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendSMS(quota string, params []dto.Param) {
|
||||
if !alertUtil.CheckSMSSendLimit(constant.SMS) {
|
||||
return
|
||||
}
|
||||
|
||||
totalCount, isValid := s.canSendAlert(constant.SMS)
|
||||
if !isValid {
|
||||
return
|
||||
}
|
||||
|
||||
create := dto.AlertLogCreate{
|
||||
Status: constant.AlertSuccess,
|
||||
Count: totalCount + 1,
|
||||
AlertId: s.alert.ID,
|
||||
Type: s.alert.Type,
|
||||
}
|
||||
|
||||
_ = xpack.CreateSMSAlertLog(s.alert.Type, s.alert, create, quota, params, constant.SMS)
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, constant.SMS)
|
||||
global.LOG.Infof("%s alert sms push successful", s.alert.Type)
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendEmail(quota string, params []dto.Param) {
|
||||
totalCount, isValid := s.canSendAlert(constant.Email)
|
||||
if !isValid {
|
||||
return
|
||||
}
|
||||
|
||||
create := dto.AlertLogCreate{
|
||||
Status: constant.AlertSuccess,
|
||||
Count: totalCount + 1,
|
||||
AlertId: s.alert.ID,
|
||||
Type: s.alert.Type,
|
||||
AlertRule: alertUtil.ProcessAlertRule(s.alert),
|
||||
AlertDetail: alertUtil.ProcessAlertDetail(s.alert, quota, params, constant.Email),
|
||||
}
|
||||
|
||||
transport := xpack.LoadRequestTransport()
|
||||
_ = alertUtil.CreateEmailAlertLog(create, s.alert, params, transport)
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, constant.Email)
|
||||
global.LOG.Infof("%s alert email push successful", s.alert.Type)
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendResourceSMS(quota string, params []dto.Param) {
|
||||
if !alertUtil.CheckSMSSendLimit(constant.SMS) {
|
||||
return
|
||||
}
|
||||
|
||||
todayCount, isValid := s.canResourceSendAlert(constant.SMS)
|
||||
if !isValid {
|
||||
return
|
||||
}
|
||||
|
||||
create := dto.AlertLogCreate{
|
||||
Status: constant.AlertSuccess,
|
||||
Count: todayCount + 1,
|
||||
AlertId: s.alert.ID,
|
||||
Type: s.alert.Type,
|
||||
}
|
||||
|
||||
if err := xpack.CreateSMSAlertLog(s.alert.Type, s.alert, create, quota, params, constant.SMS); err != nil {
|
||||
global.LOG.Errorf("failed to send SMS alert: %v", err)
|
||||
return
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, constant.SMS)
|
||||
global.LOG.Infof("%s alert sms push successful", s.alert.Type)
|
||||
}
|
||||
|
||||
func (s *AlertSender) sendResourceEmail(quota string, params []dto.Param) {
|
||||
todayCount, isValid := s.canResourceSendAlert(constant.Email)
|
||||
if !isValid {
|
||||
return
|
||||
}
|
||||
|
||||
create := dto.AlertLogCreate{
|
||||
Status: constant.AlertSuccess,
|
||||
Count: todayCount + 1,
|
||||
AlertId: s.alert.ID,
|
||||
Type: s.alert.Type,
|
||||
AlertRule: alertUtil.ProcessAlertRule(s.alert),
|
||||
AlertDetail: alertUtil.ProcessAlertDetail(s.alert, quota, params, constant.Email),
|
||||
}
|
||||
|
||||
transport := xpack.LoadRequestTransport()
|
||||
if err := alertUtil.CreateEmailAlertLog(create, s.alert, params, transport); err != nil {
|
||||
global.LOG.Errorf("failed to send Email alert: %v", err)
|
||||
return
|
||||
}
|
||||
alertUtil.CreateNewAlertTask(quota, s.alert.Type, s.quotaType, constant.Email)
|
||||
global.LOG.Infof("%s alert email push successful", s.alert.Type)
|
||||
}
|
||||
|
||||
func (s *AlertSender) canSendAlert(method string) (uint, bool) {
|
||||
todayCount, totalCount, err := alertRepo.LoadTaskCount(s.alert.Type, s.quotaType, method)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting task count: %v", err)
|
||||
return totalCount, false
|
||||
}
|
||||
|
||||
if todayCount >= 1 || s.alert.SendCount <= totalCount {
|
||||
return totalCount, false
|
||||
}
|
||||
return totalCount, true
|
||||
}
|
||||
|
||||
func (s *AlertSender) canResourceSendAlert(method string) (uint, bool) {
|
||||
todayCount, _, err := alertRepo.LoadTaskCount(s.alert.Type, s.quotaType, method)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("error getting task count: %v", err)
|
||||
return todayCount, false
|
||||
}
|
||||
if s.alert.SendCount <= todayCount {
|
||||
return todayCount, false
|
||||
}
|
||||
return todayCount, true
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user