mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-10 08:00:32 +00:00
Compare commits
630
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ade1accd3f | ||
|
|
ce14a104cc | ||
|
|
2eaabccf94 | ||
|
|
e119239d3d | ||
|
|
14a57af4e9 | ||
|
|
2701af9054 | ||
|
|
4954067736 | ||
|
|
b962144e7d | ||
|
|
8f1be42b6b | ||
|
|
c6969f231b | ||
|
|
3571fb8d86 | ||
|
|
d21288788e | ||
|
|
f65e4b06ab | ||
|
|
d26bc9a3a4 | ||
|
|
7088a903fe | ||
|
|
864ebeed82 | ||
|
|
c1b2b92708 | ||
|
|
2189d9229a | ||
|
|
d0183f460e | ||
|
|
d27d6db1ea | ||
|
|
d2bb3813d9 | ||
|
|
cac73e6d45 | ||
|
|
4712ceaf2c | ||
|
|
65243c68c4 | ||
|
|
256e79ca81 | ||
|
|
4861eb69cb | ||
|
|
fb8cf15537 | ||
|
|
c4a6791271 | ||
|
|
f58e147636 | ||
|
|
387e9fbeed | ||
|
|
4eb627bc79 | ||
|
|
850c86229c | ||
|
|
f984917a66 | ||
|
|
8588217fbf | ||
|
|
a2307c5f64 | ||
|
|
5923290de8 | ||
|
|
1c994fba4a | ||
|
|
415ab96aab | ||
|
|
19bb823b05 | ||
|
|
3a5371652e | ||
|
|
a267b4148a | ||
|
|
36a01eb60d | ||
|
|
65f6fdd045 | ||
|
|
75b60b32e4 | ||
|
|
6cb65e2290 | ||
|
|
0bad1b471f | ||
|
|
3814525edd | ||
|
|
8162dd1856 | ||
|
|
e833787020 | ||
|
|
673ffac516 | ||
|
|
e864610015 | ||
|
|
78402e1b7d | ||
|
|
782bc1e67c | ||
|
|
86e4ed6f64 | ||
|
|
ee8bac39af | ||
|
|
fe742b9f41 | ||
|
|
9a5bd9bcba | ||
|
|
b9c8e39560 | ||
|
|
6b20ff0b13 | ||
|
|
89bd32b6d4 | ||
|
|
005f240fb7 | ||
|
|
75da53e374 | ||
|
|
2485b0aa5e | ||
|
|
ed51a5e1fa | ||
|
|
56870504ac | ||
|
|
7aefb47cc3 | ||
|
|
aba41c0aea | ||
|
|
9300bf4141 | ||
|
|
b7ec17b3e3 | ||
|
|
2fcfe56a30 | ||
|
|
63b2d4e4d5 | ||
|
|
4cd77d8ee1 | ||
|
|
53a7347bea | ||
|
|
a02c25ebcc | ||
|
|
605c8cc6db | ||
|
|
033cc7c2d1 | ||
|
|
7c1ddb5b4c | ||
|
|
eb0f5264d7 | ||
|
|
5ad12c6fe4 | ||
|
|
61dacce5e0 | ||
|
|
e3f0381a26 | ||
|
|
6bc9dd96af | ||
|
|
e23f338b31 | ||
|
|
6e08b50e3c | ||
|
|
536712cd55 | ||
|
|
191ff0cda4 | ||
|
|
671f781564 | ||
|
|
30dc36b95d | ||
|
|
fac4aec680 | ||
|
|
8eac9a1808 | ||
|
|
ce74d96617 | ||
|
|
a15e77d605 | ||
|
|
bad022f524 | ||
|
|
50a54d0613 | ||
|
|
a47e41a8b7 | ||
|
|
f938443e55 | ||
|
|
b90abd2b28 | ||
|
|
da5682a600 | ||
|
|
81b72d9b7d | ||
|
|
6e13143286 | ||
|
|
70fc628c81 | ||
|
|
9858881ce6 | ||
|
|
eb6a8c7646 | ||
|
|
a71aea8aec | ||
|
|
918c441f88 | ||
|
|
960b4b0345 | ||
|
|
3aa4bfaa82 | ||
|
|
b3bdf9ef7e | ||
|
|
2948b8ffe8 | ||
|
|
e99c6c08a5 | ||
|
|
6fb389b2ed | ||
|
|
c09833cbde | ||
|
|
fa2ad69154 | ||
|
|
51d84455a3 | ||
|
|
d88d98d8a8 | ||
|
|
5aec466c8e | ||
|
|
0ee93774d5 | ||
|
|
7be7368bb9 | ||
|
|
eab0bb4a94 | ||
|
|
9f74f2077a | ||
|
|
a6e2efa6c9 | ||
|
|
205ef3009a | ||
|
|
d7edbd1e95 | ||
|
|
b361f464c5 | ||
|
|
fb377d2e99 | ||
|
|
deddd392ba | ||
|
|
3ab10848c8 | ||
|
|
433f1a940f | ||
|
|
1f12c09eb5 | ||
|
|
31e6d523f9 | ||
|
|
3c0bd051bf | ||
|
|
3c2d92dc5f | ||
|
|
262bd14bc8 | ||
|
|
f15ff46e34 | ||
|
|
fc1ec4e1b0 | ||
|
|
53f75826d8 | ||
|
|
ddfb816ef1 | ||
|
|
18428d108e | ||
|
|
3506c5dd3b | ||
|
|
2dffd06b1b | ||
|
|
12f2484d12 | ||
|
|
2dea44acf6 | ||
|
|
205f76c65d | ||
|
|
86af4fbd4d | ||
|
|
7915230121 | ||
|
|
1b27db7daa | ||
|
|
7370dcaa55 | ||
|
|
6a378b6863 | ||
|
|
6f6747a584 | ||
|
|
825221b2bb | ||
|
|
1e9d4b592e | ||
|
|
4a51db4764 | ||
|
|
afea71c81c | ||
|
|
9c8ca2ab3c | ||
|
|
a04875f64b | ||
|
|
7ec0bdb3f7 | ||
|
|
d2dbb6486e | ||
|
|
14728f889e | ||
|
|
ff199245b0 | ||
|
|
667807e249 | ||
|
|
63e09c8c47 | ||
|
|
17a8835d59 | ||
|
|
b306bfa77a | ||
|
|
b1eff2a893 | ||
|
|
5ac7c80881 | ||
|
|
d402f67fc3 | ||
|
|
c13793c445 | ||
|
|
daa3f6b206 | ||
|
|
a2d85c911d | ||
|
|
1b76c91e1b | ||
|
|
d663a4397a | ||
|
|
d1558c5eae | ||
|
|
0da4f77a2e | ||
|
|
e7ef35740c | ||
|
|
b0d561e33b | ||
|
|
75b362fa9b | ||
|
|
466f373ef6 | ||
|
|
4489641b54 | ||
|
|
1971d9dec2 | ||
|
|
c38d741770 | ||
|
|
122a474032 | ||
|
|
54854e99e7 | ||
|
|
e01fb7c905 | ||
|
|
83a3675a0c | ||
|
|
9dfa451fae | ||
|
|
9204a287fd | ||
|
|
f027507f9a | ||
|
|
01aee89f3b | ||
|
|
17285d4397 | ||
|
|
91ae846418 | ||
|
|
1eb429631d | ||
|
|
6584e3b868 | ||
|
|
14e2294db9 | ||
|
|
26b69bc208 | ||
|
|
2111d4c16b | ||
|
|
b682835b4e | ||
|
|
c34ac2f31e | ||
|
|
c28047374a | ||
|
|
60d16609f7 | ||
|
|
02ca9347dc | ||
|
|
d0187994ee | ||
|
|
be672d604f | ||
|
|
16e3d496eb | ||
|
|
9159ab842d | ||
|
|
0d8835d494 | ||
|
|
9f9e3aacfc | ||
|
|
7bd11fe73e | ||
|
|
e11dc5fadd | ||
|
|
f35b0deb29 | ||
|
|
33b3eecb95 | ||
|
|
6ac7a5f167 | ||
|
|
a5fbbfc460 | ||
|
|
563df3da71 | ||
|
|
13e6bc4fac | ||
|
|
357d77856a | ||
|
|
4279339189 | ||
|
|
380033dfe0 | ||
|
|
97d383ed12 | ||
|
|
52e6a63ebc | ||
|
|
7506e709e2 | ||
|
|
cf37de66fc | ||
|
|
e2754b447d | ||
|
|
c04848a92a | ||
|
|
748f5f070a | ||
|
|
2dcb367622 | ||
|
|
26bd2d08be | ||
|
|
739686ff89 | ||
|
|
68a871a5d7 | ||
|
|
b47bba4827 | ||
|
|
3b91859a49 | ||
|
|
c417bc9c2b | ||
|
|
7c95becfeb | ||
|
|
6b1480c5fa | ||
|
|
7f450544e1 | ||
|
|
0c046edfe5 | ||
|
|
2a2e6607b8 | ||
|
|
f6ed11ac55 | ||
|
|
d330f60b2d | ||
|
|
10c8cafcee | ||
|
|
d1534c88aa | ||
|
|
eb6b4c7cb7 | ||
|
|
c77ddcfebe | ||
|
|
af12526a6c | ||
|
|
b347abe100 | ||
|
|
092b57413b | ||
|
|
e8f35e4e06 | ||
|
|
b019e7526d | ||
|
|
1b06467521 | ||
|
|
7f3fd0cb1d | ||
|
|
3e9848554b | ||
|
|
b02cdbc5f9 | ||
|
|
d7723fd42a | ||
|
|
8b265bb81e | ||
|
|
89b6c94e42 | ||
|
|
219ac160b6 | ||
|
|
51ca1eab18 | ||
|
|
1ab3da1fab | ||
|
|
1d1b12c2fa | ||
|
|
07a658582d | ||
|
|
61da74ae50 | ||
|
|
90334f3cb0 | ||
|
|
fb9278bfc6 | ||
|
|
7750936af6 | ||
|
|
7b695af996 | ||
|
|
2874849557 | ||
|
|
9fd1f3e661 | ||
|
|
85182d9164 | ||
|
|
d9b2ea051f | ||
|
|
097fe6dcfb | ||
|
|
d5beca6d96 | ||
|
|
e3a356f893 | ||
|
|
8be2a9ab02 | ||
|
|
3d7f0f5143 | ||
|
|
1fd62fbaf7 | ||
|
|
f1372dda85 | ||
|
|
64c354adb2 | ||
|
|
a379e1f840 | ||
|
|
270ba799f7 | ||
|
|
60dcfacb88 | ||
|
|
b474d720e9 | ||
|
|
b2192b7252 | ||
|
|
6a988ad96a | ||
|
|
029ac5efee | ||
|
|
582cf1f533 | ||
|
|
b8a4e8e9e0 | ||
|
|
4a462aecc7 | ||
|
|
74f221b895 | ||
|
|
cbcb628bff | ||
|
|
f602645e31 | ||
|
|
ec9e609f10 | ||
|
|
1c1f3c7761 | ||
|
|
fae49284b7 | ||
|
|
072a608a63 | ||
|
|
1e6fd9c3a0 | ||
|
|
23200cbe85 | ||
|
|
08604e8c02 | ||
|
|
62a472d2d1 | ||
|
|
2c84665e8b | ||
|
|
616bd6830c | ||
|
|
e55ea96f00 | ||
|
|
aa676e139c | ||
|
|
7708fea58d | ||
|
|
34bdff01ad | ||
|
|
5a49579ddf | ||
|
|
b98a2b06c9 | ||
|
|
9073b16baa | ||
|
|
2ec4db8d7e | ||
|
|
fe9628f91c | ||
|
|
18a469e4be | ||
|
|
8c691cc074 | ||
|
|
2cd31a47f8 | ||
|
|
d97aa9c2a0 | ||
|
|
f31f0a89ff | ||
|
|
0a1621166e | ||
|
|
8623aa5318 | ||
|
|
ec50599526 | ||
|
|
458a30c520 | ||
|
|
9a660db4c3 | ||
|
|
f4fc71d32b | ||
|
|
e45a8185e3 | ||
|
|
7be9189b3c | ||
|
|
bdf13c01f6 | ||
|
|
902bc90aef | ||
|
|
27ba50d8be | ||
|
|
fb483ecb90 | ||
|
|
2de7079dd2 | ||
|
|
2e4ac604a8 | ||
|
|
46af80142e | ||
|
|
677b47dcdb | ||
|
|
56cccdf7c0 | ||
|
|
3e0d0bb809 | ||
|
|
86aa6c09c6 | ||
|
|
f67e1d897c | ||
|
|
9e518daa62 | ||
|
|
2e5455e655 | ||
|
|
868f1db4c5 | ||
|
|
efd84b1e1b | ||
|
|
5591fe50f0 | ||
|
|
5e0a598799 | ||
|
|
45d7b30abc | ||
|
|
46af88e1d0 | ||
|
|
7f331f5503 | ||
|
|
7b74e09d30 | ||
|
|
01e4455110 | ||
|
|
922a2d21c8 | ||
|
|
439c4794b7 | ||
|
|
5ac7f16b67 | ||
|
|
bfb79066b4 | ||
|
|
19602b42fb | ||
|
|
f987af264f | ||
|
|
a6c76dffc3 | ||
|
|
a2eed66bc4 | ||
|
|
a49b9b132d | ||
|
|
e8505a249a | ||
|
|
dbff9c02e9 | ||
|
|
45c5c5b40f | ||
|
|
aea71664ee | ||
|
|
fc65fb9323 | ||
|
|
f476823531 | ||
|
|
8222579d99 | ||
|
|
209c126445 | ||
|
|
c846ca3e71 | ||
|
|
e777fa143e | ||
|
|
e66000ffd2 | ||
|
|
cfdf448765 | ||
|
|
c61139c5cc | ||
|
|
571a4068c4 | ||
|
|
9ce63adb4f | ||
|
|
ef51a2f9b2 | ||
|
|
fa3e137db8 | ||
|
|
af6a708049 | ||
|
|
5d6ccf5717 | ||
|
|
59c870aca4 | ||
|
|
94cb014598 | ||
|
|
ed30567a22 | ||
|
|
791350c299 | ||
|
|
6547de1758 | ||
|
|
2151daab1f | ||
|
|
b791def0df | ||
|
|
c036d5859f | ||
|
|
6495869664 | ||
|
|
a2e6e7e879 | ||
|
|
338301907a | ||
|
|
681141f971 | ||
|
|
506ff1d46e | ||
|
|
c3b7deedb4 | ||
|
|
51252a15db | ||
|
|
375824f77a | ||
|
|
8918d10253 | ||
|
|
fe343a64ed | ||
|
|
205f12e14a | ||
|
|
aca94e470a | ||
|
|
a69f7b1144 | ||
|
|
e55abfb174 | ||
|
|
4a734b5bb6 | ||
|
|
758eb9dfda | ||
|
|
04e2770763 | ||
|
|
7391b4bcd0 | ||
|
|
d9d4d55eca | ||
|
|
9a64f8de98 | ||
|
|
9f9c9a2688 | ||
|
|
f80f4d1c19 | ||
|
|
145b39c4c0 | ||
|
|
44e264fe65 | ||
|
|
15fef4d84e | ||
|
|
b8bd1490ec | ||
|
|
ccd8923fdd | ||
|
|
e49fa620c8 | ||
|
|
654691543c | ||
|
|
929cd38184 | ||
|
|
9748a0794b | ||
|
|
a3f8c30508 | ||
|
|
602c0e8a3b | ||
|
|
7b7f840c2e | ||
|
|
ba9a8592ee | ||
|
|
389fcbf10c | ||
|
|
9cca14c382 | ||
|
|
243a2fe6f3 | ||
|
|
3d5069fd40 | ||
|
|
2b78bae451 | ||
|
|
8693cc17df | ||
|
|
9a2b7a7775 | ||
|
|
024a4a9ef3 | ||
|
|
f5b47cf74d | ||
|
|
4956b96193 | ||
|
|
a332dfd3b3 | ||
|
|
68f8d8d221 | ||
|
|
4f78060d35 | ||
|
|
adb97730c1 | ||
|
|
f1a0453615 | ||
|
|
e64cc875fe | ||
|
|
b1c028b786 | ||
|
|
d0e3914a29 | ||
|
|
fe7d1108cd | ||
|
|
462a3bbc83 | ||
|
|
b9dff99d63 | ||
|
|
612e67e4cc | ||
|
|
4f0838c98c | ||
|
|
fe70a77264 | ||
|
|
8ed33fd06a | ||
|
|
f5662769b3 | ||
|
|
61a2e20798 | ||
|
|
7d20118f38 | ||
|
|
7307b9d6fb | ||
|
|
c2971812a5 | ||
|
|
176a4bd34c | ||
|
|
4a01726058 | ||
|
|
18a372e027 | ||
|
|
483a2a867b | ||
|
|
1a0de94489 | ||
|
|
979c1588e1 | ||
|
|
e39f6b1003 | ||
|
|
4443ed1b7f | ||
|
|
81f11f13fe | ||
|
|
4fa14f055d | ||
|
|
0fe9033d23 | ||
|
|
e5ff53b1af | ||
|
|
d005e61c72 | ||
|
|
9328a79b37 | ||
|
|
56c7d5e3bd | ||
|
|
0cefe8f6ad | ||
|
|
3759fd2dad | ||
|
|
b35c771d16 | ||
|
|
3ce70cee4d | ||
|
|
8dd27a3e7b | ||
|
|
c91769e364 | ||
|
|
ea7856d591 | ||
|
|
023040a814 | ||
|
|
13fdb6caa9 | ||
|
|
81e1a41130 | ||
|
|
f3933155d6 | ||
|
|
4e692b8667 | ||
|
|
cf5f1cdb4e | ||
|
|
46986fba24 | ||
|
|
4627e7c0af | ||
|
|
38174a0b9f | ||
|
|
c0489245d9 | ||
|
|
bec23f793a | ||
|
|
e7578a9fc5 | ||
|
|
9d3313fe11 | ||
|
|
f41e5e3da5 | ||
|
|
540be68adf | ||
|
|
956bf0992a | ||
|
|
d0faee4eeb | ||
|
|
4517ae2f81 | ||
|
|
c77260193f | ||
|
|
d57c998047 | ||
|
|
3a5d5bc6d7 | ||
|
|
00afa748e0 | ||
|
|
8c9c7b9b1f | ||
|
|
1e2dc42554 | ||
|
|
cd621b9dba | ||
|
|
d10afe7a5a | ||
|
|
03fc9302d6 | ||
|
|
d522d837ff | ||
|
|
aa10760658 | ||
|
|
db6e8841ec | ||
|
|
75258bb465 | ||
|
|
7c7a59cf21 | ||
|
|
6f38c4eb71 | ||
|
|
7abedeae22 | ||
|
|
afacefaccb | ||
|
|
e5b2b5d5dc | ||
|
|
9508238805 | ||
|
|
2c21bd7286 | ||
|
|
811ddcc26c | ||
|
|
6cd0373678 | ||
|
|
11771b2b53 | ||
|
|
ff5c6e878e | ||
|
|
1896aed973 | ||
|
|
6dc5deb6d3 | ||
|
|
d7242d526c | ||
|
|
22c3fc8c40 | ||
|
|
8d44105f88 | ||
|
|
8fb8d97dcf | ||
|
|
6941014153 | ||
|
|
bfd610d255 | ||
|
|
5c61217c78 | ||
|
|
eb527857f3 | ||
|
|
d55982bde0 | ||
|
|
84a27de792 | ||
|
|
111bec547c | ||
|
|
db4f699b85 | ||
|
|
12f2d95265 | ||
|
|
a917ca00a1 | ||
|
|
69906046e8 | ||
|
|
d9cedeca09 | ||
|
|
0e28f27819 | ||
|
|
33fc7f14df | ||
|
|
7159aca226 | ||
|
|
2c5728e27e | ||
|
|
defb40702c | ||
|
|
b476df3b61 | ||
|
|
4bbd9b6f06 | ||
|
|
325b9c4d88 | ||
|
|
76d965b3b7 | ||
|
|
4b1b27abd8 | ||
|
|
f26b4f290d | ||
|
|
5d2221203a | ||
|
|
0aff0d529e | ||
|
|
20f09b3a0c | ||
|
|
c392b72470 | ||
|
|
50a70ef1e5 | ||
|
|
75266ef659 | ||
|
|
b3c593b852 | ||
|
|
73530bb8b9 | ||
|
|
1b6e70964b | ||
|
|
61d42b05e9 | ||
|
|
79703e3c71 | ||
|
|
aee4e4e282 | ||
|
|
744c7559f3 | ||
|
|
d94c3ec9cc | ||
|
|
f2625eab16 | ||
|
|
c6d498a9be | ||
|
|
b06bc0a455 | ||
|
|
68411bddd9 | ||
|
|
a2ac2e0b22 | ||
|
|
a5a5d9f1ac | ||
|
|
82876eac8d | ||
|
|
19c9c0f4e5 | ||
|
|
70f044dc50 | ||
|
|
1c8418026c | ||
|
|
17f8471c14 | ||
|
|
4deb2ea484 | ||
|
|
d05317dbf5 | ||
|
|
1db6ccd72b | ||
|
|
bc00760404 | ||
|
|
e57dc1240b | ||
|
|
4c396d68ca | ||
|
|
ab0fe4286a | ||
|
|
5ab758d626 | ||
|
|
3a0a6537f0 | ||
|
|
4eda92f25c | ||
|
|
94f8c5d2f1 | ||
|
|
92598effc1 | ||
|
|
748cecaee8 | ||
|
|
b783034d0a | ||
|
|
94a4e39793 | ||
|
|
1864dee591 | ||
|
|
8c4ea85d02 | ||
|
|
a714d5a84e | ||
|
|
4f97a7890f | ||
|
|
f15f91e5fa | ||
|
|
02bd500917 | ||
|
|
810c6fd232 | ||
|
|
d50a8983bc | ||
|
|
89647304bb | ||
|
|
9ebad13bf8 | ||
|
|
cc0ac8cc43 | ||
|
|
9f5a1d842a | ||
|
|
beb33957be | ||
|
|
ffcbbb705b | ||
|
|
058bc71630 | ||
|
|
0a38979bd9 | ||
|
|
5fa4a15914 | ||
|
|
81c551a11b | ||
|
|
5681449353 | ||
|
|
88849e6355 | ||
|
|
d6bbcdc32f | ||
|
|
abd1581c1d | ||
|
|
cd30ec7632 | ||
|
|
646826769a | ||
|
|
074c0abb3b | ||
|
|
3a00e893bc | ||
|
|
2f37677650 | ||
|
|
12ae89923b | ||
|
|
031a203a74 | ||
|
|
646b99974a | ||
|
|
254ed954e9 | ||
|
|
a0050dca09 | ||
|
|
cd80b4e6c3 | ||
|
|
df5d3d782c | ||
|
|
3c5b3c3467 | ||
|
|
2bdba42d87 | ||
|
|
0b146f7ff3 | ||
|
|
c28a4f6d69 | ||
|
|
f93a34acc4 | ||
|
|
4e78841bf6 | ||
|
|
7f5bb58c72 | ||
|
|
6a28359ac2 | ||
|
|
59655695b5 | ||
|
|
786c5c1d7c | ||
|
|
08388124b3 | ||
|
|
34ccc68b3a | ||
|
|
97ef386f17 | ||
|
|
394339d7dc | ||
|
|
8362578355 | ||
|
|
6dc218cf80 | ||
|
|
89888cef73 | ||
|
|
4d06f444ac |
@@ -0,0 +1,14 @@
|
|||||||
|
version: 2
|
||||||
|
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "gomod"
|
||||||
|
directories:
|
||||||
|
- "/agent"
|
||||||
|
- "/core"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/frontend"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
@@ -6,7 +6,7 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
generic_handler:
|
generic_handler:
|
||||||
name: Add Labels to PR
|
name: Add Labels to PR
|
||||||
if: github.repository == '1Panel-dev/1Panel'
|
if: github.repository == '1Panel-dev/1Panel' && github.event.pull_request.user.login != 'dependabot[bot]'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
name: Build And Publish (OSS + R2)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
create-release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: '24.11.1'
|
|
||||||
|
|
||||||
- name: Build Web
|
|
||||||
run: |
|
|
||||||
cd frontend && npm install && npm run build:pro
|
|
||||||
env:
|
|
||||||
NODE_OPTIONS: --max-old-space-size=8192
|
|
||||||
|
|
||||||
- name: Setup Go
|
|
||||||
uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: '1.25'
|
|
||||||
cache-dependency-path: |
|
|
||||||
core/go.sum
|
|
||||||
agent/go.sum
|
|
||||||
|
|
||||||
- name: Build Release
|
|
||||||
uses: goreleaser/goreleaser-action@v6
|
|
||||||
with:
|
|
||||||
distribution: goreleaser
|
|
||||||
version: '~> v2'
|
|
||||||
args: release --skip=publish --clean
|
|
||||||
|
|
||||||
- name: Upload Assets
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
with:
|
|
||||||
draft: true
|
|
||||||
files: |
|
|
||||||
dist/*.tar.gz
|
|
||||||
dist/checksums.txt
|
|
||||||
|
|
||||||
- name: Setup OSSUTIL
|
|
||||||
uses: yizhoumo/setup-ossutil@v2
|
|
||||||
with:
|
|
||||||
endpoint: ${{ secrets.OSS_ENDPOINT }}
|
|
||||||
access-key-id: ${{ secrets.OSS_ACCESS_KEY_ID }}
|
|
||||||
access-key-secret: ${{ secrets.OSS_ACCESS_KEY_SECRET }}
|
|
||||||
ossutil-version: '1.7.18'
|
|
||||||
|
|
||||||
- name: Upload Assets to OSS
|
|
||||||
run: |
|
|
||||||
ossutil cp -r dist/ oss://resource-fit2cloud-com/1panel/package/v2/stable/${{ github.ref_name }}/release/ --include "*.tar.gz" --include "checksums.txt" --only-current-dir --force
|
|
||||||
|
|
||||||
- name: Setup Rclone
|
|
||||||
uses: AnimMouse/setup-rclone@v1
|
|
||||||
with:
|
|
||||||
rclone_config: ${{ secrets.RCLONE_CONFIG }}
|
|
||||||
|
|
||||||
- name: Upload to Cloudflare R2
|
|
||||||
run: |
|
|
||||||
rclone copy dist/ cloudflare_r2:package/v2/stable/${{ github.ref_name }}/release/ --include "*.tar.gz" --include "checksums.txt" --progress
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
name: LLM Code Review
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, reopened, synchronize]
|
|
||||||
jobs:
|
|
||||||
llm-code-review:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: fit2cloud/LLM-CodeReview-Action@main
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.FIT2CLOUDRD_LLM_CODE_REVIEW_TOKEN }}
|
|
||||||
OPENAI_API_KEY: ${{ secrets.ALIYUN_LLM_API_KEY }}
|
|
||||||
LANGUAGE: English
|
|
||||||
OPENAI_API_ENDPOINT: https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
||||||
MODEL: qwen2.5-coder-3b-instruct
|
|
||||||
PROMPT: "Please check the following code differences for any irregularities, potential issues, or optimization suggestions, and provide your answers in English."
|
|
||||||
top_p: 1
|
|
||||||
temperature: 1
|
|
||||||
# max_tokens: 10000
|
|
||||||
MAX_PATCH_LENGTH: 10000
|
|
||||||
IGNORE_PATTERNS: "/node_modules,*.md,/dist,/.github"
|
|
||||||
FILE_PATTERNS: "*.java,*.go,*.py,*.vue,*.ts,*.js,*.css,*.scss,*.html"
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
name: SonarCloud Scan
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- dev
|
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened]
|
|
||||||
jobs:
|
|
||||||
sonarcloud:
|
|
||||||
name: SonarCloud
|
|
||||||
if: github.repository == '1Panel-dev/1Panel'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: SonarCloud Scan
|
|
||||||
uses: SonarSource/sonarcloud-github-action@master
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUBTOKEN }}
|
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
|
||||||
@@ -6,7 +6,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Mirror the Github organization repos to Gitee.
|
- name: Mirror the Github organization repos to Gitee.
|
||||||
uses: Yikun/hub-mirror-action@master
|
uses: Yikun/hub-mirror-action@ba51c01b28a6c9f95a25d4f1bcf6af2a147c0e18 # master
|
||||||
with:
|
with:
|
||||||
src: 'github/1Panel-dev'
|
src: 'github/1Panel-dev'
|
||||||
dst: 'gitee/fit2cloud-feizhiyun'
|
dst: 'gitee/fit2cloud-feizhiyun'
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
name: Typos Check
|
|
||||||
on: pull_request
|
|
||||||
jobs:
|
|
||||||
run:
|
|
||||||
name: Spell Check with Typos
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Actions Repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Check spelling
|
|
||||||
uses: crate-ci/typos@master
|
|
||||||
+10
-7
@@ -9,7 +9,6 @@ build/1panel-core
|
|||||||
|
|
||||||
# Mac
|
# Mac
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*/.DS_Store
|
|
||||||
|
|
||||||
# VS Code
|
# VS Code
|
||||||
.vscode
|
.vscode
|
||||||
@@ -41,20 +40,23 @@ core/cmd/server/web/index.html
|
|||||||
frontend/auto-imports.d.ts
|
frontend/auto-imports.d.ts
|
||||||
frontend/components.d.ts
|
frontend/components.d.ts
|
||||||
frontend/src/xpack
|
frontend/src/xpack
|
||||||
|
frontend/src/enterprise
|
||||||
agent/xpack
|
agent/xpack
|
||||||
|
agent/enterprise
|
||||||
agent/router/entry_xpack.go
|
agent/router/entry_xpack.go
|
||||||
|
agent/router/entry_enterprise.go
|
||||||
agent/server/init_xpack.go
|
agent/server/init_xpack.go
|
||||||
|
agent/server/init_enterprise.go
|
||||||
agent/utils/xpack/xpack.go
|
agent/utils/xpack/xpack.go
|
||||||
agent/utils/xpack/xpack_xpack.go
|
agent/utils/xpack/enterprise.go
|
||||||
core/xpack
|
core/xpack
|
||||||
|
core/enterprise
|
||||||
core/router/entry_xpack.go
|
core/router/entry_xpack.go
|
||||||
|
core/router/entry_enterprise.go
|
||||||
core/server/init_xpack.go
|
core/server/init_xpack.go
|
||||||
|
core/server/init_enterprise.go
|
||||||
core/utils/xpack/xpack.go
|
core/utils/xpack/xpack.go
|
||||||
core/utils/xpack/xpack_xpack.go
|
core/utils/xpack/enterprise.go
|
||||||
core/xpack-ee
|
|
||||||
core/router/entry_xpackee.go
|
|
||||||
core/server/init_xpackee.go
|
|
||||||
core/utils/xpack/xpack_xpackee.go
|
|
||||||
|
|
||||||
.history/
|
.history/
|
||||||
dist/
|
dist/
|
||||||
@@ -76,3 +78,4 @@ AGENTS.md
|
|||||||
opencode.json
|
opencode.json
|
||||||
superpowers
|
superpowers
|
||||||
.worktrees/
|
.worktrees/
|
||||||
|
.codex/
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
|
||||||
# vim: set ts=2 sw=2 tw=0 fo=jcroql
|
|
||||||
version: 2
|
|
||||||
|
|
||||||
before:
|
|
||||||
hooks:
|
|
||||||
# - export NODE_OPTIONS="--max-old-space-size=8192"
|
|
||||||
# - make build_web
|
|
||||||
- chmod +x ./ci/script.sh
|
|
||||||
- ./ci/script.sh
|
|
||||||
- sed -i 's@ORIGINAL_VERSION=.*@ORIGINAL_VERSION=v{{ .Version }}@g' 1pctl
|
|
||||||
|
|
||||||
builds:
|
|
||||||
- id: agent
|
|
||||||
dir: agent
|
|
||||||
main: cmd/server/main.go
|
|
||||||
binary: 1panel-agent
|
|
||||||
flags:
|
|
||||||
- -tags=xpack
|
|
||||||
- -trimpath
|
|
||||||
ldflags:
|
|
||||||
- -w -s
|
|
||||||
env:
|
|
||||||
- CGO_ENABLED=0
|
|
||||||
goos:
|
|
||||||
- linux
|
|
||||||
goarm:
|
|
||||||
- 7
|
|
||||||
goarch:
|
|
||||||
- amd64
|
|
||||||
- arm64
|
|
||||||
- arm
|
|
||||||
- ppc64le
|
|
||||||
- s390x
|
|
||||||
- riscv64
|
|
||||||
|
|
||||||
- id: core
|
|
||||||
dir: core
|
|
||||||
main: cmd/server/main.go
|
|
||||||
binary: 1panel-core
|
|
||||||
flags:
|
|
||||||
- -tags=xpack
|
|
||||||
- -trimpath
|
|
||||||
ldflags:
|
|
||||||
- -w -s
|
|
||||||
env:
|
|
||||||
- CGO_ENABLED=0
|
|
||||||
goos:
|
|
||||||
- linux
|
|
||||||
goarm:
|
|
||||||
- 7
|
|
||||||
goarch:
|
|
||||||
- amd64
|
|
||||||
- arm64
|
|
||||||
- arm
|
|
||||||
- ppc64le
|
|
||||||
- s390x
|
|
||||||
- riscv64
|
|
||||||
|
|
||||||
archives:
|
|
||||||
- formats: [ 'tar.gz' ]
|
|
||||||
ids: [core, agent]
|
|
||||||
name_template: "1panel-v{{ .Version }}-{{ .Os }}-{{ .Arch }}{{- if .Arm }}v{{ .Arm }}{{ end }}"
|
|
||||||
wrap_in_directory: true
|
|
||||||
files:
|
|
||||||
- 1pctl
|
|
||||||
- install.sh
|
|
||||||
- 1panel-core.service
|
|
||||||
- 1panel-agent.service
|
|
||||||
- initscript/*
|
|
||||||
- lang/*
|
|
||||||
- GeoIP.mmdb
|
|
||||||
|
|
||||||
checksum:
|
|
||||||
name_template: 'checksums.txt'
|
|
||||||
|
|
||||||
changelog:
|
|
||||||
sort: asc
|
|
||||||
filters:
|
|
||||||
exclude:
|
|
||||||
- "^docs:"
|
|
||||||
- "^test:"
|
|
||||||
+4
-2
@@ -10,10 +10,12 @@ PR are always welcome, even if they only contain small fixes like typos or a few
|
|||||||
|
|
||||||
Please submit a PR broken down into small changes bit by bit. A PR consisting of a lot of features and code changes may be hard to review. It is recommended to submit PRs in an incremental fashion.
|
Please submit a PR broken down into small changes bit by bit. A PR consisting of a lot of features and code changes may be hard to review. It is recommended to submit PRs in an incremental fashion.
|
||||||
|
|
||||||
This [development guideline](https://docs.1panel.pro/dev_manual/dev_manual/) contains information about repository structure, how to set up development environment, how to run it, and more.
|
|
||||||
|
|
||||||
Note: If you split your pull request to small changes, please make sure any of the changes goes to master will not break anything. Otherwise, it can not be merged until this feature complete.
|
Note: If you split your pull request to small changes, please make sure any of the changes goes to master will not break anything. Otherwise, it can not be merged until this feature complete.
|
||||||
|
|
||||||
|
## Add a new translation
|
||||||
|
|
||||||
|
If you'd like to help translate 1Panel into a new language, please read the [Translation Contribution Guide](docs/TRANSLATION.md). It lists every file you need to create or modify, along with a reference PR you can use as a concrete example.
|
||||||
|
|
||||||
## Report issues
|
## Report issues
|
||||||
It is a great way to contribute by reporting an issue. Well-written and complete bug reports are always welcome! Please open an issue and follow the template to fill in required information.
|
It is a great way to contribute by reporting an issue. Well-written and complete bug reports are always welcome! Please open an issue and follow the template to fill in required information.
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ reviewers:
|
|||||||
- wanghe-fit2cloud
|
- wanghe-fit2cloud
|
||||||
- zhengkunwang223
|
- zhengkunwang223
|
||||||
- ssongliu
|
- ssongliu
|
||||||
|
- lan-yonghui
|
||||||
|
|
||||||
approvers:
|
approvers:
|
||||||
- wanghe-fit2cloud
|
- wanghe-fit2cloud
|
||||||
- zhengkunwang223
|
- zhengkunwang223
|
||||||
- ssongliu
|
- ssongliu
|
||||||
|
- lan-yonghui
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
<p align="center"><a href="https://1panel.pro"><img src="https://resource.1panel.pro/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
|
<p align="center"><a href="https://1panel.pro"><img src="https://resource.1panel.pro/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
|
||||||
|
|
||||||
<h3 align="center">The open-source VPS control panel with native AI agent support</h3>
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
Trusted by <strong>2,000,000+</strong> self-hosters worldwide
|
Loved by a global community of <strong>2.5M+</strong> self-hosters.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -12,7 +9,6 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://shields.io/github/license/1Panel-dev/1Panel?color=%231890FF" alt="License: GPL v3"></a>
|
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://shields.io/github/license/1Panel-dev/1Panel?color=%231890FF" alt="License: GPL v3"></a>
|
||||||
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
|
|
||||||
<a href="https://discord.gg/bUpUqWqdRr"><img src="https://img.shields.io/discord/1318846410149335080?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb" alt="Discord"></a>
|
<a href="https://discord.gg/bUpUqWqdRr"><img src="https://img.shields.io/discord/1318846410149335080?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb" alt="Discord"></a>
|
||||||
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
|
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
|
||||||
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
|
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
|
||||||
@@ -25,7 +21,7 @@
|
|||||||
<a href="/docs/README.pt-br.md"><img alt="Português (Brasil)" src="https://img.shields.io/badge/Português (Brasil)-d9d9d9"></a>
|
<a href="/docs/README.pt-br.md"><img alt="Português (Brasil)" src="https://img.shields.io/badge/Português (Brasil)-d9d9d9"></a>
|
||||||
<a href="/docs/README.ar.md"><img alt="العربية" src="https://img.shields.io/badge/العربية-d9d9d9"></a>
|
<a href="/docs/README.ar.md"><img alt="العربية" src="https://img.shields.io/badge/العربية-d9d9d9"></a>
|
||||||
<a href="/docs/README.de.md"><img alt="Deutsch" src="https://img.shields.io/badge/Deutsch-d9d9d9"></a>
|
<a href="/docs/README.de.md"><img alt="Deutsch" src="https://img.shields.io/badge/Deutsch-d9d9d9"></a>
|
||||||
<a href="/docs/README.es.md"><img alt="Español" src="https://img.shields.io/badge/Español-d9d9d9"></a>
|
<a href="/docs/README.es-es.md"><img alt="Español" src="https://img.shields.io/badge/Español-d9d9d9"></a>
|
||||||
<a href="/docs/README.fr.md"><img alt="français" src="https://img.shields.io/badge/français-d9d9d9"></a>
|
<a href="/docs/README.fr.md"><img alt="français" src="https://img.shields.io/badge/français-d9d9d9"></a>
|
||||||
<a href="/docs/README.ko.md"><img alt="한국어" src="https://img.shields.io/badge/한국어-d9d9d9"></a>
|
<a href="/docs/README.ko.md"><img alt="한국어" src="https://img.shields.io/badge/한국어-d9d9d9"></a>
|
||||||
<a href="/docs/README.id.md"><img alt="Bahasa Indonesia" src="https://img.shields.io/badge/Bahasa Indonesia-d9d9d9"></a>
|
<a href="/docs/README.id.md"><img alt="Bahasa Indonesia" src="https://img.shields.io/badge/Bahasa Indonesia-d9d9d9"></a>
|
||||||
@@ -33,40 +29,36 @@
|
|||||||
<a href="/docs/README.tr.md"><img alt="Türkçe" src="https://img.shields.io/badge/Türkçe-d9d9d9"></a>
|
<a href="/docs/README.tr.md"><img alt="Türkçe" src="https://img.shields.io/badge/Türkçe-d9d9d9"></a>
|
||||||
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/Русский-d9d9d9"></a>
|
<a href="/docs/README.ru.md"><img alt="Русский" src="https://img.shields.io/badge/Русский-d9d9d9"></a>
|
||||||
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
<a href="/docs/README.ms.md"><img alt="Bahasa Melayu" src="https://img.shields.io/badge/Bahasa Melayu-d9d9d9"></a>
|
||||||
|
<a href="/docs/README.fa.md"><img alt="Persian" src="https://img.shields.io/badge/%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-d9d9d9"></a>
|
||||||
|
<a href="/docs/README.lo.md"><img alt="ພາສາລາວ" src="https://img.shields.io/badge/%E0%BA%9E%E0%BA%B2%E0%BA%AA%E0%BA%B2%E0%BA%A5%E0%BA%B2%E0%BA%A7-d9d9d9"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## What is 1Panel?
|
## What is 1Panel?
|
||||||
|
|
||||||
1Panel is a modern, open-source VPS control panel — and the only one with **native AI agent support**. Run Ollama models, deploy OpenClaw agents, and manage your entire server stack from one clean web interface. No CLI memorization required.
|
1Panel is a modern, open-source Linux server management panel and a lightweight AI management platform. Through an intuitive web interface, it provides users with comprehensive, one-stop server management capabilities:
|
||||||
|
- **AI Management**: Offers a unified management platform from bare metal to agents (Metal-to-Agent). It integrates an AI gateway, and Skills Hub, while supporting centralized management of agents and models.
|
||||||
👉 Watch the [2-minute introduction](https://www.youtube.com/watch?v=Jl_wqp-XA08)
|
- **Efficient Visual Operations**: Easily manage Linux servers through a web-based GUI, streamlining tasks such as host monitoring, file management, database management, and container management.
|
||||||
|
- **Rapid Website Deployment**: Deeply integrates with popular website builders like WordPress and Halo. It enables one-click domain binding and SSL certificate configuration, significantly lowering the barrier to website creation.
|
||||||
|
- **Curated App Store**: Features a built-in store of high-quality open-source applications, providing one-click installation and upgrade services to effortlessly extend server capabilities.
|
||||||
|
- **Enterprise-Grade Security**: Deploys applications based on container technology to effectively minimize vulnerability exposure. It also provides security features such as WAF and log auditing to ensure comprehensive server protection.
|
||||||
|
- **One-Click Data Backup**: Supports one-click backup and restoration, and integrates with various cloud storage solutions to ensure data security and prevent loss.
|
||||||
|
|
||||||
## Why 1Panel?
|
## Why 1Panel?
|
||||||
|
|
||||||
| | 1Panel | cPanel / Plesk | aaPanel | Webmin |
|
| | 1Panel | cPanel / Plesk | aaPanel | Webmin |
|
||||||
|--|--------|----------------|---------|--------|
|
|--|--------|----------------|---------|--------|
|
||||||
| Free & open source | ✅ | ❌ | Partial | ✅ |
|
| Free & open source | ✅ | ❌ | Partial | ✅ |
|
||||||
| Native AI agent runtime | ✅ | ❌ | ❌ | ❌ |
|
| AI management | ✅ | ❌ | ❌ | ❌ |
|
||||||
| One-click app marketplace | ✅ 165+ apps | ❌ | ✅ | ❌ |
|
| One-click app marketplace | ✅ 165+ apps | ❌ | ✅ | ❌ |
|
||||||
| Modern UI (post-2020) | ✅ | ❌ | Partial | ❌ |
|
| Modern UI (post-2020) | ✅ | ❌ | Partial | ❌ |
|
||||||
| Docker / container management | ✅ | ❌ | ❌ | ❌ |
|
| Docker / container management | ✅ | ❌ | ❌ | ❌ |
|
||||||
| Active development | ✅ | ✅ | ✅ | Slow |
|
| Active development | ✅ | ✅ | ✅ | Slow |
|
||||||
|
|
||||||
## Key Features
|
|
||||||
|
|
||||||
- **AI Agent Runtime**: Deploy Ollama LLMs, spin up OpenClaw personal agents, and monitor GPU utilization — all from the dashboard. No separate AI stack to manage.
|
|
||||||
- **One-Click Website Deployment**: Launch production-ready websites with automatic domain binding, SSL provisioning, and Nginx config — zero manual setup.
|
|
||||||
- **App Marketplace**: 165+ trusted open-source apps (Nextcloud, Bitwarden, Umami, NocoBase, and more) installed and updated with a single click.
|
|
||||||
- **Docker & Container Management**: Create, start, stop, and inspect containers, images, networks, and volumes through a visual UI — no CLI juggling.
|
|
||||||
- **Security Out of the Box**: Firewall rules, fail2ban, container isolation, WAF, and audit logs — configured and running from day one.
|
|
||||||
- **Backup & Restore**: Schedule automated backups to AWS S3, Cloudflare R2, or local storage. Restore any snapshot in one click.
|
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
> **Requirements:** Linux VPS (Debian / Ubuntu / CentOS / Rocky), 1 GB RAM, internet access.
|
Prepare your Linux server and run the following script:
|
||||||
> Takes ~60 seconds.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash -c "$(curl -sSL https://resource.1panel.pro/v2/quick_start.sh)"
|
bash -c "$(curl -sSL https://resource.1panel.pro/v2/quick_start.sh)"
|
||||||
@@ -81,24 +73,20 @@ Run `1pctl user-info` via SSH if you need to retrieve your access credentials.
|
|||||||
|
|
||||||
## Pro Edition
|
## Pro Edition
|
||||||
|
|
||||||
1Panel OSS is free forever. Pro adds features built for teams and production workloads:
|
1Panel OSS is free forever. 1Panel Pro and Ent adds features built for teams and production workloads:
|
||||||
|
|
||||||
| Feature | OSS | Pro |
|
| Feature | OSS | Pro | Ent |
|
||||||
|---------|:---:|:---:|
|
|---------|:---:|:---:|:---:|
|
||||||
| One-click app installs | ✅ | ✅ |
|
| One-click app installs | ✅ | ✅ | ✅ |
|
||||||
| AI agents (OpenClaw) | 1 agent | Unlimited |
|
| AI agents (OpenClaw) | 5 agent | Unlimited | ✅ |
|
||||||
| WAF & advanced security | Basic | ✅ |
|
| WAF & advanced security | Basic | ✅ | ✅ |
|
||||||
| Website tamper protection | ❌ | ✅ |
|
| Website tamper protection | ❌ | ✅ | ✅ |
|
||||||
| Website uptime monitoring | ❌ | ✅ |
|
| Website uptime monitoring | ❌ | ✅ | ✅ |
|
||||||
| Multi-node management | ❌ | ✅ |
|
| Multi-node management | ❌ | ✅ | ✅ |
|
||||||
| Custom logo & theme | ❌ | ✅ |
|
| Custom logo & theme | ❌ | ✅ | ✅ |
|
||||||
| Priority support | ❌ | ✅ |
|
| KVM Web UI | ❌ | ❌ | ✅ |
|
||||||
|
| AI Gateway | ❌ | ❌ | ✅ |
|
||||||
**From $80/year.** [Compare plans & start 30-day free trial →](https://1panel.pro/pricing)
|
| Priority support | ❌ | ❌ | ✅ |
|
||||||
|
|
||||||
## Star History
|
|
||||||
|
|
||||||
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
|
||||||
|
|
||||||
## Community & Support
|
## Community & Support
|
||||||
|
|
||||||
|
|||||||
+370
-20
@@ -27,6 +27,90 @@ func (b *BaseApi) CreateAgent(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, res)
|
helper.SuccessWithData(c, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Batch install Agent
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentBatchInstallReq true "request"
|
||||||
|
// @Success 200 {object} dto.AgentItem
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/batch/install [post]
|
||||||
|
func (b *BaseApi) BatchInstallAgent(c *gin.Context) {
|
||||||
|
var req dto.AgentBatchInstallReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := agentService.BatchInstall(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Batch upgrade Agent
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentBatchUpgradeReq true "request"
|
||||||
|
// @Success 200 {array} dto.AgentBatchUpgradeResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/batch/upgrade [post]
|
||||||
|
func (b *BaseApi) BatchUpgradeAgent(c *gin.Context) {
|
||||||
|
var req dto.AgentBatchUpgradeReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := agentService.BatchUpgrade(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Batch install Agent Skill
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentBatchSkillInstallReq true "request"
|
||||||
|
// @Success 200 {array} dto.AgentBatchSkillInstallResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/batch/skill/install [post]
|
||||||
|
func (b *BaseApi) BatchInstallAgentSkill(c *gin.Context) {
|
||||||
|
var req dto.AgentBatchSkillInstallReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := agentService.BatchInstallSkill(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Batch operate Agent
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentBatchOperateReq true "request"
|
||||||
|
// @Success 200 {array} dto.AgentBatchOperateResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/batch/operate [post]
|
||||||
|
func (b *BaseApi) BatchOperateAgent(c *gin.Context) {
|
||||||
|
var req dto.AgentBatchOperateReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := agentService.BatchOperate(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Page Agents
|
// @Summary Page Agents
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -152,6 +236,26 @@ func (b *BaseApi) BindAgentWebsite(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Unbind Agent website
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentIDReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/website/unbind [post]
|
||||||
|
func (b *BaseApi) UnbindAgentWebsite(c *gin.Context) {
|
||||||
|
var req dto.AgentIDReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := agentService.UnbindWebsite(req); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Get Agent model config
|
// @Summary Get Agent model config
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -215,11 +319,72 @@ func (b *BaseApi) GetAgentOverview(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Get Providers
|
// @Summary Get Hermes chat sessions
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentIDReq true "request"
|
||||||
|
// @Success 200 {array} dto.AgentHermesChatSessionItem
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/hermes/chat/sessions [post]
|
||||||
|
func (b *BaseApi) GetHermesChatSessions(c *gin.Context) {
|
||||||
|
var req dto.AgentIDReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := agentService.GetHermesChatSessions(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Rename Hermes chat session
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentHermesChatSessionRenameReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/hermes/chat/sessions/rename [post]
|
||||||
|
func (b *BaseApi) RenameHermesChatSession(c *gin.Context) {
|
||||||
|
var req dto.AgentHermesChatSessionRenameReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := agentService.RenameHermesChatSession(req); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Delete Hermes chat session
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentHermesChatSessionDeleteReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/hermes/chat/sessions/delete [post]
|
||||||
|
func (b *BaseApi) DeleteHermesChatSession(c *gin.Context) {
|
||||||
|
var req dto.AgentHermesChatSessionDeleteReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := agentService.DeleteHermesChatSession(req); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Get model account providers
|
||||||
// @Success 200 {array} dto.ProviderInfo
|
// @Success 200 {array} dto.ProviderInfo
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/providers [get]
|
// @Router /ai/accounts/providers [get]
|
||||||
func (b *BaseApi) GetAgentProviders(c *gin.Context) {
|
func (b *BaseApi) GetAgentProviders(c *gin.Context) {
|
||||||
list, err := agentService.GetProviders()
|
list, err := agentService.GetProviders()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -230,13 +395,13 @@ func (b *BaseApi) GetAgentProviders(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Create Agent account
|
// @Summary Create model account
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountCreateReq true "request"
|
// @Param request body dto.AgentAccountCreateReq true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts [post]
|
// @Router /ai/accounts [post]
|
||||||
func (b *BaseApi) CreateAgentAccount(c *gin.Context) {
|
func (b *BaseApi) CreateAgentAccount(c *gin.Context) {
|
||||||
var req dto.AgentAccountCreateReq
|
var req dto.AgentAccountCreateReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -250,13 +415,13 @@ func (b *BaseApi) CreateAgentAccount(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Update Agent account
|
// @Summary Update model account
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountUpdateReq true "request"
|
// @Param request body dto.AgentAccountUpdateReq true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts/update [post]
|
// @Router /ai/accounts/update [post]
|
||||||
func (b *BaseApi) UpdateAgentAccount(c *gin.Context) {
|
func (b *BaseApi) UpdateAgentAccount(c *gin.Context) {
|
||||||
var req dto.AgentAccountUpdateReq
|
var req dto.AgentAccountUpdateReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -270,13 +435,13 @@ func (b *BaseApi) UpdateAgentAccount(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Page Agent accounts
|
// @Summary Page model accounts
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountSearch true "request"
|
// @Param request body dto.AgentAccountSearch true "request"
|
||||||
// @Success 200 {object} dto.PageResult
|
// @Success 200 {object} dto.PageResult
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts/search [post]
|
// @Router /ai/accounts/search [post]
|
||||||
func (b *BaseApi) PageAgentAccounts(c *gin.Context) {
|
func (b *BaseApi) PageAgentAccounts(c *gin.Context) {
|
||||||
var req dto.AgentAccountSearch
|
var req dto.AgentAccountSearch
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -294,13 +459,34 @@ func (b *BaseApi) PageAgentAccounts(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary List Agent account models
|
// @Summary Count model accounts by provider
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentAccountProviderCountReq true "request"
|
||||||
|
// @Success 200 {object} map[string]int64
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/accounts/counts [post]
|
||||||
|
func (b *BaseApi) CountAgentAccountsByProviders(c *gin.Context) {
|
||||||
|
var req dto.AgentAccountProviderCountReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
counts, err := agentService.CountAccountsByProviders(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, counts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary List model account models
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountModelReq true "request"
|
// @Param request body dto.AgentAccountModelReq true "request"
|
||||||
// @Success 200 {array} dto.AgentAccountModel
|
// @Success 200 {array} dto.AgentAccountModel
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts/models [post]
|
// @Router /ai/accounts/models [post]
|
||||||
func (b *BaseApi) GetAgentAccountModels(c *gin.Context) {
|
func (b *BaseApi) GetAgentAccountModels(c *gin.Context) {
|
||||||
var req dto.AgentAccountModelReq
|
var req dto.AgentAccountModelReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -315,13 +501,34 @@ func (b *BaseApi) GetAgentAccountModels(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Create Agent account model
|
// @Summary Discover custom provider models
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentAccountModelDiscoverReq true "request"
|
||||||
|
// @Success 200 {array} dto.AgentAccountModel
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/accounts/models/discover [post]
|
||||||
|
func (b *BaseApi) DiscoverAgentAccountModels(c *gin.Context) {
|
||||||
|
var req dto.AgentAccountModelDiscoverReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
list, err := agentService.DiscoverAccountModels(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, list)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Create model account model
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountModelCreateReq true "request"
|
// @Param request body dto.AgentAccountModelCreateReq true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts/models/create [post]
|
// @Router /ai/accounts/models/create [post]
|
||||||
func (b *BaseApi) CreateAgentAccountModel(c *gin.Context) {
|
func (b *BaseApi) CreateAgentAccountModel(c *gin.Context) {
|
||||||
var req dto.AgentAccountModelCreateReq
|
var req dto.AgentAccountModelCreateReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -335,13 +542,13 @@ func (b *BaseApi) CreateAgentAccountModel(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Update Agent account model
|
// @Summary Update model account model
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountModelUpdateReq true "request"
|
// @Param request body dto.AgentAccountModelUpdateReq true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts/models/update [post]
|
// @Router /ai/accounts/models/update [post]
|
||||||
func (b *BaseApi) UpdateAgentAccountModel(c *gin.Context) {
|
func (b *BaseApi) UpdateAgentAccountModel(c *gin.Context) {
|
||||||
var req dto.AgentAccountModelUpdateReq
|
var req dto.AgentAccountModelUpdateReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -355,13 +562,13 @@ func (b *BaseApi) UpdateAgentAccountModel(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Delete Agent account model
|
// @Summary Delete model account model
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountModelDeleteReq true "request"
|
// @Param request body dto.AgentAccountModelDeleteReq true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts/models/delete [post]
|
// @Router /ai/accounts/models/delete [post]
|
||||||
func (b *BaseApi) DeleteAgentAccountModel(c *gin.Context) {
|
func (b *BaseApi) DeleteAgentAccountModel(c *gin.Context) {
|
||||||
var req dto.AgentAccountModelDeleteReq
|
var req dto.AgentAccountModelDeleteReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -375,13 +582,13 @@ func (b *BaseApi) DeleteAgentAccountModel(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Verify Agent account
|
// @Summary Verify model account
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountVerifyReq true "request"
|
// @Param request body dto.AgentAccountVerifyReq true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts/verify [post]
|
// @Router /ai/accounts/verify [post]
|
||||||
func (b *BaseApi) VerifyAgentAccount(c *gin.Context) {
|
func (b *BaseApi) VerifyAgentAccount(c *gin.Context) {
|
||||||
var req dto.AgentAccountVerifyReq
|
var req dto.AgentAccountVerifyReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -395,13 +602,13 @@ func (b *BaseApi) VerifyAgentAccount(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Delete Agent account
|
// @Summary Delete model account
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.AgentAccountDeleteReq true "request"
|
// @Param request body dto.AgentAccountDeleteReq true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /ai/agents/accounts/delete [post]
|
// @Router /ai/accounts/delete [post]
|
||||||
func (b *BaseApi) DeleteAgentAccount(c *gin.Context) {
|
func (b *BaseApi) DeleteAgentAccount(c *gin.Context) {
|
||||||
var req dto.AgentAccountDeleteReq
|
var req dto.AgentAccountDeleteReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -783,6 +990,27 @@ func (b *BaseApi) UpdateAgentDingTalkConfig(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Get Agent Weixin channel config
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentIDReq true "request"
|
||||||
|
// @Success 200 {object} dto.AgentWeixinConfig
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/channel/weixin/get [post]
|
||||||
|
func (b *BaseApi) GetAgentWeixinConfig(c *gin.Context) {
|
||||||
|
var req dto.AgentIDReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := agentService.GetWeixinConfig(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Get Agent QQ Bot channel config
|
// @Summary Get Agent QQ Bot channel config
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -824,6 +1052,26 @@ func (b *BaseApi) UpdateAgentQQBotConfig(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Delete Agent channel config
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentChannelDeleteReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/channel/delete [post]
|
||||||
|
func (b *BaseApi) DeleteAgentChannelConfig(c *gin.Context) {
|
||||||
|
var req dto.AgentChannelDeleteReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := agentService.DeleteChannelConfig(req); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Install Agent plugin
|
// @Summary Install Agent plugin
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -1110,6 +1358,108 @@ func (b *BaseApi) InstallAgentSkill(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Uninstall Agent skill
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentSkillUninstallReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/skills/uninstall [post]
|
||||||
|
func (b *BaseApi) UninstallAgentSkill(c *gin.Context) {
|
||||||
|
var req dto.AgentSkillUninstallReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := agentService.UninstallSkill(req); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary List OpenClaw plugins
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentPluginsReq true "request"
|
||||||
|
// @Success 200 {array} dto.AgentPluginItem
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/plugins/list [post]
|
||||||
|
func (b *BaseApi) ListAgentPlugins(c *gin.Context) {
|
||||||
|
var req dto.AgentPluginsReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := agentService.ListPlugins(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Search OpenClaw plugins
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentPluginSearchReq true "request"
|
||||||
|
// @Success 200 {array} dto.AgentPluginSearchItem
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/plugins/search [post]
|
||||||
|
func (b *BaseApi) SearchAgentPlugins(c *gin.Context) {
|
||||||
|
var req dto.AgentPluginSearchReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := agentService.SearchPlugins(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Install an OpenClaw marketplace plugin
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentPluginMarketInstallReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/plugins/install [post]
|
||||||
|
func (b *BaseApi) InstallAgentMarketPlugin(c *gin.Context) {
|
||||||
|
var req dto.AgentPluginMarketInstallReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := agentService.InstallMarketPlugin(req); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Operate an OpenClaw plugin
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AgentPluginOperateReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/agents/plugins/operate [post]
|
||||||
|
func (b *BaseApi) OperateAgentPlugin(c *gin.Context) {
|
||||||
|
var req dto.AgentPluginOperateReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := agentService.OperatePlugin(req); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Login Agent Weixin channel
|
// @Summary Login Agent Weixin channel
|
||||||
// @Accept json
|
// @Accept json
|
||||||
|
|||||||
+9
-42
@@ -3,9 +3,6 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/dto"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/ai_tools/gpu"
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/ai_tools/gpu/common"
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/ai_tools/xpu"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -163,37 +160,6 @@ func (b *BaseApi) DeleteOllamaModel(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags AI
|
|
||||||
// @Summary Load gpu / xpu info
|
|
||||||
// @Accept json
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /ai/gpu/load [get]
|
|
||||||
func (b *BaseApi) LoadGpuInfo(c *gin.Context) {
|
|
||||||
ok, client := gpu.New()
|
|
||||||
if ok {
|
|
||||||
info, err := client.LoadGpuInfo()
|
|
||||||
if err != nil {
|
|
||||||
helper.BadRequest(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, info)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
xpuOK, xpuClient := xpu.New()
|
|
||||||
if xpuOK {
|
|
||||||
info, err := xpuClient.LoadGpuInfo()
|
|
||||||
if err != nil {
|
|
||||||
helper.BadRequest(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, info)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, &common.GpuInfo{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags AI
|
// @Tags AI
|
||||||
// @Summary Bind domain
|
// @Summary Bind domain
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -235,14 +201,15 @@ func (b *BaseApi) GetBindDomain(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, res)
|
helper.SuccessWithData(c, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags AI
|
// @Tags AI
|
||||||
// Summary Update bind domain
|
// @Summary Update bind domain
|
||||||
// Accept json
|
// @Accept json
|
||||||
// Param request body dto.OllamaBindDomain true "request"
|
// @Param request body dto.OllamaBindDomain true "request"
|
||||||
// Success 200
|
// @Success 200
|
||||||
// Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// Security Timestamp
|
// @Security Timestamp
|
||||||
// Router /ai/domain/update [post]
|
// @Router /ai/domain/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["domain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 Ollama 绑定域名 [domain]","formatEN":"update Ollama bind domain [domain]"}
|
||||||
func (b *BaseApi) UpdateBindDomain(c *gin.Context) {
|
func (b *BaseApi) UpdateBindDomain(c *gin.Context) {
|
||||||
var req dto.OllamaBindDomain
|
var req dto.OllamaBindDomain
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
+199
-4
@@ -2,11 +2,27 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const defaultAuditUser = "system"
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Page alert
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertSearch true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/search [post]
|
||||||
func (b *BaseApi) PageAlert(c *gin.Context) {
|
func (b *BaseApi) PageAlert(c *gin.Context) {
|
||||||
var req dto.AlertSearch
|
var req dto.AlertSearch
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -32,12 +48,21 @@ func (b *BaseApi) GetAlerts(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, alerts)
|
helper.SuccessWithData(c, alerts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Create alert
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["title"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建告警任务 [title]","formatEN":"create alert [title]"}
|
||||||
func (b *BaseApi) CreateAlert(c *gin.Context) {
|
func (b *BaseApi) CreateAlert(c *gin.Context) {
|
||||||
var req dto.AlertCreate
|
var req dto.AlertCreate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := alertService.CreateAlert(req)
|
err := alertService.CreateAlert(req, loadAuditUser(c))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
@@ -45,6 +70,15 @@ func (b *BaseApi) CreateAlert(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Delete alert
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.DeleteRequest true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除告警任务 [id]","formatEN":"delete alert [id]"}
|
||||||
func (b *BaseApi) DeleteAlert(c *gin.Context) {
|
func (b *BaseApi) DeleteAlert(c *gin.Context) {
|
||||||
var req dto.DeleteRequest
|
var req dto.DeleteRequest
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -58,12 +92,21 @@ func (b *BaseApi) DeleteAlert(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Update alert
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["title"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新告警任务 [title]","formatEN":"update alert [title]"}
|
||||||
func (b *BaseApi) UpdateAlert(c *gin.Context) {
|
func (b *BaseApi) UpdateAlert(c *gin.Context) {
|
||||||
var req dto.AlertUpdate
|
var req dto.AlertUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := alertService.UpdateAlert(req); err != nil {
|
if err := alertService.UpdateAlert(req, loadAuditUser(c)); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -84,6 +127,15 @@ func (b *BaseApi) GetAlert(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, alert)
|
helper.SuccessWithData(c, alert)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Update alert status
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertUpdateStatus true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/status [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新告警任务 [id] 状态 [status]","formatEN":"update alert [id] status [status]"}
|
||||||
func (b *BaseApi) UpdateAlertStatus(c *gin.Context) {
|
func (b *BaseApi) UpdateAlertStatus(c *gin.Context) {
|
||||||
var req dto.AlertUpdateStatus
|
var req dto.AlertUpdateStatus
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -97,6 +149,12 @@ func (b *BaseApi) UpdateAlertStatus(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Get disks
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/disks/list [get]
|
||||||
func (b *BaseApi) GetDisks(c *gin.Context) {
|
func (b *BaseApi) GetDisks(c *gin.Context) {
|
||||||
alerts, err := alertService.GetDisks()
|
alerts, err := alertService.GetDisks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -106,6 +164,14 @@ func (b *BaseApi) GetDisks(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, alerts)
|
helper.SuccessWithData(c, alerts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Page alert logs
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertLogSearch true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/logs/search [post]
|
||||||
func (b *BaseApi) PageAlertLogs(c *gin.Context) {
|
func (b *BaseApi) PageAlertLogs(c *gin.Context) {
|
||||||
var req dto.AlertLogSearch
|
var req dto.AlertLogSearch
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -122,6 +188,13 @@ func (b *BaseApi) PageAlertLogs(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Clean alert logs
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/logs/clean [post]
|
||||||
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空告警日志","formatEN":"clean alert logs"}
|
||||||
func (b *BaseApi) CleanAlertLogs(c *gin.Context) {
|
func (b *BaseApi) CleanAlertLogs(c *gin.Context) {
|
||||||
if err := alertService.CleanAlertLogs(); err != nil {
|
if err := alertService.CleanAlertLogs(); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
@@ -130,6 +203,12 @@ func (b *BaseApi) CleanAlertLogs(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Get clams
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/clams/list [get]
|
||||||
func (b *BaseApi) GetClams(c *gin.Context) {
|
func (b *BaseApi) GetClams(c *gin.Context) {
|
||||||
clams, err := alertService.GetClams()
|
clams, err := alertService.GetClams()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -139,6 +218,14 @@ func (b *BaseApi) GetClams(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, clams)
|
helper.SuccessWithData(c, clams)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Get cron jobs
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.CronJobReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/cronjob/list [post]
|
||||||
func (b *BaseApi) GetCronJobs(c *gin.Context) {
|
func (b *BaseApi) GetCronJobs(c *gin.Context) {
|
||||||
var req dto.CronJobReq
|
var req dto.CronJobReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -152,8 +239,18 @@ func (b *BaseApi) GetCronJobs(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, cronJobs)
|
helper.SuccessWithData(c, cronJobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Get alert config
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/config/info [post]
|
||||||
func (b *BaseApi) GetAlertConfig(c *gin.Context) {
|
func (b *BaseApi) GetAlertConfig(c *gin.Context) {
|
||||||
config, err := alertService.GetAlertConfig()
|
var req dto.AlertConfigQuery
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config, err := alertService.GetAlertConfig(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
@@ -161,18 +258,99 @@ func (b *BaseApi) GetAlertConfig(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, config)
|
helper.SuccessWithData(c, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Page alert config
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertConfigPageReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/config/search [post]
|
||||||
|
func (b *BaseApi) PageAlertConfig(c *gin.Context) {
|
||||||
|
var req dto.AlertConfigPageReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, configs, err := alertService.PageAlertConfig(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{
|
||||||
|
Total: total,
|
||||||
|
Items: configs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Update alert config
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertConfigUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/config/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","displayName"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新告警配置 [id][displayName]","formatEN":"update alert config [id][displayName]"}
|
||||||
func (b *BaseApi) UpdateAlertConfig(c *gin.Context) {
|
func (b *BaseApi) UpdateAlertConfig(c *gin.Context) {
|
||||||
var req dto.AlertConfigUpdate
|
var req dto.AlertConfigUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := alertService.UpdateAlertConfig(req); err != nil {
|
if err := alertService.UpdateAlertConfig(req, loadAuditUser(c)); err != nil {
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, repo.ErrAlertConfigRevisionConflict):
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusConflict, "ALERT_CONFIG_REVISION_CONFLICT", "ErrInvalidParams", err)
|
||||||
|
case errors.Is(err, repo.ErrAlertConfigRevisionRequired):
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusConflict, "ALERT_CONFIG_REVISION_REQUIRED", "ErrInvalidParams", err)
|
||||||
|
default:
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Update alert config status
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertConfigStatusUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/config/status [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新告警配置状态 [id][status]","formatEN":"update alert config status [id][status]"}
|
||||||
|
func (b *BaseApi) UpdateAlertConfigStatus(c *gin.Context) {
|
||||||
|
var req dto.AlertConfigStatusUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := alertService.UpdateAlertConfigStatus(req, loadAuditUser(c)); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadAuditUser(c *gin.Context) string {
|
||||||
|
userName := strings.TrimSpace(c.GetHeader("X-Panel-User"))
|
||||||
|
if userName == "" {
|
||||||
|
return defaultAuditUser
|
||||||
|
}
|
||||||
|
if decoded, err := url.QueryUnescape(userName); err == nil {
|
||||||
|
return decoded
|
||||||
|
}
|
||||||
|
return userName
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Delete alert config
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.DeleteRequest true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/config/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除告警配置 [id]","formatEN":"delete alert config [id]"}
|
||||||
func (b *BaseApi) DeleteAlertConfig(c *gin.Context) {
|
func (b *BaseApi) DeleteAlertConfig(c *gin.Context) {
|
||||||
var req dto.DeleteRequest
|
var req dto.DeleteRequest
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -186,11 +364,28 @@ func (b *BaseApi) DeleteAlertConfig(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Alert
|
||||||
|
// @Summary Test alert config
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.AlertConfigTest true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /alert/config/test [post]
|
||||||
func (b *BaseApi) TestAlertConfig(c *gin.Context) {
|
func (b *BaseApi) TestAlertConfig(c *gin.Context) {
|
||||||
var req dto.AlertConfigTest
|
var req dto.AlertConfigTest
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if req.Type == constant.Custom {
|
||||||
|
result, err := alertService.TestCustomAlertConfig(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
return
|
||||||
|
}
|
||||||
flag, err := alertService.TestAlertConfig(req)
|
flag, err := alertService.TestAlertConfig(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
|
|||||||
+10
-4
@@ -107,7 +107,7 @@ func (b *BaseApi) GetApp(c *gin.Context) {
|
|||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param appId path integer true "app id"
|
// @Param appId path integer true "app id"
|
||||||
// @Param version path string true "app 版本"
|
// @Param version path string true "app 版本"
|
||||||
// @Param version path string true "app 类型"
|
// @Param type path string true "app 类型"
|
||||||
// @Success 200 {object} response.AppDetailDTO
|
// @Success 200 {object} response.AppDetailDTO
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
@@ -131,7 +131,7 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
|||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Get app detail by id
|
// @Summary Get app detail by id
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param appId path integer true "id"
|
// @Param id path integer true "id"
|
||||||
// @Success 200 {object} response.AppDetailDTO
|
// @Success 200 {object} response.AppDetailDTO
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
@@ -172,6 +172,12 @@ func (b *BaseApi) InstallApp(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, install)
|
helper.SuccessWithData(c, install)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags App
|
||||||
|
// @Summary Get app tags
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /apps/tags [get]
|
||||||
func (b *BaseApi) GetAppTags(c *gin.Context) {
|
func (b *BaseApi) GetAppTags(c *gin.Context) {
|
||||||
tags, err := appService.GetAppTags(c)
|
tags, err := appService.GetAppTags(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -199,7 +205,7 @@ func (b *BaseApi) GetAppListUpdate(c *gin.Context) {
|
|||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Get app icon by app_id
|
// @Summary Get app icon by app_id
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param appId path integer true "app id"
|
// @Param key path string true "app key"
|
||||||
// @Success 200 {file} file "app icon"
|
// @Success 200 {file} file "app icon"
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
@@ -237,7 +243,7 @@ func (b *BaseApi) GetAppIcon(c *gin.Context) {
|
|||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Search app detail by appkey and version
|
// @Summary Search app detail by appkey and version
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param appId path integer true "app key"
|
// @Param appKey path string true "app key"
|
||||||
// @Param version path string true "app version"
|
// @Param version path string true "app version"
|
||||||
// @Success 200 {object} response.AppDetailSimpleDTO
|
// @Success 200 {object} response.AppDetailSimpleDTO
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
|
|||||||
@@ -203,7 +203,6 @@ func (b *BaseApi) GetServices(c *gin.Context) {
|
|||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Search app update version by install id
|
// @Summary Search app update version by install id
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param appInstallId path integer true "request"
|
|
||||||
// @Success 200 {array} dto.AppVersion
|
// @Success 200 {array} dto.AppVersion
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
@@ -267,7 +266,7 @@ func (b *BaseApi) GetDefaultConfig(c *gin.Context) {
|
|||||||
// @Tags App
|
// @Tags App
|
||||||
// @Summary Search params by appInstallId
|
// @Summary Search params by appInstallId
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param appInstallId path string true "request"
|
// @Param appInstallId path integer true "request"
|
||||||
// @Success 200 {object} response.AppConfig
|
// @Success 200 {object} response.AppConfig
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
@@ -350,6 +349,15 @@ func (b *BaseApi) GetAppInstallInfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, info)
|
helper.SuccessWithData(c, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags App
|
||||||
|
// @Summary Update app install sort
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.AppInstallSort true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /apps/installed/sort/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新已安装应用排序","formatEN":"update installed app sort"}
|
||||||
func (b *BaseApi) UpdateAppInstallSort(c *gin.Context) {
|
func (b *BaseApi) UpdateAppInstallSort(c *gin.Context) {
|
||||||
var req request.AppInstallSort
|
var req request.AppInstallSort
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @Tags Backup Account
|
||||||
|
// @Summary Check backup used
|
||||||
|
// @Param name path string true "name"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /backups/check/{name} [get]
|
||||||
func (b *BaseApi) CheckBackupUsed(c *gin.Context) {
|
func (b *BaseApi) CheckBackupUsed(c *gin.Context) {
|
||||||
name, err := helper.GetStrParamByKey(c, "name")
|
name, err := helper.GetStrParamByKey(c, "name")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -32,7 +39,7 @@ func (b *BaseApi) CheckBackupUsed(c *gin.Context) {
|
|||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /backups/check [post]
|
// @Router /backups/conn/check [post]
|
||||||
func (b *BaseApi) CheckBackup(c *gin.Context) {
|
func (b *BaseApi) CheckBackup(c *gin.Context) {
|
||||||
var req dto.BackupOperate
|
var req dto.BackupOperate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -136,7 +143,7 @@ func (b *BaseApi) DeleteBackup(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /backups/update [post]
|
// @Router /backups/update [post]
|
||||||
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新备份账号 [types]","formatEN":"update backup account [types]"}
|
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新备份账号 [type]","formatEN":"update backup account [type]"}
|
||||||
func (b *BaseApi) UpdateBackup(c *gin.Context) {
|
func (b *BaseApi) UpdateBackup(c *gin.Context) {
|
||||||
var req dto.BackupOperate
|
var req dto.BackupOperate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -406,15 +413,25 @@ func (b *BaseApi) Backup(c *gin.Context) {
|
|||||||
|
|
||||||
switch req.Type {
|
switch req.Type {
|
||||||
case "app":
|
case "app":
|
||||||
if _, err := backupService.AppBackup(req); err != nil {
|
record, err := backupService.AppBackup(req)
|
||||||
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if req.IsImmediate {
|
||||||
|
helper.SuccessWithData(c, record)
|
||||||
|
return
|
||||||
|
}
|
||||||
case "mysql", "mariadb", constant.AppMysqlCluster:
|
case "mysql", "mariadb", constant.AppMysqlCluster:
|
||||||
if err := backupService.MysqlBackup(req); err != nil {
|
if err := backupService.MysqlBackup(req); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case "mongodb":
|
||||||
|
if err := backupService.MongodbBackup(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
||||||
if err := backupService.PostgresqlBackup(req); err != nil {
|
if err := backupService.PostgresqlBackup(req); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
@@ -475,6 +492,11 @@ func (b *BaseApi) Recover(c *gin.Context) {
|
|||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case "mongodb":
|
||||||
|
if err := backupService.MongodbRecover(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
||||||
if err := backupService.PostgresqlRecover(req); err != nil {
|
if err := backupService.PostgresqlRecover(req); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
@@ -530,6 +552,11 @@ func (b *BaseApi) RecoverByUpload(c *gin.Context) {
|
|||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case "mongodb":
|
||||||
|
if err := backupService.MongodbRecoverByUpload(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
case constant.AppPostgresql, constant.AppPostgresqlCluster:
|
||||||
if err := backupService.PostgresqlRecoverByUpload(req); err != nil {
|
if err := backupService.PostgresqlRecoverByUpload(req); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func (b *BaseApi) CreateClam(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := clamService.Create(req); err != nil {
|
if err := clamService.Create(req, loadAuditUser(c)); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ func (b *BaseApi) UpdateClam(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := clamService.Update(req); err != nil {
|
if err := clamService.Update(req, loadAuditUser(c)); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ func (b *BaseApi) LoadClamBaseInfo(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /toolbox/clam/operate [post]
|
// @Router /toolbox/clam/operate [post]
|
||||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] Clam","formatEN":"[operation] FTP"}
|
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] Clam","formatEN":"[operation] Clam"}
|
||||||
func (b *BaseApi) OperateClam(c *gin.Context) {
|
func (b *BaseApi) OperateClam(c *gin.Context) {
|
||||||
var req dto.Operate
|
var req dto.Operate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/dto"
|
||||||
@@ -394,6 +395,7 @@ func (b *BaseApi) ContainerInfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
// @Summary Load container limits
|
// @Summary Load container limits
|
||||||
// @Success 200 {object} dto.ResourceLimit
|
// @Success 200 {object} dto.ResourceLimit
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
@@ -408,6 +410,7 @@ func (b *BaseApi) LoadResourceLimit(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
// @Summary Load container stats
|
// @Summary Load container stats
|
||||||
// @Success 200 {array} dto.ContainerListStats
|
// @Success 200 {array} dto.ContainerListStats
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
@@ -422,6 +425,7 @@ func (b *BaseApi) ContainerListStats(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
// @Summary Load container stats size
|
// @Summary Load container stats size
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.OperationWithName true "request"
|
// @Param request body dto.OperationWithName true "request"
|
||||||
@@ -435,7 +439,7 @@ func (b *BaseApi) ContainerItemStats(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := containerService.ContainerItemStats(req)
|
data, err := containerService.ContainerItemStats(c.Request.Context(), req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
@@ -662,6 +666,14 @@ func (b *BaseApi) Inspect(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, result)
|
helper.SuccessWithData(c, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
|
// @Summary Download container logs
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ContainerLog true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/download/log [post]
|
||||||
func (b *BaseApi) DownloadContainerLogs(c *gin.Context) {
|
func (b *BaseApi) DownloadContainerLogs(c *gin.Context) {
|
||||||
var req dto.ContainerLog
|
var req dto.ContainerLog
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -869,6 +881,26 @@ func (b *BaseApi) ComposeUpdate(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Container Compose
|
||||||
|
// @Summary Pin compose
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ComposePin true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/compose/pin [post]
|
||||||
|
func (b *BaseApi) ComposePin(c *gin.Context) {
|
||||||
|
var req dto.ComposePin
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := containerService.ComposePin(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Container Compose
|
// @Tags Container Compose
|
||||||
// @Summary Load compose environment variables
|
// @Summary Load compose environment variables
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -901,6 +933,10 @@ func (b *BaseApi) LoadComposeEnv(c *gin.Context) {
|
|||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /containers/search/log [get]
|
// @Router /containers/search/log [get]
|
||||||
func (b *BaseApi) ContainerStreamLogs(c *gin.Context) {
|
func (b *BaseApi) ContainerStreamLogs(c *gin.Context) {
|
||||||
|
if !strings.Contains(strings.ToLower(c.GetHeader("Accept")), "text/event-stream") {
|
||||||
|
helper.Success(c)
|
||||||
|
return
|
||||||
|
}
|
||||||
c.Header("Content-Type", "text/event-stream")
|
c.Header("Content-Type", "text/event-stream")
|
||||||
c.Header("Cache-Control", "no-cache")
|
c.Header("Cache-Control", "no-cache")
|
||||||
c.Header("Connection", "keep-alive")
|
c.Header("Connection", "keep-alive")
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func (b *BaseApi) CreateCronjob(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cronjobService.Create(req); err != nil {
|
if err := cronjobService.Create(req, loadAuditUser(c)); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ func (b *BaseApi) ImportCronjob(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cronjobService.Import(req.Cronjobs); err != nil {
|
if err := cronjobService.Import(req.Cronjobs, loadAuditUser(c)); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -285,7 +285,7 @@ func (b *BaseApi) UpdateCronjob(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cronjobService.Update(req.ID, req); err != nil {
|
if err := cronjobService.Update(req.ID, req, loadAuditUser(c)); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ func (b *BaseApi) SearchDatabase(c *gin.Context) {
|
|||||||
// @Success 200 {array} dto.DatabaseOption
|
// @Success 200 {array} dto.DatabaseOption
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
// @Param type path string true "type"
|
||||||
// @Router /databases/db/list/:type [get]
|
// @Router /databases/db/list/:type [get]
|
||||||
func (b *BaseApi) ListDatabase(c *gin.Context) {
|
func (b *BaseApi) ListDatabase(c *gin.Context) {
|
||||||
dbType, err := helper.GetStrParamByKey(c, "type")
|
dbType, err := helper.GetStrParamByKey(c, "type")
|
||||||
@@ -116,6 +117,7 @@ func (b *BaseApi) ListDatabase(c *gin.Context) {
|
|||||||
// @Success 200 {array} dto.DatabaseItem
|
// @Success 200 {array} dto.DatabaseItem
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
// @Param type path string true "type"
|
||||||
// @Router /databases/db/item/:type [get]
|
// @Router /databases/db/item/:type [get]
|
||||||
func (b *BaseApi) LoadDatabaseItems(c *gin.Context) {
|
func (b *BaseApi) LoadDatabaseItems(c *gin.Context) {
|
||||||
dbType, err := helper.GetStrParamByKey(c, "type")
|
dbType, err := helper.GetStrParamByKey(c, "type")
|
||||||
@@ -137,6 +139,7 @@ func (b *BaseApi) LoadDatabaseItems(c *gin.Context) {
|
|||||||
// @Success 200 {object} dto.DatabaseInfo
|
// @Success 200 {object} dto.DatabaseInfo
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
// @Param name path string true "name"
|
||||||
// @Router /databases/db/:name [get]
|
// @Router /databases/db/:name [get]
|
||||||
func (b *BaseApi) GetDatabase(c *gin.Context) {
|
func (b *BaseApi) GetDatabase(c *gin.Context) {
|
||||||
name, err := helper.GetStrParamByKey(c, "name")
|
name, err := helper.GetStrParamByKey(c, "name")
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Create mongodb database
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbDBCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 mongodb 数据库 [name]","formatEN":"create mongodb database [name]"}
|
||||||
|
func (b *BaseApi) CreateMongodb(c *gin.Context) {
|
||||||
|
var req dto.MongodbDBCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := mongodbService.Create(context.Background(), req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Page mongodb databases
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbDBSearch true "request"
|
||||||
|
// @Success 200 {object} dto.PageResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/search [post]
|
||||||
|
func (b *BaseApi) SearchMongodb(c *gin.Context) {
|
||||||
|
var req dto.MongodbDBSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
total, list, err := mongodbService.SearchWithPage(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{
|
||||||
|
Items: list,
|
||||||
|
Total: total,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Update mongodb database description
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.UpdateDescription true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/description [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mongodbs","output_column":"name","output_value":"name"}],"formatZH":"mongodb 数据库 [name] 描述信息修改 [description]","formatEN":"The description of the mongodb database [name] is modified => [description]"}
|
||||||
|
func (b *BaseApi) UpdateMongodbDescription(c *gin.Context) {
|
||||||
|
var req dto.UpdateDescription
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mongodbService.UpdateDescription(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Load mongodb database from remote
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbLoadDB true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/load [post]
|
||||||
|
func (b *BaseApi) LoadMongodbFromRemote(c *gin.Context) {
|
||||||
|
var req dto.MongodbLoadDB
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mongodbService.LoadFromRemote(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Bind mongodb database user info
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbBind true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/bind [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database", "name", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"绑定 mongodb 数据库 [database] [name] 用户 [username]","formatEN":"bind mongodb database [database] [name] user [username]"}
|
||||||
|
func (b *BaseApi) BindMongodbUser(c *gin.Context) {
|
||||||
|
var req dto.MongodbBind
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mongodbService.BindUser(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Change mongodb database password
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbPassword true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/password [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database", "name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mongodb 数据库 [database] [name] 密码","formatEN":"update mongodb database [database] [name] password"}
|
||||||
|
func (b *BaseApi) ChangeMongodbPassword(c *gin.Context) {
|
||||||
|
var req dto.MongodbPassword
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mongodbService.ChangePassword(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Change mongodb root password
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ChangeDBInfo true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/root/password [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mongodb 数据库 [database] root 密码","formatEN":"update mongodb database [database] root password"}
|
||||||
|
func (b *BaseApi) ChangeMongodbRootPassword(c *gin.Context) {
|
||||||
|
var req dto.ChangeDBInfo
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Value) != 0 {
|
||||||
|
value, err := base64.StdEncoding.DecodeString(req.Value)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Value = string(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mongodbService.ChangeRootPassword(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Load mongodb privileges
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbPrivilegesLoad true "request"
|
||||||
|
// @Success 200 {string} string
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/privileges [post]
|
||||||
|
func (b *BaseApi) LoadMongodbPrivileges(c *gin.Context) {
|
||||||
|
var req dto.MongodbPrivilegesLoad
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
permission, err := mongodbService.LoadPrivileges(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, permission)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Change mongodb privileges
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbPrivileges true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/privileges/change [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mongodb 数据库 [database] 用户 [username] 权限","formatEN":"update mongodb database [database] user [username] privileges"}
|
||||||
|
func (b *BaseApi) ChangeMongodbPrivileges(c *gin.Context) {
|
||||||
|
var req dto.MongodbPrivileges
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mongodbService.ChangePrivileges(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Check before delete mongodb database
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbDBDeleteCheck true "request"
|
||||||
|
// @Success 200 {array} string
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/del/check [post]
|
||||||
|
func (b *BaseApi) DeleteCheckMongodb(c *gin.Context) {
|
||||||
|
var req dto.MongodbDBDeleteCheck
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apps, err := mongodbService.DeleteCheck(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, apps)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mongodb
|
||||||
|
// @Summary Delete mongodb database
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MongodbDBDelete true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/mongodb/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mongodbs","output_column":"name","output_value":"name"}],"formatZH":"删除 mongodb 数据库 [name]","formatEN":"delete mongodb database [name]"}
|
||||||
|
func (b *BaseApi) DeleteMongodb(c *gin.Context) {
|
||||||
|
var req dto.MongodbDBDelete
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, ctx := helper.GetTxAndContext()
|
||||||
|
if err := mongodbService.Delete(ctx, req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
tx.Rollback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tx.Commit()
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
@@ -41,20 +41,40 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Database Mysql
|
// @Tags Database Mysql
|
||||||
// @Summary Bind user of mysql database
|
// @Summary List mysql users
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.BindUser true "request"
|
// @Param request body dto.MysqlUserSearch true "request"
|
||||||
// @Success 200
|
// @Success 200 {array} dto.MysqlUser
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /databases/bind [post]
|
// @Router /databases/users/search [post]
|
||||||
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"绑定 mysql 数据库名 [database] [username]","formatEN":"bind mysql database [database] [username]"}
|
func (b *BaseApi) ListMysqlUsers(c *gin.Context) {
|
||||||
func (b *BaseApi) BindUser(c *gin.Context) {
|
var req dto.MysqlUserSearch
|
||||||
var req dto.BindUser
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
data, err := mysqlService.ListUsers(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mysql
|
||||||
|
// @Summary Create mysql user
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlUserCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/users [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database","username","host"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 mysql 数据库 [database] 用户 [username]@[host]","formatEN":"create mysql database [database] user [username]@[host]"}
|
||||||
|
func (b *BaseApi) CreateMysqlUser(c *gin.Context) {
|
||||||
|
var req dto.MysqlUserCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
if len(req.Password) != 0 {
|
if len(req.Password) != 0 {
|
||||||
password, err := base64.StdEncoding.DecodeString(req.Password)
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -63,8 +83,191 @@ func (b *BaseApi) BindUser(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
req.Password = string(password)
|
req.Password = string(password)
|
||||||
}
|
}
|
||||||
|
if err := mysqlService.CreateUser(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
if err := mysqlService.BindUser(req); err != nil {
|
// @Tags Database Mysql
|
||||||
|
// @Summary Delete mysql user
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlUserDelete true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/users/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database","username","host"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除 mysql 数据库 [database] 用户 [username]@[host]","formatEN":"delete mysql database [database] user [username]@[host]"}
|
||||||
|
func (b *BaseApi) DeleteMysqlUser(c *gin.Context) {
|
||||||
|
var req dto.MysqlUserDelete
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := mysqlService.DeleteUser(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mysql
|
||||||
|
// @Summary Update mysql user
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlUserUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/users/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database","username","host","newHost","description"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mysql 数据库 [database] 用户 [username] 访问权限 [host] => [newHost] 描述 [description]","formatEN":"update mysql database [database] user [username] access [host] => [newHost] description [description]"}
|
||||||
|
func (b *BaseApi) UpdateMysqlUser(c *gin.Context) {
|
||||||
|
var req dto.MysqlUserUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := mysqlService.UpdateUser(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mysql
|
||||||
|
// @Summary Change mysql user password
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlUserPassword true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/users/password [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database","username","host"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 mysql 数据库 [database] 用户 [username]@[host] 密码","formatEN":"update mysql database [database] user [username]@[host] password"}
|
||||||
|
func (b *BaseApi) ChangeMysqlUserPassword(c *gin.Context) {
|
||||||
|
var req dto.MysqlUserPassword
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
if err := mysqlService.ChangeUserPassword(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mysql
|
||||||
|
// @Summary Save mysql user password locally
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlUserPassword true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/users/password/save [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database","username","host"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"补充 mysql 数据库 [database] 用户 [username]@[host] 密码","formatEN":"save mysql database [database] user [username]@[host] password locally"}
|
||||||
|
func (b *BaseApi) SaveMysqlUserPassword(c *gin.Context) {
|
||||||
|
var req dto.MysqlUserPassword
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
if err := mysqlService.SaveUserPassword(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mysql
|
||||||
|
// @Summary List mysql grants
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlUserSearch true "request"
|
||||||
|
// @Success 200 {array} dto.MysqlGrant
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/grants/search [post]
|
||||||
|
func (b *BaseApi) ListMysqlGrants(c *gin.Context) {
|
||||||
|
var req dto.MysqlUserSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := mysqlService.ListGrants(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mysql
|
||||||
|
// @Summary List mysql grant summary
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlGrantSummarySearch true "request"
|
||||||
|
// @Success 200 {object} map[string][]dto.MysqlUser
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/grants/summary [post]
|
||||||
|
func (b *BaseApi) ListMysqlGrantSummary(c *gin.Context) {
|
||||||
|
var req dto.MysqlGrantSummarySearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := mysqlService.ListGrantSummary(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mysql
|
||||||
|
// @Summary Grant mysql user
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlGrantCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/grants [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database","db","username","host"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"授权 mysql 数据库 [database] 用户 [username]@[host] 访问 [db]","formatEN":"grant mysql database [database] user [username]@[host] access to [db]"}
|
||||||
|
func (b *BaseApi) GrantMysqlUser(c *gin.Context) {
|
||||||
|
var req dto.MysqlGrantCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := mysqlService.GrantUser(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Database Mysql
|
||||||
|
// @Summary Revoke mysql grant
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.MysqlGrantDelete true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/grants/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["database","db","username","host"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"取消 mysql 数据库 [database] 用户 [username]@[host] 对 [db] 的授权","formatEN":"revoke mysql database [database] user [username]@[host] access to [db]"}
|
||||||
|
func (b *BaseApi) RevokeMysqlGrant(c *gin.Context) {
|
||||||
|
var req dto.MysqlGrantDelete
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := mysqlService.RevokeGrant(req); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -94,14 +297,14 @@ func (b *BaseApi) UpdateMysqlDescription(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Database Mysql
|
// @Tags Database Mysql
|
||||||
// @Summary Change mysql password
|
// @Summary Change mysql root password
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.ChangeDBInfo true "request"
|
// @Param request body dto.ChangeDBInfo true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /databases/change/password [post]
|
// @Router /databases/change/password [post]
|
||||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 密码","formatEN":"Update database [name] password"}
|
// @x-panel-log {"bodyKeys":["database"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新数据库 [database] root 密码","formatEN":"Update database [database] root password"}
|
||||||
func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
|
func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
|
||||||
var req dto.ChangeDBInfo
|
var req dto.ChangeDBInfo
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -125,14 +328,14 @@ func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Database Mysql
|
// @Tags Database Mysql
|
||||||
// @Summary Change mysql access
|
// @Summary Change mysql root access
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.ChangeDBInfo true "request"
|
// @Param request body dto.ChangeDBInfo true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /databases/change/access [post]
|
// @Router /databases/change/access [post]
|
||||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 访问权限","formatEN":"Update database [name] access"}
|
// @x-panel-log {"bodyKeys":["database"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新数据库 [database] root 访问权限","formatEN":"Update database [database] root access"}
|
||||||
func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) {
|
func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) {
|
||||||
var req dto.ChangeDBInfo
|
var req dto.ChangeDBInfo
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (b *BaseApi) UpdatePostgresqlDescription(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /databases/pg/privileges [post]
|
// @Router /databases/pg/privileges [post]
|
||||||
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新数据库 [database] 用户 [username] 权限","formatEN":"Update [user] privileges of database [database]"}
|
// @x-panel-log {"bodyKeys":["database", "username"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新数据库 [database] 用户 [username] 权限","formatEN":"Update [username] privileges of database [database]"}
|
||||||
func (b *BaseApi) ChangePostgresqlPrivileges(c *gin.Context) {
|
func (b *BaseApi) ChangePostgresqlPrivileges(c *gin.Context) {
|
||||||
var req dto.PostgresqlPrivileges
|
var req dto.PostgresqlPrivileges
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -170,6 +170,7 @@ func (b *BaseApi) SearchPostgresql(c *gin.Context) {
|
|||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
// @Param database path string true "database"
|
||||||
// @Router /databases/pg/:database/load [post]
|
// @Router /databases/pg/:database/load [post]
|
||||||
func (b *BaseApi) LoadPostgresqlDBFromRemote(c *gin.Context) {
|
func (b *BaseApi) LoadPostgresqlDBFromRemote(c *gin.Context) {
|
||||||
database, err := helper.GetStrParamByKey(c, "database")
|
database, err := helper.GetStrParamByKey(c, "database")
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ func (b *BaseApi) LoadPersistenceConf(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Database Redis
|
||||||
|
// @Summary Check has cli
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /databases/redis/check [get]
|
||||||
func (b *BaseApi) CheckHasCli(c *gin.Context) {
|
func (b *BaseApi) CheckHasCli(c *gin.Context) {
|
||||||
helper.SuccessWithData(c, redisService.CheckHasCli())
|
helper.SuccessWithData(c, redisService.CheckHasCli())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,18 +31,23 @@ var (
|
|||||||
dbCommonService = service.NewIDBCommonService()
|
dbCommonService = service.NewIDBCommonService()
|
||||||
mysqlService = service.NewIMysqlService()
|
mysqlService = service.NewIMysqlService()
|
||||||
postgresqlService = service.NewIPostgresqlService()
|
postgresqlService = service.NewIPostgresqlService()
|
||||||
|
mongodbService = service.NewIMongodbService()
|
||||||
databaseService = service.NewIDatabaseService()
|
databaseService = service.NewIDatabaseService()
|
||||||
redisService = service.NewIRedisService()
|
redisService = service.NewIRedisService()
|
||||||
|
|
||||||
cronjobService = service.NewICronjobService()
|
cronjobService = service.NewICronjobService()
|
||||||
|
|
||||||
fileService = service.NewIFileService()
|
fileService = service.NewIFileService()
|
||||||
fileShareService = service.NewIFileShareService()
|
fileHistoryService = service.NewIFileHistoryService()
|
||||||
sshService = service.NewISSHService()
|
fileShareService = service.NewIFileShareService()
|
||||||
firewallService = service.NewIFirewallService()
|
sshService = service.NewISSHService()
|
||||||
iptablesService = service.NewIIptablesService()
|
firewallService = service.NewIFirewallService()
|
||||||
monitorService = service.NewIMonitorService()
|
firewallSettingService = service.NewIFirewallSettingService()
|
||||||
systemService = service.NewISystemService()
|
forwardingService = service.NewIForwardingService()
|
||||||
|
dockerPortGuardService = service.NewIDockerPortGuardService()
|
||||||
|
monitorService = service.NewIMonitorService()
|
||||||
|
systemService = service.NewISystemService()
|
||||||
|
runtimeDiagnosticsService = service.NewIRuntimeDiagnosticsService()
|
||||||
|
|
||||||
deviceService = service.NewIDeviceService()
|
deviceService = service.NewIDeviceService()
|
||||||
fail2banService = service.NewIFail2BanService()
|
fail2banService = service.NewIFail2BanService()
|
||||||
@@ -57,6 +62,7 @@ var (
|
|||||||
websiteDnsAccountService = service.NewIWebsiteDnsAccountService()
|
websiteDnsAccountService = service.NewIWebsiteDnsAccountService()
|
||||||
websiteSSLService = service.NewIWebsiteSSLService()
|
websiteSSLService = service.NewIWebsiteSSLService()
|
||||||
websiteAcmeAccountService = service.NewIWebsiteAcmeAccountService()
|
websiteAcmeAccountService = service.NewIWebsiteAcmeAccountService()
|
||||||
|
websiteTemplateService = service.NewIWebsiteTemplateService()
|
||||||
|
|
||||||
nginxService = service.NewINginxService()
|
nginxService = service.NewINginxService()
|
||||||
|
|
||||||
|
|||||||
+623
-39
@@ -12,7 +12,9 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/dto"
|
||||||
@@ -28,6 +30,86 @@ import (
|
|||||||
qrcode "github.com/skip2/go-qrcode"
|
qrcode "github.com/skip2/go-qrcode"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var cancelledChunkUploads = struct {
|
||||||
|
sync.RWMutex
|
||||||
|
ids map[string]struct{}
|
||||||
|
}{ids: make(map[string]struct{})}
|
||||||
|
|
||||||
|
type chunkUploadLock struct {
|
||||||
|
mutex sync.Mutex
|
||||||
|
refs int
|
||||||
|
}
|
||||||
|
|
||||||
|
var chunkUploadLocks = struct {
|
||||||
|
sync.Mutex
|
||||||
|
items map[string]*chunkUploadLock
|
||||||
|
}{items: make(map[string]*chunkUploadLock)}
|
||||||
|
|
||||||
|
type completedChunkUpload struct {
|
||||||
|
dstDir string
|
||||||
|
filename string
|
||||||
|
fileSize int64
|
||||||
|
}
|
||||||
|
|
||||||
|
var completedChunkUploads = struct {
|
||||||
|
sync.RWMutex
|
||||||
|
items map[string]completedChunkUpload
|
||||||
|
}{items: make(map[string]completedChunkUpload)}
|
||||||
|
|
||||||
|
var activeChunkUploadTTL = 24 * time.Hour
|
||||||
|
|
||||||
|
var (
|
||||||
|
errChunkUploadCancelled = errors.New("upload cancelled")
|
||||||
|
errInvalidChunkUpload = errors.New("invalid chunk upload")
|
||||||
|
)
|
||||||
|
|
||||||
|
type activeChunkUpload struct {
|
||||||
|
upload completedChunkUpload
|
||||||
|
expiresAt time.Time
|
||||||
|
timer *time.Timer
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeChunkUploads = struct {
|
||||||
|
sync.RWMutex
|
||||||
|
items map[string]activeChunkUpload
|
||||||
|
}{items: make(map[string]activeChunkUpload)}
|
||||||
|
|
||||||
|
type resumableUploadChunk struct {
|
||||||
|
UploadID string
|
||||||
|
Filename string
|
||||||
|
DstDir string
|
||||||
|
ChunkIndex int
|
||||||
|
ChunkCount int
|
||||||
|
Offset int64
|
||||||
|
FileSize int64
|
||||||
|
Overwrite bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func invalidChunkUploadError(message string) error {
|
||||||
|
return fmt.Errorf("%w: %s", errInvalidChunkUpload, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isRetryableChunkUploadError(err error) bool {
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if errors.Is(err, errChunkUploadCancelled) ||
|
||||||
|
errors.Is(err, errInvalidChunkUpload) ||
|
||||||
|
errors.Is(err, os.ErrExist) ||
|
||||||
|
errors.Is(err, os.ErrPermission) ||
|
||||||
|
errors.Is(err, os.ErrInvalid) ||
|
||||||
|
errors.Is(err, syscall.ENOSPC) ||
|
||||||
|
errors.Is(err, syscall.EDQUOT) ||
|
||||||
|
errors.Is(err, syscall.EROFS) ||
|
||||||
|
errors.Is(err, syscall.EFBIG) ||
|
||||||
|
errors.Is(err, syscall.ENAMETOOLONG) ||
|
||||||
|
errors.Is(err, syscall.ENOTDIR) ||
|
||||||
|
errors.Is(err, syscall.EISDIR) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary List files
|
// @Summary List files
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -193,7 +275,7 @@ func (b *BaseApi) BatchDeleteFile(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /files/mode [post]
|
// @Router /files/mode [post]
|
||||||
// @x-panel-log {"bodyKeys":["path","mode"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改权限 [paths] => [mode]","formatEN":"Change mode [paths] => [mode]"}
|
// @x-panel-log {"bodyKeys":["path","mode"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改权限 [path] => [mode]","formatEN":"Change mode [path] => [mode]"}
|
||||||
func (b *BaseApi) ChangeFileMode(c *gin.Context) {
|
func (b *BaseApi) ChangeFileMode(c *gin.Context) {
|
||||||
var req request.FileCreate
|
var req request.FileCreate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -215,7 +297,7 @@ func (b *BaseApi) ChangeFileMode(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /files/owner [post]
|
// @Router /files/owner [post]
|
||||||
// @x-panel-log {"bodyKeys":["path","user","group"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改用户/组 [paths] => [user]/[group]","formatEN":"Change owner [paths] => [user]/[group]"}
|
// @x-panel-log {"bodyKeys":["path","user","group"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改用户/组 [path] => [user]/[group]","formatEN":"Change owner [path] => [user]/[group]"}
|
||||||
func (b *BaseApi) ChangeFileOwner(c *gin.Context) {
|
func (b *BaseApi) ChangeFileOwner(c *gin.Context) {
|
||||||
var req request.FileRoleUpdate
|
var req request.FileRoleUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -250,6 +332,26 @@ func (b *BaseApi) CompressFile(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Stop compress task
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileCompressStopReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/compress/stop [post]
|
||||||
|
func (b *BaseApi) StopCompressFile(c *gin.Context) {
|
||||||
|
var req request.FileCompressStopReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fileService.StopCompress(req.TaskID); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Decompress file
|
// @Summary Decompress file
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -272,6 +374,26 @@ func (b *BaseApi) DeCompressFile(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Stop decompress task
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileDeCompressStopReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/decompress/stop [post]
|
||||||
|
func (b *BaseApi) StopDeCompressFile(c *gin.Context) {
|
||||||
|
var req request.FileDeCompressStopReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fileService.StopDeCompress(req.TaskID); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Load file content
|
// @Summary Load file content
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -371,7 +493,7 @@ func (b *BaseApi) UploadFiles(c *gin.Context) {
|
|||||||
helper.BadRequest(c, errors.New("error paths in request"))
|
helper.BadRequest(c, errors.New("error paths in request"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dir := path.Dir(paths[0])
|
dir := path.Clean(paths[0])
|
||||||
|
|
||||||
_, err = os.Stat(dir)
|
_, err = os.Stat(dir)
|
||||||
if err != nil && os.IsNotExist(err) {
|
if err != nil && os.IsNotExist(err) {
|
||||||
@@ -412,8 +534,14 @@ func (b *BaseApi) UploadFiles(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
_ = os.Chown(dstDir, uid, gid)
|
_ = os.Chown(dstDir, uid, gid)
|
||||||
}
|
}
|
||||||
|
dstDirMode := mode
|
||||||
|
dstFileMode := mode.Perm()
|
||||||
|
if dstDirInfo, err := os.Stat(dstDir); err == nil {
|
||||||
|
dstDirMode = dstDirInfo.Mode()
|
||||||
|
dstFileMode = dstDirInfo.Mode().Perm()
|
||||||
|
}
|
||||||
tmpFilename := dstFilename + ".tmp"
|
tmpFilename := dstFilename + ".tmp"
|
||||||
if err := c.SaveUploadedFile(file, tmpFilename); err != nil {
|
if err := c.SaveUploadedFile(file, tmpFilename, dstDirMode); err != nil {
|
||||||
_ = os.Remove(tmpFilename)
|
_ = os.Remove(tmpFilename)
|
||||||
e := fmt.Errorf("upload [%s] file failed, err: %v", file.Filename, err)
|
e := fmt.Errorf("upload [%s] file failed, err: %v", file.Filename, err)
|
||||||
failures[file.Filename] = e
|
failures[file.Filename] = e
|
||||||
@@ -421,11 +549,7 @@ func (b *BaseApi) UploadFiles(c *gin.Context) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
dstInfo, statErr := os.Stat(dstFilename)
|
dstInfo, statErr := os.Stat(dstFilename)
|
||||||
if overwrite {
|
err = finalizeUploadedFile(tmpFilename, dstFilename, overwrite)
|
||||||
_ = os.Remove(dstFilename)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Rename(tmpFilename, dstFilename)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = os.Remove(tmpFilename)
|
_ = os.Remove(tmpFilename)
|
||||||
e := fmt.Errorf("upload [%s] file failed, err: %v", file.Filename, err)
|
e := fmt.Errorf("upload [%s] file failed, err: %v", file.Filename, err)
|
||||||
@@ -436,7 +560,7 @@ func (b *BaseApi) UploadFiles(c *gin.Context) {
|
|||||||
if statErr == nil {
|
if statErr == nil {
|
||||||
_ = os.Chmod(dstFilename, dstInfo.Mode())
|
_ = os.Chmod(dstFilename, dstInfo.Mode())
|
||||||
} else {
|
} else {
|
||||||
_ = os.Chmod(dstFilename, mode)
|
_ = os.Chmod(dstFilename, dstFileMode)
|
||||||
}
|
}
|
||||||
if uid != -1 && gid != -1 {
|
if uid != -1 && gid != -1 {
|
||||||
_ = os.Chown(dstFilename, uid, gid)
|
_ = os.Chown(dstFilename, uid, gid)
|
||||||
@@ -560,10 +684,35 @@ func (b *BaseApi) StopWget(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
files.CancelDownload(req.Key)
|
if err := files.CancelDownload(req.Key); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Remove finished download progress records without deleting files
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileProcessRemoveReq true "request"
|
||||||
|
// @Success 200 {object} response.FileProcessKeys
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/wget/process/remove [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["keys"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"移除已结束下载记录 [keys]","formatEN":"Remove finished download records [keys]"}
|
||||||
|
func (b *BaseApi) RemoveWgetRecords(c *gin.Context) {
|
||||||
|
var req request.FileProcessRemoveReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
keys, err := files.RemoveDownloadRecords(req.Keys)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, response.FileProcessKeys{Keys: keys})
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Move file
|
// @Summary Move file
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -585,6 +734,26 @@ func (b *BaseApi) MoveFile(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Stop file move task
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileMoveStopReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/move/stop [post]
|
||||||
|
func (b *BaseApi) StopMoveFile(c *gin.Context) {
|
||||||
|
var req request.FileMoveStopReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fileService.StopMvFile(req.TaskID); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Download file
|
// @Summary Download file
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -594,6 +763,10 @@ func (b *BaseApi) MoveFile(c *gin.Context) {
|
|||||||
// @Router /files/download [get]
|
// @Router /files/download [get]
|
||||||
func (b *BaseApi) Download(c *gin.Context) {
|
func (b *BaseApi) Download(c *gin.Context) {
|
||||||
filePath := c.Query("path")
|
filePath := c.Query("path")
|
||||||
|
if files.ShouldDenySensitiveFileRead(filePath) {
|
||||||
|
helper.InternalServer(c, buserr.New("ErrSensitiveFileRead"))
|
||||||
|
return
|
||||||
|
}
|
||||||
file, err := os.Open(filePath)
|
file, err := os.Open(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
@@ -629,6 +802,10 @@ func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, http.StatusInternalServerError, "ErrPathNotFound", nil)
|
helper.ErrorWithDetail(c, http.StatusInternalServerError, "ErrPathNotFound", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if files.ShouldDenySensitiveFileRead(req.Path) {
|
||||||
|
helper.InternalServer(c, buserr.New("ErrSensitiveFileRead"))
|
||||||
|
return
|
||||||
|
}
|
||||||
filePath := req.Path
|
filePath := req.Path
|
||||||
fstFile, err := fileOp.OpenFile(filePath)
|
fstFile, err := fileOp.OpenFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -731,6 +908,289 @@ func (b *BaseApi) DepthDirSize(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, res)
|
helper.SuccessWithData(c, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lockChunkUpload(uploadID string) func() {
|
||||||
|
chunkUploadLocks.Lock()
|
||||||
|
lock, ok := chunkUploadLocks.items[uploadID]
|
||||||
|
if !ok {
|
||||||
|
lock = &chunkUploadLock{}
|
||||||
|
chunkUploadLocks.items[uploadID] = lock
|
||||||
|
}
|
||||||
|
lock.refs++
|
||||||
|
chunkUploadLocks.Unlock()
|
||||||
|
|
||||||
|
lock.mutex.Lock()
|
||||||
|
return func() {
|
||||||
|
lock.mutex.Unlock()
|
||||||
|
chunkUploadLocks.Lock()
|
||||||
|
lock.refs--
|
||||||
|
if lock.refs == 0 {
|
||||||
|
delete(chunkUploadLocks.items, uploadID)
|
||||||
|
}
|
||||||
|
chunkUploadLocks.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resumableUploadPartPath(dstDir, uploadID string) string {
|
||||||
|
return filepath.Join(dstDir, fmt.Sprintf(".1panel-upload-%s.part", uploadID))
|
||||||
|
}
|
||||||
|
|
||||||
|
func finalizeUploadedFile(tmpFile, dstFile string, overwrite bool) error {
|
||||||
|
if overwrite {
|
||||||
|
return os.Rename(tmpFile, dstFile)
|
||||||
|
}
|
||||||
|
if err := os.Link(tmpFile, dstFile); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.Remove(tmpFile); err != nil {
|
||||||
|
if rollbackErr := os.Remove(dstFile); rollbackErr != nil {
|
||||||
|
return fmt.Errorf("remove upload temporary file failed: %v, rollback destination failed: %w", err, rollbackErr)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerActiveChunkUpload(uploadID string, upload completedChunkUpload) error {
|
||||||
|
activeChunkUploads.Lock()
|
||||||
|
defer activeChunkUploads.Unlock()
|
||||||
|
if active, ok := activeChunkUploads.items[uploadID]; ok {
|
||||||
|
if active.upload != upload {
|
||||||
|
return invalidChunkUploadError("upload ID is already used by another file")
|
||||||
|
}
|
||||||
|
active.timer.Stop()
|
||||||
|
}
|
||||||
|
expiresAt := time.Now().Add(activeChunkUploadTTL)
|
||||||
|
timer := time.AfterFunc(activeChunkUploadTTL, func() {
|
||||||
|
expireActiveChunkUpload(uploadID, expiresAt)
|
||||||
|
})
|
||||||
|
activeChunkUploads.items[uploadID] = activeChunkUpload{
|
||||||
|
upload: upload,
|
||||||
|
expiresAt: expiresAt,
|
||||||
|
timer: timer,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadActiveChunkUpload(uploadID string) (completedChunkUpload, bool) {
|
||||||
|
activeChunkUploads.RLock()
|
||||||
|
active, ok := activeChunkUploads.items[uploadID]
|
||||||
|
activeChunkUploads.RUnlock()
|
||||||
|
return active.upload, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteActiveChunkUpload(uploadID string) {
|
||||||
|
activeChunkUploads.Lock()
|
||||||
|
if active, ok := activeChunkUploads.items[uploadID]; ok {
|
||||||
|
active.timer.Stop()
|
||||||
|
}
|
||||||
|
delete(activeChunkUploads.items, uploadID)
|
||||||
|
activeChunkUploads.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func discardActiveChunkUpload(uploadID, partFile string) error {
|
||||||
|
deleteActiveChunkUpload(uploadID)
|
||||||
|
if err := os.Remove(partFile); err != nil && !os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("remove upload temporary file failed: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func finalizeActiveChunkUpload(uploadID, partFile, dstFile string, overwrite bool) error {
|
||||||
|
if err := finalizeUploadedFile(partFile, dstFile, overwrite); err != nil {
|
||||||
|
if removeErr := discardActiveChunkUpload(uploadID, partFile); removeErr != nil {
|
||||||
|
return errors.Join(err, removeErr)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expireActiveChunkUpload(uploadID string, expiresAt time.Time) {
|
||||||
|
unlock := lockChunkUpload(uploadID)
|
||||||
|
defer unlock()
|
||||||
|
activeChunkUploads.Lock()
|
||||||
|
active, ok := activeChunkUploads.items[uploadID]
|
||||||
|
if !ok || !active.expiresAt.Equal(expiresAt) {
|
||||||
|
activeChunkUploads.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
delete(activeChunkUploads.items, uploadID)
|
||||||
|
activeChunkUploads.Unlock()
|
||||||
|
partFile := resumableUploadPartPath(active.upload.dstDir, uploadID)
|
||||||
|
if err := os.Remove(partFile); err != nil && !os.IsNotExist(err) {
|
||||||
|
global.LOG.Warnf("remove inactive upload part [%s] failed: %v", partFile, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeActiveResumableUploadPart(uploadID string) error {
|
||||||
|
unlock := lockChunkUpload(uploadID)
|
||||||
|
defer unlock()
|
||||||
|
upload, ok := loadActiveChunkUpload(uploadID)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := os.Remove(resumableUploadPartPath(upload.dstDir, uploadID))
|
||||||
|
if err == nil || os.IsNotExist(err) {
|
||||||
|
deleteActiveChunkUpload(uploadID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCompletedChunkUpload(uploadID string) (completedChunkUpload, bool) {
|
||||||
|
completedChunkUploads.RLock()
|
||||||
|
completed, ok := completedChunkUploads.items[uploadID]
|
||||||
|
completedChunkUploads.RUnlock()
|
||||||
|
return completed, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func markChunkUploadCompleted(uploadID string, completed completedChunkUpload) {
|
||||||
|
completedChunkUploads.Lock()
|
||||||
|
completedChunkUploads.items[uploadID] = completed
|
||||||
|
completedChunkUploads.Unlock()
|
||||||
|
time.AfterFunc(10*time.Minute, func() {
|
||||||
|
completedChunkUploads.Lock()
|
||||||
|
delete(completedChunkUploads.items, uploadID)
|
||||||
|
completedChunkUploads.Unlock()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeResumableUploadChunk(chunk resumableUploadChunk, chunkData []byte) error {
|
||||||
|
unlock := lockChunkUpload(chunk.UploadID)
|
||||||
|
defer unlock()
|
||||||
|
if chunkUploadCancelled(chunk.UploadID) {
|
||||||
|
return errChunkUploadCancelled
|
||||||
|
}
|
||||||
|
if chunk.UploadID == "" || filepath.Base(chunk.UploadID) != chunk.UploadID || strings.ContainsAny(chunk.UploadID, `/\`) {
|
||||||
|
return invalidChunkUploadError("invalid upload ID")
|
||||||
|
}
|
||||||
|
if chunk.Filename == "" || filepath.Base(chunk.Filename) != chunk.Filename || strings.ContainsAny(chunk.Filename, `/\`) {
|
||||||
|
return invalidChunkUploadError("invalid filename")
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(chunk.DstDir) == "" {
|
||||||
|
return invalidChunkUploadError("upload destination is required")
|
||||||
|
}
|
||||||
|
dstDir := filepath.Clean(strings.TrimSpace(chunk.DstDir))
|
||||||
|
|
||||||
|
if chunk.ChunkCount <= 0 || chunk.ChunkIndex < 0 || chunk.ChunkIndex >= chunk.ChunkCount {
|
||||||
|
return invalidChunkUploadError("invalid chunk index")
|
||||||
|
}
|
||||||
|
if chunk.FileSize <= 0 || chunk.Offset < 0 || chunk.Offset > chunk.FileSize {
|
||||||
|
return invalidChunkUploadError("invalid upload offset")
|
||||||
|
}
|
||||||
|
chunkEnd := chunk.Offset + int64(len(chunkData))
|
||||||
|
if chunkEnd > chunk.FileSize {
|
||||||
|
return invalidChunkUploadError("chunk exceeds file size")
|
||||||
|
}
|
||||||
|
if chunk.ChunkIndex+1 == chunk.ChunkCount {
|
||||||
|
if chunkEnd != chunk.FileSize {
|
||||||
|
return invalidChunkUploadError("final chunk does not match file size")
|
||||||
|
}
|
||||||
|
} else if chunkEnd >= chunk.FileSize {
|
||||||
|
return invalidChunkUploadError("non-final chunk reaches file size")
|
||||||
|
}
|
||||||
|
if completed, ok := loadCompletedChunkUpload(chunk.UploadID); ok {
|
||||||
|
if completed.dstDir == dstDir && completed.filename == chunk.Filename && completed.fileSize == chunk.FileSize {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return invalidChunkUploadError("upload ID has already completed another file")
|
||||||
|
}
|
||||||
|
upload := completedChunkUpload{dstDir: dstDir, filename: chunk.Filename, fileSize: chunk.FileSize}
|
||||||
|
if err := registerActiveChunkUpload(chunk.UploadID, upload); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
mode, err := files.GetParentMode(dstDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = os.MkdirAll(dstDir, mode); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dstDirInfo, err := os.Stat(dstDir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !dstDirInfo.IsDir() {
|
||||||
|
return invalidChunkUploadError(fmt.Sprintf("upload destination [%s] is not a directory", dstDir))
|
||||||
|
}
|
||||||
|
|
||||||
|
dstFile := filepath.Join(dstDir, chunk.Filename)
|
||||||
|
partFile := resumableUploadPartPath(dstDir, chunk.UploadID)
|
||||||
|
if dstFile == partFile {
|
||||||
|
return invalidChunkUploadError("filename conflicts with upload temporary file")
|
||||||
|
}
|
||||||
|
fileMode := dstDirInfo.Mode().Perm()
|
||||||
|
ownerInfo := dstDirInfo
|
||||||
|
if dstInfo, statErr := os.Stat(dstFile); statErr == nil {
|
||||||
|
if !chunk.Overwrite {
|
||||||
|
if err := discardActiveChunkUpload(chunk.UploadID, partFile); err != nil {
|
||||||
|
return errors.Join(os.ErrExist, err)
|
||||||
|
}
|
||||||
|
return os.ErrExist
|
||||||
|
}
|
||||||
|
fileMode = dstInfo.Mode().Perm()
|
||||||
|
ownerInfo = dstInfo
|
||||||
|
} else if !os.IsNotExist(statErr) {
|
||||||
|
return statErr
|
||||||
|
}
|
||||||
|
|
||||||
|
part, err := os.OpenFile(partFile, os.O_CREATE|os.O_RDWR, fileMode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
partClosed := false
|
||||||
|
defer func() {
|
||||||
|
if !partClosed {
|
||||||
|
_ = part.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if stat, statErr := part.Stat(); statErr != nil {
|
||||||
|
return statErr
|
||||||
|
} else if chunk.Offset > stat.Size() {
|
||||||
|
return invalidChunkUploadError(fmt.Sprintf("unexpected upload offset %d, current size is %d", chunk.Offset, stat.Size()))
|
||||||
|
} else if chunk.Offset < stat.Size() && chunkEnd > stat.Size() {
|
||||||
|
if err = part.Truncate(chunk.Offset); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = part.WriteAt(chunkData, chunk.Offset); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if chunk.ChunkIndex+1 != chunk.ChunkCount {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
partInfo, err := part.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if partInfo.Size() != chunk.FileSize {
|
||||||
|
return invalidChunkUploadError(fmt.Sprintf("uploaded file size mismatch: expected %d, got %d", chunk.FileSize, partInfo.Size()))
|
||||||
|
}
|
||||||
|
if err = part.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
partClosed = true
|
||||||
|
if err = os.Chmod(partFile, fileMode); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if stat, ok := ownerInfo.Sys().(*syscall.Stat_t); ok {
|
||||||
|
if err = os.Chown(partFile, int(stat.Uid), int(stat.Gid)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if chunkUploadCancelled(chunk.UploadID) {
|
||||||
|
return errChunkUploadCancelled
|
||||||
|
}
|
||||||
|
if err = finalizeActiveChunkUpload(chunk.UploadID, partFile, dstFile, chunk.Overwrite); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
markChunkUploadCompleted(chunk.UploadID, upload)
|
||||||
|
deleteActiveChunkUpload(chunk.UploadID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int, overwrite bool) error {
|
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int, overwrite bool) error {
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = os.RemoveAll(fileDir)
|
_ = os.RemoveAll(fileDir)
|
||||||
@@ -747,12 +1207,13 @@ func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if dstDirInfo, err := os.Stat(dstDir); err == nil {
|
||||||
|
mode = dstDirInfo.Mode().Perm()
|
||||||
|
}
|
||||||
dstFileName := filepath.Join(dstDir, fileName)
|
dstFileName := filepath.Join(dstDir, fileName)
|
||||||
dstInfo, statErr := os.Stat(dstFileName)
|
dstInfo, statErr := os.Stat(dstFileName)
|
||||||
if statErr == nil {
|
if statErr == nil {
|
||||||
mode = dstInfo.Mode()
|
mode = dstInfo.Mode()
|
||||||
} else {
|
|
||||||
mode = 0644
|
|
||||||
}
|
}
|
||||||
if overwrite {
|
if overwrite {
|
||||||
_ = os.Remove(dstFileName)
|
_ = os.Remove(dstFileName)
|
||||||
@@ -774,6 +1235,7 @@ func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int,
|
|||||||
}
|
}
|
||||||
_ = os.Remove(chunkPath)
|
_ = os.Remove(chunkPath)
|
||||||
}
|
}
|
||||||
|
_ = os.Chmod(dstFileName, mode)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -808,6 +1270,10 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
|||||||
helper.BadRequest(c, err)
|
helper.BadRequest(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if chunkCount <= 0 || chunkIndex < 0 || chunkIndex >= chunkCount {
|
||||||
|
helper.BadRequest(c, errors.New("invalid chunk index"))
|
||||||
|
return
|
||||||
|
}
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
tmpDir := path.Join(global.Dir.TmpDir, "upload")
|
tmpDir := path.Join(global.Dir.TmpDir, "upload")
|
||||||
if !fileOp.Stat(tmpDir) {
|
if !fileOp.Stat(tmpDir) {
|
||||||
@@ -817,8 +1283,30 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
filename := c.PostForm("filename")
|
filename := c.PostForm("filename")
|
||||||
fileDir := filepath.Join(tmpDir, filename)
|
if filename == "" || filepath.Base(filename) != filename || strings.ContainsAny(filename, `/\\`) {
|
||||||
if chunkIndex == 0 {
|
helper.BadRequest(c, errors.New("invalid filename"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uploadID := strings.TrimSpace(c.PostForm("uploadID"))
|
||||||
|
resumable := c.PostForm("fileSize") != "" || c.PostForm("offset") != ""
|
||||||
|
cancellable := uploadID != ""
|
||||||
|
if cancellable && (filepath.Base(uploadID) != uploadID || strings.ContainsAny(uploadID, `/\\`)) {
|
||||||
|
helper.BadRequest(c, errors.New("invalid upload ID"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resumable && !cancellable {
|
||||||
|
helper.BadRequest(c, errors.New("upload ID is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !cancellable {
|
||||||
|
uploadID = filename
|
||||||
|
}
|
||||||
|
fileDir := filepath.Join(tmpDir, uploadID)
|
||||||
|
if cancellable && chunkUploadCancelled(uploadID) {
|
||||||
|
helper.BadRequest(c, errChunkUploadCancelled)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !resumable && chunkIndex == 0 {
|
||||||
if fileOp.Stat(fileDir) {
|
if fileOp.Stat(fileDir) {
|
||||||
_ = fileOp.DeleteDir(fileDir)
|
_ = fileOp.DeleteDir(fileDir)
|
||||||
}
|
}
|
||||||
@@ -827,28 +1315,68 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
|||||||
filePath := filepath.Join(fileDir, filename)
|
filePath := filepath.Join(fileDir, filename)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if !resumable && err != nil {
|
||||||
_ = os.Remove(fileDir)
|
_ = os.RemoveAll(fileDir)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
var (
|
chunkData, err := io.ReadAll(uploadFile)
|
||||||
emptyFile *os.File
|
if err != nil {
|
||||||
chunkData []byte
|
helper.InternalServer(c, buserr.WithMap("ErrFileUpload", map[string]interface{}{"name": filename, "detail": err.Error()}, err))
|
||||||
)
|
return
|
||||||
|
}
|
||||||
|
if cancellable && chunkUploadCancelled(uploadID) {
|
||||||
|
err = errChunkUploadCancelled
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resumable {
|
||||||
|
offset, parseErr := strconv.ParseInt(c.PostForm("offset"), 10, 64)
|
||||||
|
if parseErr != nil {
|
||||||
|
helper.BadRequest(c, parseErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fileSize, parseErr := strconv.ParseInt(c.PostForm("fileSize"), 10, 64)
|
||||||
|
if parseErr != nil {
|
||||||
|
helper.BadRequest(c, parseErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
overwrite := true
|
||||||
|
if ow := c.PostForm("overwrite"); ow != "" {
|
||||||
|
overwrite, _ = strconv.ParseBool(ow)
|
||||||
|
}
|
||||||
|
err = writeResumableUploadChunk(resumableUploadChunk{
|
||||||
|
UploadID: uploadID,
|
||||||
|
Filename: filename,
|
||||||
|
DstDir: c.PostForm("path"),
|
||||||
|
ChunkIndex: chunkIndex,
|
||||||
|
ChunkCount: chunkCount,
|
||||||
|
Offset: offset,
|
||||||
|
FileSize: fileSize,
|
||||||
|
Overwrite: overwrite,
|
||||||
|
}, chunkData)
|
||||||
|
if err != nil {
|
||||||
|
uploadErr := buserr.WithMap("ErrFileUpload", map[string]interface{}{"name": filename, "detail": err.Error()}, err)
|
||||||
|
helper.ErrorWithDetailAndData(c, http.StatusInternalServerError, "ErrInternalServer", uploadErr, gin.H{
|
||||||
|
"retryable": isRetryableChunkUploadError(err),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if chunkIndex+1 == chunkCount {
|
||||||
|
cancelledChunkUploads.Lock()
|
||||||
|
delete(cancelledChunkUploads.ids, uploadID)
|
||||||
|
cancelledChunkUploads.Unlock()
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
emptyFile, err = os.Create(filePath)
|
emptyFile, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.BadRequest(c, err)
|
helper.BadRequest(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer emptyFile.Close()
|
defer emptyFile.Close()
|
||||||
|
|
||||||
chunkData, err = io.ReadAll(uploadFile)
|
|
||||||
if err != nil {
|
|
||||||
helper.InternalServer(c, buserr.WithMap("ErrFileUpload", map[string]interface{}{"name": filename, "detail": err.Error()}, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", filename, chunkIndex))
|
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", filename, chunkIndex))
|
||||||
err = os.WriteFile(chunkPath, chunkData, constant.DirPerm)
|
err = os.WriteFile(chunkPath, chunkData, constant.DirPerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -866,19 +1394,71 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
|||||||
helper.InternalServer(c, buserr.WithMap("ErrFileUpload", map[string]interface{}{"name": filename, "detail": err.Error()}, err))
|
helper.InternalServer(c, buserr.WithMap("ErrFileUpload", map[string]interface{}{"name": filename, "detail": err.Error()}, err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if cancellable {
|
||||||
|
cancelledChunkUploads.Lock()
|
||||||
|
delete(cancelledChunkUploads.ids, uploadID)
|
||||||
|
cancelledChunkUploads.Unlock()
|
||||||
|
}
|
||||||
helper.SuccessWithData(c, true)
|
helper.SuccessWithData(c, true)
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StopChunkUpload removes temporary chunks left by a cancelled upload.
|
||||||
|
func (b *BaseApi) StopChunkUpload(c *gin.Context) {
|
||||||
|
var req request.FileProcessReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uploadID := strings.TrimSpace(req.Key)
|
||||||
|
if uploadID == "" || filepath.Base(uploadID) != uploadID || strings.ContainsAny(uploadID, `/\\`) {
|
||||||
|
helper.BadRequest(c, errors.New("invalid upload ID"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cancelledChunkUploads.Lock()
|
||||||
|
cancelledChunkUploads.ids[uploadID] = struct{}{}
|
||||||
|
cancelledChunkUploads.Unlock()
|
||||||
|
time.AfterFunc(10*time.Minute, func() {
|
||||||
|
cancelledChunkUploads.Lock()
|
||||||
|
delete(cancelledChunkUploads.ids, uploadID)
|
||||||
|
cancelledChunkUploads.Unlock()
|
||||||
|
})
|
||||||
|
if err := os.RemoveAll(filepath.Join(global.Dir.TmpDir, "upload", uploadID)); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := removeActiveResumableUploadPart(uploadID); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func chunkUploadCancelled(uploadID string) bool {
|
||||||
|
cancelledChunkUploads.RLock()
|
||||||
|
_, ok := cancelledChunkUploads.ids[uploadID]
|
||||||
|
cancelledChunkUploads.RUnlock()
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
var wsUpgrade = websocket.Upgrader{
|
var wsUpgrade = websocket.Upgrader{
|
||||||
CheckOrigin: func(r *http.Request) bool {
|
CheckOrigin: func(r *http.Request) bool {
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Wget process
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/wget/process [get]
|
||||||
func (b *BaseApi) WgetProcess(c *gin.Context) {
|
func (b *BaseApi) WgetProcess(c *gin.Context) {
|
||||||
|
if !websocket.IsWebSocketUpgrade(c.Request) {
|
||||||
|
helper.Success(c)
|
||||||
|
return
|
||||||
|
}
|
||||||
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
|
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -888,6 +1468,12 @@ func (b *BaseApi) WgetProcess(c *gin.Context) {
|
|||||||
go wsClient.Write()
|
go wsClient.Write()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Process keys
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/wget/process/keys [get]
|
||||||
func (b *BaseApi) ProcessKeys(c *gin.Context) {
|
func (b *BaseApi) ProcessKeys(c *gin.Context) {
|
||||||
res := &response.FileProcessKeys{}
|
res := &response.FileProcessKeys{}
|
||||||
keys := global.CACHE.PrefixScanKey("file-wget-")
|
keys := global.CACHE.PrefixScanKey("file-wget-")
|
||||||
@@ -907,16 +1493,20 @@ func (b *BaseApi) ProcessKeys(c *gin.Context) {
|
|||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Read file by Line
|
// @Summary Read file by Line
|
||||||
|
// @Param type path string true "type"
|
||||||
// @Param request body request.FileReadByLineReq true "request"
|
// @Param request body request.FileReadByLineReq true "request"
|
||||||
// @Success 200 {object} response.FileLineContent
|
// @Success 200 {object} response.FileLineContent
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /files/read [post]
|
// @Router /files/read/{type} [post]
|
||||||
func (b *BaseApi) ReadFileByLine(c *gin.Context) {
|
func (b *BaseApi) ReadFileByLine(c *gin.Context) {
|
||||||
var req request.FileReadByLineReq
|
var req request.FileReadByLineReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if readType := strings.TrimSpace(c.Param("type")); readType != "" {
|
||||||
|
req.Type = readType
|
||||||
|
}
|
||||||
res, err := fileService.ReadLogByLine(req)
|
res, err := fileService.ReadLogByLine(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
@@ -949,16 +1539,6 @@ func (b *BaseApi) BatchChangeModeAndOwner(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BaseApi) GetPathByType(c *gin.Context) {
|
|
||||||
pathType, ok := c.Params.Get("type")
|
|
||||||
if !ok {
|
|
||||||
helper.BadRequest(c, errors.New("error pathType id in path"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resPath := fileService.GetPathByType(pathType)
|
|
||||||
helper.SuccessWithData(c, resPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary system mount
|
// @Summary system mount
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -1290,6 +1870,10 @@ func (b *BaseApi) DownloadFileShare(c *gin.Context) {
|
|||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if files.ShouldDenySensitiveFileRead(filePath) {
|
||||||
|
helper.InternalServer(c, buserr.New("ErrSensitiveFileRead"))
|
||||||
|
return
|
||||||
|
}
|
||||||
file, err := os.Open(filePath)
|
file, err := os.Open(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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/dto/request"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Load file history list
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileHistorySearchReq true "request"
|
||||||
|
// @Success 200 {object} dto.PageResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/history/search [post]
|
||||||
|
func (b *BaseApi) SearchFileHistory(c *gin.Context) {
|
||||||
|
var req request.FileHistorySearchReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, items, err := fileHistoryService.Search(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{Items: items, Total: total})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Load file history content
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileHistoryContentReq true "request"
|
||||||
|
// @Success 200 {object} response.FileHistoryInfo
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/history/content [post]
|
||||||
|
func (b *BaseApi) GetFileHistoryContent(c *gin.Context) {
|
||||||
|
var req request.FileHistoryContentReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
item, err := fileHistoryService.GetContent(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Delete file history record
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileHistoryDeleteReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/history/del [post]
|
||||||
|
func (b *BaseApi) DeleteFileHistory(c *gin.Context) {
|
||||||
|
var req request.FileHistoryDeleteReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fileHistoryService.Delete(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Restore file history record
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileHistoryRestoreReq true "request"
|
||||||
|
// @Success 200 {object} response.FileInfo
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/history/restore [post]
|
||||||
|
func (b *BaseApi) RestoreFileHistory(c *gin.Context) {
|
||||||
|
var req request.FileHistoryRestoreReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info, err := fileHistoryService.Restore(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, info)
|
||||||
|
}
|
||||||
+587
-246
@@ -1,26 +1,53 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/dto"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/firewall/filter"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (b *BaseApi) UpdatePanelFirewallPort(c *gin.Context) {
|
||||||
|
if !global.IsMaster {
|
||||||
|
c.AbortWithStatus(http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var request struct {
|
||||||
|
OldPort uint `json:"oldPort" validate:"required,min=1,max=65535"`
|
||||||
|
NewPort uint `json:"newPort" validate:"required,min=1,max=65535"`
|
||||||
|
}
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := firewallService.UpdatePanelPort(c.Request.Context(), request.OldPort, request.NewPort); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Firewall
|
// @Tags Firewall
|
||||||
// @Summary Load firewall base info
|
// @Summary Load firewall base info
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.OperationWithName true "request"
|
// @Param request body dto.OperationWithName true "request"
|
||||||
// @Success 200 {object} dto.FirewallBaseInfo
|
// @Success 200 {object} dto.FirewallSubsystemStatus
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/firewall/base [post]
|
// @Router /hosts/firewall/base [post]
|
||||||
func (b *BaseApi) LoadFirewallBaseInfo(c *gin.Context) {
|
func (b *BaseApi) LoadFirewallBaseInfo(c *gin.Context) {
|
||||||
var req dto.OperationWithName
|
var request dto.OperationWithName
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := firewallService.LoadBaseInfo(req.Name)
|
data, err := firewallService.LoadBaseInfo(request.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
@@ -29,311 +56,625 @@ func (b *BaseApi) LoadFirewallBaseInfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary Page firewall rules
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.RuleSearch true "request"
|
|
||||||
// @Success 200 {object} dto.PageResult
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/search [post]
|
|
||||||
func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
|
|
||||||
var req dto.RuleSearch
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
total, list, err := firewallService.SearchWithPage(req)
|
|
||||||
if err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
helper.SuccessWithData(c, dto.PageResult{
|
|
||||||
Items: list,
|
|
||||||
Total: total,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Firewall
|
// @Tags Firewall
|
||||||
// @Summary Operate firewall
|
// @Summary Operate firewall
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.FirewallOperation true "request"
|
// @Param request body dto.FirewallLifecycleOperation true "request"
|
||||||
// @Success 200
|
// @Success 200 {object} dto.FirewallLifecycleOperationResponse
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/firewall/operate [post]
|
// @Router /hosts/firewall/operate [post]
|
||||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"}
|
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"}
|
||||||
func (b *BaseApi) OperateFirewall(c *gin.Context) {
|
func (b *BaseApi) OperateFirewall(c *gin.Context) {
|
||||||
var req dto.FirewallOperation
|
var request dto.FirewallLifecycleOperation
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := firewallService.OperateFirewall(req); err != nil {
|
result, err := firewallService.QueueFirewallOperation(request)
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary Create group
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.PortRuleOperate true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/port [post]
|
|
||||||
// @x-panel-log {"bodyKeys":["port","strategy"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加端口规则 [strategy] [port]","formatEN":"create port rules [strategy][port]"}
|
|
||||||
func (b *BaseApi) OperatePortRule(c *gin.Context) {
|
|
||||||
var req dto.PortRuleOperate
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := firewallService.OperatePortRule(req, true); err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OperateForwardRule
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary Operate forward rule
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.ForwardRuleOperate true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/forward [post]
|
|
||||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新端口转发规则","formatEN":"update port forward rules"}
|
|
||||||
func (b *BaseApi) OperateForwardRule(c *gin.Context) {
|
|
||||||
var req dto.ForwardRuleOperate
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := firewallService.OperateForwardRule(req); err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary Operate Ip rule
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.AddrRuleOperate true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/ip [post]
|
|
||||||
// @x-panel-log {"bodyKeys":["strategy","address"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加 ip 规则 [strategy] [address]","formatEN":"create address rules [strategy][address]"}
|
|
||||||
func (b *BaseApi) OperateIPRule(c *gin.Context) {
|
|
||||||
var req dto.AddrRuleOperate
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := firewallService.OperateAddressRule(req, true); err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary Batch operate rule
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.BatchRuleOperate true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/batch [post]
|
|
||||||
func (b *BaseApi) BatchOperateRule(c *gin.Context) {
|
|
||||||
var req dto.BatchRuleOperate
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := firewallService.BatchOperateRule(req); err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary Update rule description
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.UpdateFirewallDescription true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/update/description [post]
|
|
||||||
func (b *BaseApi) UpdateFirewallDescription(c *gin.Context) {
|
|
||||||
var req dto.UpdateFirewallDescription
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := firewallService.UpdateDescription(req); err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary Update port rule
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.PortRuleUpdate true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/update/port [post]
|
|
||||||
func (b *BaseApi) UpdatePortRule(c *gin.Context) {
|
|
||||||
var req dto.PortRuleUpdate
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := firewallService.UpdatePortRule(req); err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary Update Ip rule
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.AddrRuleUpdate true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/update/addr [post]
|
|
||||||
func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
|
|
||||||
var req dto.AddrRuleUpdate
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := firewallService.UpdateAddrRule(req); err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Firewall
|
|
||||||
// @Summary search iptables filter rules
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.SearchPageWithType true "request"
|
|
||||||
// @Success 200 {object} dto.PageResult
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/firewall/filter/search [post]
|
|
||||||
func (b *BaseApi) SearchFilterRules(c *gin.Context) {
|
|
||||||
var req dto.SearchPageWithType
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
total, list, err := iptablesService.Search(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
helper.SuccessWithData(c, dto.PageResult{
|
helper.SuccessWithData(c, result)
|
||||||
Items: list,
|
|
||||||
Total: total,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Firewall
|
// @Tags Firewall
|
||||||
// @Summary Operate iptables filter rule
|
// @Summary Load forwarding base info
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.IptablesRuleOp true "request"
|
// @Success 200 {object} dto.FirewallSubsystemStatus
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/firewall/filter/rule/operate [post]
|
// @Router /hosts/firewall/forward/base [post]
|
||||||
// @x-panel-log {"bodyKeys":["operation","chain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] filter规则到 [chain]","formatEN":"[operation] filter rule to [chain]"}
|
func (b *BaseApi) LoadForwardingBaseInfo(c *gin.Context) {
|
||||||
func (b *BaseApi) OperateFilterRule(c *gin.Context) {
|
data, err := forwardingService.LoadBaseInfo(c.Request.Context())
|
||||||
var req dto.IptablesRuleOp
|
if err != nil {
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := iptablesService.OperateRule(req, true); err != nil {
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Page forwarding rules
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ForwardRuleSearch true "request"
|
||||||
|
// @Success 200 {object} dto.PageResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/forward/search [post]
|
||||||
|
func (b *BaseApi) SearchForwardingRules(c *gin.Context) {
|
||||||
|
var request dto.ForwardRuleSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, items, err := forwardingService.SearchRules(c.Request.Context(), request)
|
||||||
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
helper.Success(c)
|
helper.SuccessWithData(c, dto.PageResult{Items: items, Total: total})
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Firewall
|
// @Tags Firewall
|
||||||
// @Summary Batch operate iptables filter rules
|
// @Summary Operate forwarding rules
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.IptablesBatchOperate true "request"
|
// @Param request body dto.ForwardRuleOperate true "request"
|
||||||
// @Success 200
|
// @Success 200 {object} dto.FilterChainOperationResponse
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/firewall/filter/rule/batch [post]
|
// @Router /hosts/firewall/forward/operate [post]
|
||||||
func (b *BaseApi) BatchOperateFilterRule(c *gin.Context) {
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新端口转发规则","formatEN":"update port forward rules"}
|
||||||
var req dto.IptablesBatchOperate
|
func (b *BaseApi) OperateForwardingRules(c *gin.Context) {
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
var request dto.ForwardRuleOperate
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := iptablesService.BatchOperate(req); err != nil {
|
result, err := forwardingService.OperateRules(request)
|
||||||
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
helper.Success(c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Firewall
|
// @Tags Firewall
|
||||||
// @Summary Apply/Unload/Init iptables filter
|
// @Summary Enable forwarding
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.IptablesOp true "request"
|
// @Param request body dto.FirewallInitializationTask true "request"
|
||||||
// @Success 200
|
// @Success 200 {object} dto.FilterChainOperationResponse
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/forward/enable [post]
|
||||||
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"初始化并启用端口转发","formatEN":"initialize and enable port forwarding"}
|
||||||
|
func (b *BaseApi) EnableForwarding(c *gin.Context) {
|
||||||
|
var request dto.FirewallInitializationTask
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := forwardingService.QueueInitialization(request)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Apply/Unload/Init firewall filter chain
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FilterChainOperation true "request"
|
||||||
|
// @Success 200 {object} dto.FilterChainOperationResponse
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/firewall/filter/operate [post]
|
// @Router /hosts/firewall/filter/operate [post]
|
||||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] iptables filter 防火墙","formatEN":"[operate] iptables filter firewall"}
|
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 防火墙过滤链","formatEN":"[operate] firewall filter chain"}
|
||||||
func (b *BaseApi) OperateFilterChain(c *gin.Context) {
|
func (b *BaseApi) OperateFilterChain(c *gin.Context) {
|
||||||
var req dto.IptablesOp
|
var request dto.FilterChainOperation
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := iptablesService.Operate(req); err != nil {
|
if request.Operate == "init-base" {
|
||||||
|
result, err := firewallService.QueueFilterChainInitialization(request)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := firewallService.OperateFilterChain(request); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
helper.SuccessWithData(c, dto.FilterChainOperationResponse{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary List unified firewall v2 rules
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallRuleInventory true "request"
|
||||||
|
// @Success 200 {object} dto.FirewallRuleInventoryResponse
|
||||||
|
// @Failure 400 {object} dto.Response
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/rules/search [post]
|
||||||
|
func (b *BaseApi) SearchFirewallRules(c *gin.Context) {
|
||||||
|
var request dto.FirewallRuleInventory
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
inventory, err := firewallService.Inventory(c.Request.Context(), request)
|
||||||
|
if err != nil {
|
||||||
|
handleFirewallRuleError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, inventory)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Reset firewall rules
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallRuleReset true "request"
|
||||||
|
// @Success 200 {object} dto.FirewallRuleResetResponse
|
||||||
|
// @Failure 400 {object} dto.Response
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/rules/reset [post]
|
||||||
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"重置防火墙规则","formatEN":"reset firewall rules"}
|
||||||
|
func (b *BaseApi) ResetFirewallRules(c *gin.Context) {
|
||||||
|
var request dto.FirewallRuleReset
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := firewallService.Reset(c.Request.Context(), request)
|
||||||
|
if err != nil {
|
||||||
|
handleFirewallRuleError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Load one provider-native firewall object definition
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallNativeDetail true "request"
|
||||||
|
// @Success 200 {string} string
|
||||||
|
// @Failure 400 {object} dto.Response
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/rules/native/detail [post]
|
||||||
|
func (b *BaseApi) LoadFirewallNativeDetail(c *gin.Context) {
|
||||||
|
var request dto.FirewallNativeDetail
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info, err := firewallService.LoadFirewallNativeDetail(c.Request.Context(), request)
|
||||||
|
if err != nil {
|
||||||
|
handleFirewallRuleError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Queue firewall rule creation
|
||||||
|
// @Description Creation and import return a taskID immediately; validation and execution results are written to the task log.
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallRuleCreate true "request"
|
||||||
|
// @Success 200 {object} dto.FirewallRuleCreateResponse
|
||||||
|
// @Failure 400 {object} dto.Response
|
||||||
|
// @Failure 409 {object} dto.Response
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/rules [post]
|
||||||
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"添加防火墙规则","formatEN":"create firewall rules"}
|
||||||
|
func (b *BaseApi) CreateFirewallRules(c *gin.Context) {
|
||||||
|
var request dto.FirewallRuleCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := firewallService.Create(c.Request.Context(), request)
|
||||||
|
if err != nil {
|
||||||
|
handleFirewallRuleError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Queue firewall rule deletion
|
||||||
|
// @Description Deletes non-whitelist rules by scope and instance key. Returns a taskID immediately; results are written to the task log.
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallRuleDelete true "request"
|
||||||
|
// @Success 200 {object} dto.FirewallRuleDeleteResponse
|
||||||
|
// @Failure 400 {object} dto.Response
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/rules/delete [post]
|
||||||
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除防火墙规则","formatEN":"delete firewall rules"}
|
||||||
|
func (b *BaseApi) DeleteFirewallRules(c *gin.Context) {
|
||||||
|
var request dto.FirewallRuleDelete
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := firewallService.Delete(c.Request.Context(), request)
|
||||||
|
if err != nil {
|
||||||
|
handleFirewallRuleError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Update a firewall rule
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallRuleUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Failure 400 {object} dto.Response
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/rules/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["instanceKey"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新防火墙规则 [instanceKey]","formatEN":"update firewall rule [instanceKey]"}
|
||||||
|
func (b *BaseApi) UpdateFirewallRule(c *gin.Context) {
|
||||||
|
var request dto.FirewallRuleUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := firewallService.Update(c.Request.Context(), request); err != nil {
|
||||||
|
handleFirewallRuleError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Firewall
|
// @Tags Firewall
|
||||||
// @Summary load chain status with name
|
// @Summary Reorder a firewall rule
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.OperationWithName true "request"
|
// @Param request body dto.FirewallRuleReorder true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Failure 400 {object} dto.Response
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/rules/reorder [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["instanceKey"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"调整防火墙规则顺序 [instanceKey]","formatEN":"reorder firewall rule [instanceKey]"}
|
||||||
|
func (b *BaseApi) ReorderFirewallRule(c *gin.Context) {
|
||||||
|
var request dto.FirewallRuleReorder
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := firewallService.Reorder(c.Request.Context(), request); err != nil {
|
||||||
|
handleFirewallRuleError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleFirewallRuleError(c *gin.Context, err error) {
|
||||||
|
var businessErr buserr.BusinessError
|
||||||
|
isBusinessError := errors.As(err, &businessErr)
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, filter.ErrProtectedRule):
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusBadRequest, "FW_LOCKOUT_RISK", "ErrInvalidParams", err)
|
||||||
|
case errors.Is(err, filter.ErrRuleStale):
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusConflict, "FW_RULE_STALE", "ErrInvalidParams", err)
|
||||||
|
case errors.Is(err, filter.ErrUnsupportedScope), errors.Is(err, filter.ErrInvalidScope),
|
||||||
|
errors.Is(err, filter.ErrProviderUnavailable), errors.Is(err, filter.ErrAdapterUnavailable):
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusBadRequest, "FW_SCOPE_UNSUPPORTED", "ErrInvalidParams", err)
|
||||||
|
case errors.Is(err, filter.ErrInvalidRule), errors.Is(err, filter.ErrRuleOperation):
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusBadRequest, "FW_RULE_UNSUPPORTED", "ErrInvalidParams", err)
|
||||||
|
case isBusinessError && businessErr.Msg == "ErrRecordExist":
|
||||||
|
c.JSON(http.StatusOK, dto.Response{Code: http.StatusConflict, ErrorCode: "FW_RULE_DUPLICATE", Message: err.Error()})
|
||||||
|
c.Abort()
|
||||||
|
case isBusinessError && businessErr.Msg == "ErrFirewallRuleConflict":
|
||||||
|
c.JSON(http.StatusOK, dto.Response{Code: http.StatusConflict, ErrorCode: "FW_RULE_CONFLICT", Message: err.Error()})
|
||||||
|
c.Abort()
|
||||||
|
case isBusinessError && businessErr.Msg == "ErrInvalidParams":
|
||||||
|
c.JSON(http.StatusOK, dto.Response{Code: http.StatusBadRequest, ErrorCode: "FW_RULE_UNSUPPORTED", Message: err.Error()})
|
||||||
|
c.Abort()
|
||||||
|
default:
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusInternalServerError, "FW_APPLY_FAILED", "ErrInternalServer", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Load firewall settings
|
||||||
|
// @Success 200 {object} dto.FirewallSettings
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/settings [get]
|
||||||
|
func (b *BaseApi) LoadFirewallSettings(c *gin.Context) {
|
||||||
|
data, err := firewallSettingService.Load(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Create firewall port whitelist rules
|
||||||
|
// @Description Saves whitelist configuration and applies missing allowances; existing rules are not removed.
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallPortWhitelistCreate true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/firewall/filter/chain/status [post]
|
// @Router /hosts/firewall/settings/whitelist [post]
|
||||||
func (b *BaseApi) LoadChainStatus(c *gin.Context) {
|
// @x-panel-log {"bodyKeys":["rule"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建防火墙端口白名单","formatEN":"create firewall port whitelist"}
|
||||||
var req dto.OperationWithName
|
func (b *BaseApi) CreateFirewallPortWhitelist(c *gin.Context) {
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
var request dto.FirewallPortWhitelistCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if err := firewallSettingService.CreatePortWhitelist(c.Request.Context(), request); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
helper.SuccessWithData(c, iptablesService.LoadChainStatus(req))
|
// @Tags Firewall
|
||||||
|
// @Summary Update firewall port whitelist rules
|
||||||
|
// @Description Saves whitelist configuration and applies missing allowances; existing rules are not removed.
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallPortWhitelistUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/settings/whitelist/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["oldRule","rule"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"编辑防火墙端口白名单","formatEN":"update firewall port whitelist"}
|
||||||
|
func (b *BaseApi) UpdateFirewallPortWhitelist(c *gin.Context) {
|
||||||
|
var request dto.FirewallPortWhitelistUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := firewallSettingService.UpdatePortWhitelist(c.Request.Context(), request); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Delete firewall port whitelist rules
|
||||||
|
// @Description Removes whitelist configuration; existing firewall rules are not removed.
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallPortWhitelistDelete true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/settings/whitelist/delete [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["rules"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除防火墙端口白名单","formatEN":"delete firewall port whitelist"}
|
||||||
|
func (b *BaseApi) DeleteFirewallPortWhitelist(c *gin.Context) {
|
||||||
|
var request dto.FirewallPortWhitelistDelete
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := firewallSettingService.DeletePortWhitelist(c.Request.Context(), request); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Operate firewall backend
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallBackendOperation true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/settings/operate [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["subsystem","backend","operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"防火墙子系统 [subsystem] 后端 [operation] [backend]","formatEN":"[operation] firewall [subsystem] backend [backend]"}
|
||||||
|
func (b *BaseApi) OperateFirewallBackend(c *gin.Context) {
|
||||||
|
var request dto.FirewallBackendOperation
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := firewallSettingService.Operate(c.Request.Context(), request); err != nil {
|
||||||
|
var businessErr buserr.BusinessError
|
||||||
|
if errors.As(err, &businessErr) && businessErr.Msg == "ErrFirewallBackendCleanupRequired" {
|
||||||
|
c.JSON(http.StatusOK, dto.Response{Code: http.StatusConflict, ErrorCode: "FW_BACKEND_CLEANUP_REQUIRED", Message: err.Error()})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary List Docker port guard status and policies
|
||||||
|
// @Success 200 {object} dto.DockerPortGuardList
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/docker/ports [get]
|
||||||
|
func (b *BaseApi) ListDockerPortGuard(c *gin.Context) {
|
||||||
|
data, err := dockerPortGuardService.LoadOverview(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
handleDockerPortGuardError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary List Docker published ports
|
||||||
|
// @Success 200 {array} dto.DockerPortGuardContainer
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/docker/endpoints [get]
|
||||||
|
func (b *BaseApi) ListDockerPublishedPorts(c *gin.Context) {
|
||||||
|
data, err := dockerPortGuardService.LoadPublishedPorts(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
handleDockerPortGuardError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Operate Docker port guard
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.DockerPortGuardOperation true "request"
|
||||||
|
// @Success 200 {object} dto.FilterChainOperationResponse
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/docker/operate [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] Docker 端口防护","formatEN":"[operation] Docker port guard"}
|
||||||
|
func (b *BaseApi) OperateDockerPortGuard(c *gin.Context) {
|
||||||
|
var request dto.DockerPortGuardOperation
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if request.Operation == "initialize" {
|
||||||
|
result, err := dockerPortGuardService.QueueInitialization(request)
|
||||||
|
if err != nil {
|
||||||
|
handleDockerPortGuardError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := dockerPortGuardService.Operate(c.Request.Context(), request); err != nil {
|
||||||
|
handleDockerPortGuardError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Delete Docker port guard policies
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.DockerPortGuardPolicyBatchDelete true "request"
|
||||||
|
// @Success 200 {object} dto.FilterChainOperationResponse
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/docker/policies/delete/batch [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["uuids"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除 Docker 端口防护策略 [uuids]","formatEN":"delete Docker port guard policies [uuids]"}
|
||||||
|
func (b *BaseApi) DeleteDockerPortGuardPolicies(c *gin.Context) {
|
||||||
|
var request dto.DockerPortGuardPolicyBatchDelete
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := dockerPortGuardService.DeletePolicies(request)
|
||||||
|
if err != nil {
|
||||||
|
handleDockerPortGuardError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Batch upsert Docker port guard policies
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.DockerPortGuardPolicyBatch true "request"
|
||||||
|
// @Success 200 {object} dto.FilterChainOperationResponse
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/docker/policies/batch [post]
|
||||||
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"批量更新 Docker 端口防护策略","formatEN":"batch update Docker port guard policies"}
|
||||||
|
func (b *BaseApi) UpsertDockerPortGuardPolicies(c *gin.Context) {
|
||||||
|
var request dto.DockerPortGuardPolicyBatch
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := dockerPortGuardService.UpsertPolicies(request)
|
||||||
|
if err != nil {
|
||||||
|
handleDockerPortGuardError(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDockerPortGuardError(c *gin.Context, err error) {
|
||||||
|
var businessErr buserr.BusinessError
|
||||||
|
if errors.As(err, &businessErr) {
|
||||||
|
code, errorCode := http.StatusInternalServerError, ""
|
||||||
|
switch businessErr.Msg {
|
||||||
|
case "ErrDockerIptablesChainUnavailable":
|
||||||
|
code, errorCode = http.StatusServiceUnavailable, "FW_DOCKER_IPTABLES_CHAIN_UNAVAILABLE"
|
||||||
|
case "ErrDockerNftablesChainUnavailable":
|
||||||
|
code, errorCode = http.StatusServiceUnavailable, "FW_DOCKER_NFTABLES_CHAIN_UNAVAILABLE"
|
||||||
|
case "ErrInvalidParams":
|
||||||
|
code, errorCode = http.StatusBadRequest, "FW_DOCKER_GUARD_INVALID"
|
||||||
|
case "ErrDockerFailed":
|
||||||
|
code, errorCode = http.StatusServiceUnavailable, "FW_DOCKER_UNAVAILABLE"
|
||||||
|
}
|
||||||
|
if errorCode != "" {
|
||||||
|
c.JSON(http.StatusOK, dto.Response{Code: code, ErrorCode: errorCode, Message: err.Error()})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if errors.Is(err, docker.ErrUnavailable) {
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusServiceUnavailable, "FW_DOCKER_UNAVAILABLE", "ErrDockerFailed", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.ErrorWithBusinessCode(c, http.StatusInternalServerError, "FW_DOCKER_GUARD_FAILED", "ErrInternalServer", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary List firewall rule backups
|
||||||
|
// @Param subsystem query string false "Firewall subsystem" Enums(system,forwarding,docker) default(system)
|
||||||
|
// @Success 200 {object} dto.FirewallRuleBackups
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/rules/backups [get]
|
||||||
|
func (b *BaseApi) ListFirewallRuleBackups(c *gin.Context) {
|
||||||
|
result, err := firewallService.ListRuleBackups(c.Request.Context(), c.DefaultQuery("subsystem", "system"))
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Initialize, repair or bind one firewall address family
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallFamilyOperation true "request"
|
||||||
|
// @Success 200 {object} dto.FilterChainOperationResponse
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/family/operate [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["subsystem","family","operation"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operation] [subsystem] [family] 防火墙链","formatEN":"[operation] [subsystem] [family] firewall chains"}
|
||||||
|
func (b *BaseApi) OperateFirewallFamily(c *gin.Context) {
|
||||||
|
var request dto.FirewallFamilyOperation
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := firewallSettingService.OperateFamily(request)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Firewall
|
||||||
|
// @Summary Update firewall IPv6 support
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FirewallIPv6Operation true "request"
|
||||||
|
// @Success 200 {object} dto.FilterChainOperationResponse
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/firewall/settings/ipv6 [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["status"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"设置防火墙 IPv6 支持为 [status]","formatEN":"Set firewall IPv6 support to [status]"}
|
||||||
|
func (b *BaseApi) OperateFirewallIPv6(c *gin.Context) {
|
||||||
|
var request dto.FirewallIPv6Operation
|
||||||
|
if err := helper.CheckBindAndValidate(&request, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result, err := firewallSettingService.OperateIPv6(request)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, result)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/ai_tools/accelerator"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Load gpu / xpu info
|
||||||
|
// @Accept json
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/gpu/load [get]
|
||||||
|
func (b *BaseApi) LoadGpuInfo(c *gin.Context) {
|
||||||
|
ok, client := accelerator.New()
|
||||||
|
if ok {
|
||||||
|
snapshot, err := client.Collect(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if warning := snapshot.Warning(); warning != nil {
|
||||||
|
global.LOG.Warnf("load realtime accelerator data partially failed, err: %v", warning)
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, &snapshot.Info)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, &accelerator.Info{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags AI
|
||||||
|
// @Summary Get CPU options
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/gpu/options [get]
|
||||||
|
func (b *BaseApi) GetCPUOptions(c *gin.Context) {
|
||||||
|
helper.SuccessWithData(c, monitorService.LoadGPUOptions())
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Monitor
|
||||||
|
// @Summary Load monitor data
|
||||||
|
// @Param request body dto.MonitorGPUSearch true "request"
|
||||||
|
// @Success 200 {object} dto.MonitorGPUData
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/gpu/search [post]
|
||||||
|
func (b *BaseApi) LoadGPUMonitor(c *gin.Context) {
|
||||||
|
var req dto.MonitorGPUSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := monitorService.LoadGPUMonitorData(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
@@ -5,6 +5,12 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @Tags Health
|
||||||
|
// @Summary Check health
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /health/check [get]
|
||||||
func (b *BaseApi) CheckHealth(c *gin.Context) {
|
func (b *BaseApi) CheckHealth(c *gin.Context) {
|
||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,26 @@ func ErrorWithDetail(ctx *gin.Context, code int, msgKey string, err error) {
|
|||||||
ctx.Abort()
|
ctx.Abort()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ErrorWithBusinessCode(ctx *gin.Context, code int, businessCode, msgKey string, err error) {
|
||||||
|
res := dto.Response{
|
||||||
|
Code: code,
|
||||||
|
ErrorCode: businessCode,
|
||||||
|
Message: i18n.GetMsgWithDetail(msgKey, err.Error()),
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
ctx.Abort()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ErrorWithDetailAndData(ctx *gin.Context, code int, msgKey string, err error, data interface{}) {
|
||||||
|
res := dto.Response{
|
||||||
|
Code: code,
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
res.Message = i18n.GetMsgWithDetail(msgKey, err.Error())
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
ctx.Abort()
|
||||||
|
}
|
||||||
|
|
||||||
func InternalServer(ctx *gin.Context, err error) {
|
func InternalServer(ctx *gin.Context, err error) {
|
||||||
ErrorWithDetail(ctx, http.StatusInternalServerError, "ErrInternalServer", err)
|
ErrorWithDetail(ctx, http.StatusInternalServerError, "ErrInternalServer", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,15 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Create host
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.HostOperate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["name","addr"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建主机 [name][addr]","formatEN":"create host [name][addr]"}
|
||||||
func (b *BaseApi) CreateHost(c *gin.Context) {
|
func (b *BaseApi) CreateHost(c *gin.Context) {
|
||||||
var req dto.HostOperate
|
var req dto.HostOperate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -21,6 +30,14 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, host)
|
helper.SuccessWithData(c, host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Test by info
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.HostConnTest true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/test/byinfo [post]
|
||||||
func (b *BaseApi) TestByInfo(c *gin.Context) {
|
func (b *BaseApi) TestByInfo(c *gin.Context) {
|
||||||
var req dto.HostConnTest
|
var req dto.HostConnTest
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -30,6 +47,14 @@ func (b *BaseApi) TestByInfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, hostService.TestByInfo(req))
|
helper.SuccessWithData(c, hostService.TestByInfo(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Test by ID
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.OperateByID true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/test/byid [post]
|
||||||
func (b *BaseApi) TestByID(c *gin.Context) {
|
func (b *BaseApi) TestByID(c *gin.Context) {
|
||||||
var req dto.OperateByID
|
var req dto.OperateByID
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -39,6 +64,14 @@ func (b *BaseApi) TestByID(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, hostService.TestLocalConn(req.ID))
|
helper.SuccessWithData(c, hostService.TestLocalConn(req.ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Host tree
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.SearchForTree true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/tree [post]
|
||||||
func (b *BaseApi) HostTree(c *gin.Context) {
|
func (b *BaseApi) HostTree(c *gin.Context) {
|
||||||
var req dto.SearchForTree
|
var req dto.SearchForTree
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -53,6 +86,14 @@ func (b *BaseApi) HostTree(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Search host
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.SearchPageWithGroup true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/search [post]
|
||||||
func (b *BaseApi) SearchHost(c *gin.Context) {
|
func (b *BaseApi) SearchHost(c *gin.Context) {
|
||||||
var req dto.SearchPageWithGroup
|
var req dto.SearchPageWithGroup
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -68,6 +109,15 @@ func (b *BaseApi) SearchHost(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, dto.PageResult{Items: list, Total: total})
|
helper.SuccessWithData(c, dto.PageResult{Items: list, Total: total})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Delete host
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.OperateByIDs true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"hosts","output_column":"name","output_value":"names"}],"formatZH":"删除主机 [names]","formatEN":"delete host [names]"}
|
||||||
func (b *BaseApi) DeleteHost(c *gin.Context) {
|
func (b *BaseApi) DeleteHost(c *gin.Context) {
|
||||||
var req dto.OperateByIDs
|
var req dto.OperateByIDs
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -81,6 +131,15 @@ func (b *BaseApi) DeleteHost(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Update host
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.HostOperate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["name","addr"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新主机 [name][addr]","formatEN":"update host [name][addr]"}
|
||||||
func (b *BaseApi) UpdateHost(c *gin.Context) {
|
func (b *BaseApi) UpdateHost(c *gin.Context) {
|
||||||
var req dto.HostOperate
|
var req dto.HostOperate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -140,6 +199,15 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, hostItem)
|
helper.SuccessWithData(c, hostItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Update host group
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ChangeGroup true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/update/group [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","groupID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"hosts","output_column":"name","output_value":"name"}],"formatZH":"更新主机 [name] 分组","formatEN":"update host [name] group"}
|
||||||
func (b *BaseApi) UpdateHostGroup(c *gin.Context) {
|
func (b *BaseApi) UpdateHostGroup(c *gin.Context) {
|
||||||
var req dto.ChangeGroup
|
var req dto.ChangeGroup
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -153,6 +221,14 @@ func (b *BaseApi) UpdateHostGroup(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host
|
||||||
|
// @Summary Get host by ID
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.OperateByID true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/info [post]
|
||||||
func (b *BaseApi) GetHostByID(c *gin.Context) {
|
func (b *BaseApi) GetHostByID(c *gin.Context) {
|
||||||
var req dto.OperateByID
|
var req dto.OperateByID
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import (
|
|||||||
// @Tags Host tool
|
// @Tags Host tool
|
||||||
// @Summary Get tool status
|
// @Summary Get tool status
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body request.HostToolReq true "request"
|
// @Param request body request.HostToolTypeReq true "request"
|
||||||
// @Success 200 {object} response.HostToolRes
|
// @Success 200 {object} response.HostToolRes
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/tool [post]
|
// @Router /hosts/tool/status [post]
|
||||||
func (b *BaseApi) GetToolStatus(c *gin.Context) {
|
func (b *BaseApi) GetToolStatus(c *gin.Context) {
|
||||||
var req request.HostToolReq
|
var req request.HostToolTypeReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -53,14 +53,14 @@ func (b *BaseApi) InitToolConfig(c *gin.Context) {
|
|||||||
// @Tags Host tool
|
// @Tags Host tool
|
||||||
// @Summary Operate tool
|
// @Summary Operate tool
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body request.HostToolReq true "request"
|
// @Param request body request.HostToolOperateReq true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/tool/operate [post]
|
// @Router /hosts/tool/operate [post]
|
||||||
// @x-panel-log {"bodyKeys":["operate","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] [type] ","formatEN":"[operate] [type]"}
|
// @x-panel-log {"bodyKeys":["operate","type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] [type] ","formatEN":"[operate] [type]"}
|
||||||
func (b *BaseApi) OperateTool(c *gin.Context) {
|
func (b *BaseApi) OperateTool(c *gin.Context) {
|
||||||
var req request.HostToolReq
|
var req request.HostToolOperateReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -75,19 +75,18 @@ func (b *BaseApi) OperateTool(c *gin.Context) {
|
|||||||
// @Tags Host tool
|
// @Tags Host tool
|
||||||
// @Summary Get tool config
|
// @Summary Get tool config
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body request.HostToolConfig true "request"
|
// @Param request body request.HostToolTypeReq true "request"
|
||||||
// @Success 200 {object} response.HostToolConfig
|
// @Success 200 {object} response.HostToolConfig
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/tool/config [post]
|
// @Router /hosts/tool/config/get [post]
|
||||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] 主机工具配置文件 ","formatEN":"[operate] tool config"}
|
func (b *BaseApi) GetToolConfig(c *gin.Context) {
|
||||||
func (b *BaseApi) OperateToolConfig(c *gin.Context) {
|
var req request.HostToolTypeReq
|
||||||
var req request.HostToolConfig
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
config, err := hostToolService.OperateToolConfig(req)
|
config, err := hostToolService.GetToolConfig(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
@@ -95,6 +94,28 @@ func (b *BaseApi) OperateToolConfig(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, config)
|
helper.SuccessWithData(c, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Host tool
|
||||||
|
// @Summary Update tool config
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.HostToolConfigUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/tool/config/set [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 [type] 主机工具配置文件 ","formatEN":"update [type] tool config"}
|
||||||
|
func (b *BaseApi) UpdateToolConfig(c *gin.Context) {
|
||||||
|
var req request.HostToolConfigUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := hostToolService.UpdateToolConfig(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Host tool
|
// @Tags Host tool
|
||||||
// @Summary Create Supervisor process
|
// @Summary Create Supervisor process
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -137,18 +158,44 @@ func (b *BaseApi) GetProcess(c *gin.Context) {
|
|||||||
// @Tags Host tool
|
// @Tags Host tool
|
||||||
// @Summary Get Supervisor process config file
|
// @Summary Get Supervisor process config file
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body request.SupervisorProcessFileReq true "request"
|
// @Param request body request.HostSupervisorProcessFileGetReq true "request"
|
||||||
// @Success 200 {string} content
|
// @Success 200 {string} content
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/tool/supervisor/process/file [post]
|
// @Router /hosts/tool/supervisor/process/file/get [post]
|
||||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"[operate] Supervisor 进程文件 ","formatEN":"[operate] Supervisor Process Config file"}
|
|
||||||
func (b *BaseApi) GetProcessFile(c *gin.Context) {
|
func (b *BaseApi) GetProcessFile(c *gin.Context) {
|
||||||
var req request.SupervisorProcessFileReq
|
var req request.HostSupervisorProcessFileGetReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
content, err := hostToolService.OperateSupervisorProcessFile(req)
|
content, err := hostToolService.GetSupervisorProcessFile(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Host tool
|
||||||
|
// @Summary Operate Supervisor process config file
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.HostSupervisorProcessFileOperateReq true "request"
|
||||||
|
// @Success 200 {string} content
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @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) OperateProcessFile(c *gin.Context) {
|
||||||
|
var req request.HostSupervisorProcessFileOperateReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
content, err := hostToolService.OperateSupervisorProcessFile(request.SupervisorProcessFileReq{
|
||||||
|
Name: req.Name,
|
||||||
|
Operate: req.Operate,
|
||||||
|
Content: req.Content,
|
||||||
|
File: req.File,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,3 +21,57 @@ func (b *BaseApi) GetSystemFiles(c *gin.Context) {
|
|||||||
|
|
||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Logs
|
||||||
|
// @Summary Get host system log status
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} dto.SystemLogStatus
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /logs/system/status [get]
|
||||||
|
func (b *BaseApi) GetSystemLogStatus(c *gin.Context) {
|
||||||
|
data, err := logService.GetSystemLogStatus()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Logs
|
||||||
|
// @Summary Read host logs
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.SystemLogReq true "request"
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} dto.SystemLogRes
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /logs/system/read [post]
|
||||||
|
func (b *BaseApi) ReadSystemLog(c *gin.Context) {
|
||||||
|
var req dto.SystemLogReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := logService.ReadSystemLog(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Logs
|
||||||
|
// @Summary List running host services
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {array} string
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /logs/system/services [get]
|
||||||
|
func (b *BaseApi) ListRunningServices(c *gin.Context) {
|
||||||
|
data, err := logService.ListRunningServices()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,27 @@ func (b *BaseApi) PageMcpServers(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, list)
|
helper.SuccessWithData(c, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags McpServer
|
||||||
|
// @Summary Load mcp server detail
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.McpServerDetail true "request"
|
||||||
|
// @Success 200 {object} response.McpServerDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/mcp/server/detail [post]
|
||||||
|
func (b *BaseApi) LoadMcpServerDetail(c *gin.Context) {
|
||||||
|
var req request.McpServerDetail
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := mcpServerService.Detail(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags McpServer
|
// @Tags McpServer
|
||||||
// @Summary Create mcp server
|
// @Summary Create mcp server
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -107,6 +128,48 @@ func (b *BaseApi) OperateMcpServer(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags McpServer
|
||||||
|
// @Summary Sync mcp server status
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.McpServerStatusSync true "request"
|
||||||
|
// @Success 200 {array} response.McpServerStatusDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/mcp/server/status/sync [post]
|
||||||
|
func (b *BaseApi) SyncMcpServerStatus(c *gin.Context) {
|
||||||
|
var req request.McpServerStatusSync
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := mcpServerService.SyncStatus(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags McpServer
|
||||||
|
// @Summary Test mcp server connection
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.McpServerConnectionTest true "request"
|
||||||
|
// @Success 200 {object} response.McpServerConnectionTestRes
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/mcp/server/connection/test [post]
|
||||||
|
func (b *BaseApi) TestMcpServerConnection(c *gin.Context) {
|
||||||
|
var req request.McpServerConnectionTest
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := mcpServerService.TestConnection(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags McpServer
|
// @Tags McpServer
|
||||||
// @Summary Bind Domain for mcp server
|
// @Summary Bind Domain for mcp server
|
||||||
// @Accept json
|
// @Accept json
|
||||||
|
|||||||
+23
-49
@@ -1,13 +1,9 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/dto"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/shirou/gopsutil/v4/disk"
|
|
||||||
"github.com/shirou/gopsutil/v4/net"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// @Tags Monitor
|
// @Tags Monitor
|
||||||
@@ -32,35 +28,19 @@ func (b *BaseApi) LoadMonitor(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Monitor
|
// @Tags Monitor
|
||||||
// @Summary Load monitor data
|
// @Summary Clean host or GPU monitor data
|
||||||
// @Param request body dto.MonitorGPUSearch true "request"
|
// @Param request body dto.MonitorClean true "request"
|
||||||
// @Success 200 {object} dto.MonitorGPUData
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /hosts/monitor/gpu/search [post]
|
|
||||||
func (b *BaseApi) LoadGPUMonitor(c *gin.Context) {
|
|
||||||
var req dto.MonitorGPUSearch
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := monitorService.LoadGPUMonitorData(req)
|
|
||||||
if err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Monitor
|
|
||||||
// @Summary Clean monitor data
|
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/monitor/clean [post]
|
// @Router /hosts/monitor/clean [post]
|
||||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空监控数据","formatEN":"clean monitor datas"}
|
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空 [type] 监控数据","formatEN":"clean [type] monitoring data"}
|
||||||
func (b *BaseApi) CleanMonitor(c *gin.Context) {
|
func (b *BaseApi) CleanMonitor(c *gin.Context) {
|
||||||
if err := monitorService.CleanData(); err != nil {
|
var req dto.MonitorClean
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := monitorService.CleanData(req.Type); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -91,7 +71,7 @@ func (b *BaseApi) LoadMonitorSetting(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/monitor/setting/update [post]
|
// @Router /hosts/monitor/setting/update [post]
|
||||||
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改默认监控网卡 [name]-[value]","formatEN":"update default monitor [name]-[value]"}
|
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改默认监控网卡 [key]-[value]","formatEN":"update default monitor [key]-[value]"}
|
||||||
func (b *BaseApi) UpdateMonitorSetting(c *gin.Context) {
|
func (b *BaseApi) UpdateMonitorSetting(c *gin.Context) {
|
||||||
var req dto.MonitorSettingUpdate
|
var req dto.MonitorSettingUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -105,28 +85,22 @@ func (b *BaseApi) UpdateMonitorSetting(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Monitor
|
||||||
|
// @Summary Get network options
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/monitor/netoptions [get]
|
||||||
func (b *BaseApi) GetNetworkOptions(c *gin.Context) {
|
func (b *BaseApi) GetNetworkOptions(c *gin.Context) {
|
||||||
netStat, _ := net.IOCounters(true)
|
helper.SuccessWithData(c, monitorService.LoadNetworkOptions())
|
||||||
var options []string
|
|
||||||
options = append(options, "all")
|
|
||||||
for _, net := range netStat {
|
|
||||||
options = append(options, net.Name)
|
|
||||||
}
|
|
||||||
sort.Strings(options)
|
|
||||||
helper.SuccessWithData(c, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Monitor
|
||||||
|
// @Summary Get IO options
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/monitor/iooptions [get]
|
||||||
func (b *BaseApi) GetIOOptions(c *gin.Context) {
|
func (b *BaseApi) GetIOOptions(c *gin.Context) {
|
||||||
diskStat, _ := disk.IOCounters()
|
helper.SuccessWithData(c, monitorService.LoadIOOptions())
|
||||||
var options []string
|
|
||||||
options = append(options, "all")
|
|
||||||
for _, net := range diskStat {
|
|
||||||
options = append(options, net.Name)
|
|
||||||
}
|
|
||||||
sort.Strings(options)
|
|
||||||
helper.SuccessWithData(c, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseApi) GetCPUOptions(c *gin.Context) {
|
|
||||||
helper.SuccessWithData(c, monitorService.LoadGPUOptions())
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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) LoadVLLMMonitor(c *gin.Context) {
|
||||||
|
var req dto.MonitorVLLMSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := monitorService.LoadVLLMMonitorData(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) LoadVLLMCurrent(c *gin.Context) {
|
||||||
|
var req dto.MonitorVLLMCurrent
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := monitorService.LoadVLLMCurrent(c.Request.Context(), req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) CleanVLLMMonitor(c *gin.Context) {
|
||||||
|
var req dto.MonitorVLLMClean
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := monitorService.CleanVLLMMonitor(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
@@ -5,9 +5,20 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||||
websocket2 "github.com/1Panel-dev/1Panel/agent/utils/websocket"
|
websocket2 "github.com/1Panel-dev/1Panel/agent/utils/websocket"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @Tags Process
|
||||||
|
// @Summary Process ws
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /process/ws [get]
|
||||||
func (b *BaseApi) ProcessWs(c *gin.Context) {
|
func (b *BaseApi) ProcessWs(c *gin.Context) {
|
||||||
|
if !websocket.IsWebSocketUpgrade(c.Request) {
|
||||||
|
helper.Success(c)
|
||||||
|
return
|
||||||
|
}
|
||||||
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
|
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ func (b *BaseApi) CreateRuntime(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /runtimes/del [post]
|
// @Router /runtimes/del [post]
|
||||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除运行环境 [name]","formatEN":"Delete runtime [name]"}
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除运行环境 [id]","formatEN":"Delete runtime [id]"}
|
||||||
func (b *BaseApi) DeleteRuntime(c *gin.Context) {
|
func (b *BaseApi) DeleteRuntime(c *gin.Context) {
|
||||||
var req request.RuntimeDelete
|
var req request.RuntimeDelete
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -81,6 +81,7 @@ func (b *BaseApi) DeleteRuntime(c *gin.Context) {
|
|||||||
// @Success 200 {array} dto.AppResource
|
// @Success 200 {array} dto.AppResource
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
// @Param id path integer true "id"
|
||||||
// @Router /runtimes/installed/delete/check/:id [get]
|
// @Router /runtimes/installed/delete/check/:id [get]
|
||||||
func (b *BaseApi) DeleteRuntimeCheck(c *gin.Context) {
|
func (b *BaseApi) DeleteRuntimeCheck(c *gin.Context) {
|
||||||
runTimeId, err := helper.GetIntParamByKey(c, "id")
|
runTimeId, err := helper.GetIntParamByKey(c, "id")
|
||||||
@@ -120,7 +121,7 @@ func (b *BaseApi) UpdateRuntime(c *gin.Context) {
|
|||||||
// @Tags Runtime
|
// @Tags Runtime
|
||||||
// @Summary Get runtime
|
// @Summary Get runtime
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param id path string true "request"
|
// @Param id path integer true "request"
|
||||||
// @Success 200 {object} response.RuntimeDTO
|
// @Success 200 {object} response.RuntimeDTO
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
@@ -168,7 +169,7 @@ func (b *BaseApi) GetNodePackageRunScript(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /runtimes/operate [post]
|
// @Router /runtimes/operate [post]
|
||||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"操作运行环境 [name]","formatEN":"Operate runtime [name]"}
|
// @x-panel-log {"bodyKeys":["ID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ID","isList":false,"db":"runtimes","output_column":"name","output_value":"name"}],"formatZH":"操作运行环境 [name]","formatEN":"Operate runtime [name]"}
|
||||||
func (b *BaseApi) OperateRuntime(c *gin.Context) {
|
func (b *BaseApi) OperateRuntime(c *gin.Context) {
|
||||||
var req request.RuntimeOperate
|
var req request.RuntimeOperate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -242,7 +243,7 @@ func (b *BaseApi) SyncStatus(c *gin.Context) {
|
|||||||
// @Tags Runtime
|
// @Tags Runtime
|
||||||
// @Summary Get php runtime extension
|
// @Summary Get php runtime extension
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param id path string true "request"
|
// @Param id path integer true "request"
|
||||||
// @Success 200 {object} response.PHPExtensionRes
|
// @Success 200 {object} response.PHPExtensionRes
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Tags RuntimeDiagnostics
|
||||||
|
// @Summary Load runtime diagnostics summary
|
||||||
|
// @Success 200 {object} dto.RuntimeDiagnosticsSummary
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/diagnostics/summary [get]
|
||||||
|
func (b *BaseApi) LoadRuntimeDiagnosticsSummary(c *gin.Context) {
|
||||||
|
data, err := runtimeDiagnosticsService.Summary()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags RuntimeDiagnostics
|
||||||
|
// @Summary Load grouped goroutine snapshot
|
||||||
|
// @Success 200 {object} dto.RuntimeGoroutineSnapshot
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/diagnostics/goroutines [get]
|
||||||
|
func (b *BaseApi) LoadRuntimeGoroutines(c *gin.Context) {
|
||||||
|
data, err := runtimeDiagnosticsService.Goroutines()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithDataGzipped(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags RuntimeDiagnostics
|
||||||
|
// @Summary Capture runtime profile
|
||||||
|
// @Param request body dto.RuntimeProfileCreate true "request"
|
||||||
|
// @Success 200 {file} file
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/diagnostics/profiles [post]
|
||||||
|
func (b *BaseApi) CreateRuntimeProfile(c *gin.Context) {
|
||||||
|
var req dto.RuntimeProfileCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
profile, err := runtimeDiagnosticsService.CreateProfile(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer os.Remove(profile.Path)
|
||||||
|
c.Header("Content-Disposition", `attachment; filename="`+profile.Name+`"`)
|
||||||
|
c.Header("Content-Type", "application/octet-stream")
|
||||||
|
c.File(profile.Path)
|
||||||
|
c.Abort()
|
||||||
|
}
|
||||||
+87
-30
@@ -1,15 +1,12 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/dto"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||||
"github.com/1Panel-dev/1Panel/agent/global"
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/ssh"
|
"github.com/1Panel-dev/1Panel/agent/utils/ssh"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// @Tags System Setting
|
// @Tags System Setting
|
||||||
@@ -27,6 +24,12 @@ func (b *BaseApi) GetSettingInfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, setting)
|
helper.SuccessWithData(c, setting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Get terminal AI setting info
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /settings/terminal/ai/search [post]
|
||||||
func (b *BaseApi) GetTerminalAISettingInfo(c *gin.Context) {
|
func (b *BaseApi) GetTerminalAISettingInfo(c *gin.Context) {
|
||||||
setting, err := settingService.GetTerminalAIInfo()
|
setting, err := settingService.GetTerminalAIInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -49,14 +52,14 @@ func (b *BaseApi) GetSystemAvailable(c *gin.Context) {
|
|||||||
// @Tags System Setting
|
// @Tags System Setting
|
||||||
// @Summary Update system setting
|
// @Summary Update system setting
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.SettingUpdate true "request"
|
// @Param request body dto.AgentSettingUpdate true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /settings/update [post]
|
// @Router /settings/update [post]
|
||||||
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统配置 [key] => [value]","formatEN":"update system setting [key] => [value]"}
|
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改系统配置 [key] => [value]","formatEN":"update system setting [key] => [value]"}
|
||||||
func (b *BaseApi) UpdateSetting(c *gin.Context) {
|
func (b *BaseApi) UpdateSetting(c *gin.Context) {
|
||||||
var req dto.SettingUpdate
|
var req dto.AgentSettingUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -68,6 +71,15 @@ func (b *BaseApi) UpdateSetting(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Update terminal AI setting
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.TerminalAIInfo true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /settings/terminal/ai/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["aiStatus","aiAccountId"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新终端 AI 设置 [aiStatus][aiAccountId]","formatEN":"update terminal AI setting [aiStatus][aiAccountId]"}
|
||||||
func (b *BaseApi) UpdateTerminalAISetting(c *gin.Context) {
|
func (b *BaseApi) UpdateTerminalAISetting(c *gin.Context) {
|
||||||
var req dto.TerminalAIInfo
|
var req dto.TerminalAIInfo
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -81,6 +93,12 @@ func (b *BaseApi) UpdateTerminalAISetting(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Get file manage AI setting info
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /settings/files/ai/search [post]
|
||||||
func (b *BaseApi) GetFileManageAISettingInfo(c *gin.Context) {
|
func (b *BaseApi) GetFileManageAISettingInfo(c *gin.Context) {
|
||||||
setting, err := settingService.GetFileManageAIInfo()
|
setting, err := settingService.GetFileManageAIInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -90,6 +108,15 @@ func (b *BaseApi) GetFileManageAISettingInfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, setting)
|
helper.SuccessWithData(c, setting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Update file manage AI setting
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FileManageAIInfo true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /settings/files/ai/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["aiStatus","aiAccountId"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新文件管理 AI 设置 [aiStatus][aiAccountId]","formatEN":"update file manage AI setting [aiStatus][aiAccountId]"}
|
||||||
func (b *BaseApi) UpdateFileManageAISetting(c *gin.Context) {
|
func (b *BaseApi) UpdateFileManageAISetting(c *gin.Context) {
|
||||||
var req dto.FileManageAIInfo
|
var req dto.FileManageAIInfo
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -102,6 +129,51 @@ func (b *BaseApi) UpdateFileManageAISetting(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Load file history setting info
|
||||||
|
// @Success 200 {object} response.FileHistorySettingInfo
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /settings/file-history/search [post]
|
||||||
|
func (b *BaseApi) GetFileHistorySettingInfo(c *gin.Context) {
|
||||||
|
setting, err := settingService.GetFileHistorySettingInfo()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, setting)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Update file history setting
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileHistorySettingUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /settings/file-history/update [post]
|
||||||
|
func (b *BaseApi) UpdateFileHistorySetting(c *gin.Context) {
|
||||||
|
var req request.FileHistorySettingUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := settingService.UpdateFileHistorySetting(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Load website dir
|
||||||
|
// @Success 200 {string} path
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /settings/website/dir [get]
|
||||||
|
func (b *BaseApi) LoadWebsiteDir(c *gin.Context) {
|
||||||
|
helper.SuccessWithData(c, settingService.GetWebsiteDir())
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags System Setting
|
// @Tags System Setting
|
||||||
// @Summary Load local backup dir
|
// @Summary Load local backup dir
|
||||||
// @Success 200 {string} path
|
// @Success 200 {string} path
|
||||||
@@ -122,6 +194,12 @@ func (b *BaseApi) LoadLocalConn(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, settingService.GetLocalConn())
|
helper.SuccessWithData(c, settingService.GetLocalConn())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Check local conn
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /settings/ssh/check [post]
|
||||||
func (b *BaseApi) CheckLocalConn(c *gin.Context) {
|
func (b *BaseApi) CheckLocalConn(c *gin.Context) {
|
||||||
client, err := loadLocalConn()
|
client, err := loadLocalConn()
|
||||||
if err == nil && client != nil {
|
if err == nil && client != nil {
|
||||||
@@ -137,7 +215,7 @@ func (b *BaseApi) CheckLocalConn(c *gin.Context) {
|
|||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /settings/ssh/conn/default [post]
|
// @Router /settings/ssh/default [post]
|
||||||
// @x-panel-log {"bodyKeys":["defaultConn"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"本地终端默认连接 [defaultConn]","formatEN":"update system default conn [defaultConn]"}
|
// @x-panel-log {"bodyKeys":["defaultConn"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"本地终端默认连接 [defaultConn]","formatEN":"update system default conn [defaultConn]"}
|
||||||
func (b *BaseApi) SetDefaultIsConn(c *gin.Context) {
|
func (b *BaseApi) SetDefaultIsConn(c *gin.Context) {
|
||||||
var req dto.SSHDefaultConn
|
var req dto.SSHDefaultConn
|
||||||
@@ -187,12 +265,8 @@ func (b *BaseApi) SaveLocalConn(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func loadLocalConn() (*ssh.SSHClient, error) {
|
func loadLocalConn() (*ssh.SSHClient, error) {
|
||||||
connInfoInDB := settingService.GetSettingByKey("LocalSSHConn")
|
connInDB, err := settingService.GetLocalConnForSSH()
|
||||||
if len(connInfoInDB) == 0 {
|
if err != nil {
|
||||||
return nil, errors.New("no such ssh conn info in db!")
|
|
||||||
}
|
|
||||||
var connInDB model.LocalConnInfo
|
|
||||||
if err := json.Unmarshal([]byte(connInfoInDB), &connInDB); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshInfo := ssh.ConnInfo{
|
sshInfo := ssh.ConnInfo{
|
||||||
@@ -207,23 +281,6 @@ func loadLocalConn() (*ssh.SSHClient, error) {
|
|||||||
return ssh.NewClient(sshInfo)
|
return ssh.NewClient(sshInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags System Setting
|
|
||||||
// @Summary Load system setting by key
|
|
||||||
// @Param key path string true "key"
|
|
||||||
// @Success 200 {object} dto.SettingInfo
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /settings/get/{key} [get]
|
|
||||||
func (b *BaseApi) GetSettingByKey(c *gin.Context) {
|
|
||||||
key := c.Param("key")
|
|
||||||
if len(key) == 0 {
|
|
||||||
helper.BadRequest(c, errors.New("key is empty"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
value := settingService.GetSettingByKey(key)
|
|
||||||
helper.SuccessWithData(c, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags System Setting
|
// @Tags System Setting
|
||||||
// @Summary Save common description
|
// @Summary Save common description
|
||||||
// @Accept json
|
// @Accept json
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ func (b *BaseApi) CreateRootCert(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
if err := loadCertAfterDecrypt(&req); err != nil {
|
if err := loadCertAfterDecrypt(&req); err != nil {
|
||||||
helper.BadRequest(c, err)
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if err := sshService.CreateRootCert(req); err != nil {
|
if err := sshService.CreateRootCert(req); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
@@ -107,6 +108,7 @@ func (b *BaseApi) EditRootCert(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
if err := loadCertAfterDecrypt(&req); err != nil {
|
if err := loadCertAfterDecrypt(&req); err != nil {
|
||||||
helper.BadRequest(c, err)
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if err := sshService.EditRootCert(req); err != nil {
|
if err := sshService.EditRootCert(req); err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
@@ -224,6 +226,21 @@ func (b *BaseApi) ExportSSHLogs(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, tmpFile)
|
helper.SuccessWithData(c, tmpFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags SSH
|
||||||
|
// @Summary Clean host SSH logs
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/ssh/log/clean [post]
|
||||||
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFunctions":[],"formatZH":"清空 SSH 登录日志","formatEN":"clean SSH login logs"}
|
||||||
|
func (b *BaseApi) CleanSSHLogs(c *gin.Context) {
|
||||||
|
if err := sshService.CleanLog(); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Load host SSH conf
|
// @Summary Load host SSH conf
|
||||||
// @Accept json
|
// @Accept json
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
"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/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,6 +32,31 @@ func (b *BaseApi) PageTasks(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags TaskLog
|
||||||
|
// @Summary Read task log by Line
|
||||||
|
// @Param request body request.TaskLogReadReq true "request"
|
||||||
|
// @Success 200 {object} response.FileLineContent
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /logs/tasks/read [post]
|
||||||
|
func (b *BaseApi) ReadTaskLogByLine(c *gin.Context) {
|
||||||
|
var req request.TaskLogReadReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var res *response.FileLineContent
|
||||||
|
res, err := taskService.ReadByLine(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if res.TotalLines > 100 {
|
||||||
|
helper.SuccessWithDataGzipped(c, res)
|
||||||
|
} else {
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags TaskLog
|
// @Tags TaskLog
|
||||||
// @Summary Get the number of executing tasks
|
// @Summary Get the number of executing tasks
|
||||||
// @Success 200 {integer} int64
|
// @Success 200 {integer} int64
|
||||||
|
|||||||
@@ -6,6 +6,14 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// @Tags TensorRT LLM
|
||||||
|
// @Summary Page TensorRT LLMs
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.TensorRTLLMSearch true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/tensorrt/search [post]
|
||||||
func (b *BaseApi) PageTensorRTLLMs(c *gin.Context) {
|
func (b *BaseApi) PageTensorRTLLMs(c *gin.Context) {
|
||||||
var req request.TensorRTLLMSearch
|
var req request.TensorRTLLMSearch
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -15,6 +23,15 @@ func (b *BaseApi) PageTensorRTLLMs(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, list)
|
helper.SuccessWithData(c, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags TensorRT LLM
|
||||||
|
// @Summary Create TensorRT LLM
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.TensorRTLLMCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/tensorrt/create [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建 TensorRT LLM [name]","formatEN":"create TensorRT LLM [name]"}
|
||||||
func (b *BaseApi) CreateTensorRTLLM(c *gin.Context) {
|
func (b *BaseApi) CreateTensorRTLLM(c *gin.Context) {
|
||||||
var req request.TensorRTLLMCreate
|
var req request.TensorRTLLMCreate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -28,6 +45,15 @@ func (b *BaseApi) CreateTensorRTLLM(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags TensorRT LLM
|
||||||
|
// @Summary Update TensorRT LLM
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.TensorRTLLMUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/tensorrt/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新 TensorRT LLM [id][name]","formatEN":"update TensorRT LLM [id][name]"}
|
||||||
func (b *BaseApi) UpdateTensorRTLLM(c *gin.Context) {
|
func (b *BaseApi) UpdateTensorRTLLM(c *gin.Context) {
|
||||||
var req request.TensorRTLLMUpdate
|
var req request.TensorRTLLMUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -41,6 +67,15 @@ func (b *BaseApi) UpdateTensorRTLLM(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags TensorRT LLM
|
||||||
|
// @Summary Delete TensorRT LLM
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.TensorRTLLMDelete true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/tensorrt/delete [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除 TensorRT LLM [id]","formatEN":"delete TensorRT LLM [id]"}
|
||||||
func (b *BaseApi) DeleteTensorRTLLM(c *gin.Context) {
|
func (b *BaseApi) DeleteTensorRTLLM(c *gin.Context) {
|
||||||
var req request.TensorRTLLMDelete
|
var req request.TensorRTLLMDelete
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -54,6 +89,15 @@ func (b *BaseApi) DeleteTensorRTLLM(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags TensorRT LLM
|
||||||
|
// @Summary Operate TensorRT LLM
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.TensorRTLLMOperate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /ai/tensorrt/operate [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","operate"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"操作 TensorRT LLM [id][operate]","formatEN":"operate TensorRT LLM [id][operate]"}
|
||||||
func (b *BaseApi) OperateTensorRTLLM(c *gin.Context) {
|
func (b *BaseApi) OperateTensorRTLLM(c *gin.Context) {
|
||||||
var req request.TensorRTLLMOperate
|
var req request.TensorRTLLMOperate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
+259
-88
@@ -1,14 +1,19 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"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/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/service"
|
"github.com/1Panel-dev/1Panel/agent/app/service"
|
||||||
"github.com/1Panel-dev/1Panel/agent/global"
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||||
@@ -17,101 +22,278 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
gossh "golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *BaseApi) WsSSH(c *gin.Context) {
|
// @Tags Terminal
|
||||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
// @Summary Ws local terminal
|
||||||
if err != nil {
|
// @Param command query string false "command"
|
||||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
// @Param session query string false "session id to reattach"
|
||||||
|
// @Param terminalPersistent query boolean false "allow recovery after an unexpected disconnect"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/terminal/local [get]
|
||||||
|
func (b *BaseApi) WsLocalTerminal(c *gin.Context) {
|
||||||
|
b.runSSHSession(c, "local", loadLocalConn, c.DefaultQuery("command", ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Terminal
|
||||||
|
// @Summary Ws host SSH
|
||||||
|
// @Param id query integer false "id"
|
||||||
|
// @Param command query string false "command"
|
||||||
|
// @Param session query string false "session id to reattach"
|
||||||
|
// @Param title query string false "session title shown in the session list"
|
||||||
|
// @Param terminalPersistent query boolean false "allow recovery after an unexpected disconnect"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/terminal/ssh [get]
|
||||||
|
func (b *BaseApi) WsHostSSH(c *gin.Context) {
|
||||||
|
b.runSSHSession(c, "ssh", func() (*ssh.SSHClient, error) {
|
||||||
|
hostID, _ := strconv.Atoi(c.DefaultQuery("id", "0"))
|
||||||
|
if hostID <= 0 {
|
||||||
|
return nil, errors.New("missing host id")
|
||||||
|
}
|
||||||
|
host, err := service.GetHostInfo(uint(hostID))
|
||||||
|
return newHostSSHClient(host, err)
|
||||||
|
}, c.DefaultQuery("command", ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Terminal
|
||||||
|
// @Summary Ws container terminal
|
||||||
|
// @Param cols query integer false "cols"
|
||||||
|
// @Param rows query integer false "rows"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/terminal/container [get]
|
||||||
|
func (b *BaseApi) WsContainerTerminal(c *gin.Context) {
|
||||||
|
wsConn, cols, rows, ok := prepareTerminalSession(c)
|
||||||
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer wsConn.Close()
|
defer wsConn.Close()
|
||||||
|
identity, ok := loadTerminalIdentity(c)
|
||||||
|
if !ok {
|
||||||
|
_ = wshandleError(wsConn, errors.New("missing terminal identity"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := terminal.SessionOptions{
|
||||||
|
Identity: identity,
|
||||||
|
Kind: "container",
|
||||||
|
Target: containerTerminalTarget(c),
|
||||||
|
Cols: cols,
|
||||||
|
Rows: rows,
|
||||||
|
}
|
||||||
|
if err := terminal.ServeCommand(wsConn, strings.TrimSpace(c.Query("session")), opts, func() (*terminal.LocalCommand, error) {
|
||||||
|
return loadContainerTerminalCommand(c)
|
||||||
|
}); err != nil {
|
||||||
|
_ = wshandleError(wsConn, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func containerTerminalTarget(c *gin.Context) string {
|
||||||
|
query := c.Request.URL.Query()
|
||||||
|
for _, key := range []string{"cols", "rows", "session", "terminalRevalidate"} {
|
||||||
|
query.Del(key)
|
||||||
|
}
|
||||||
|
sum := sha256.Sum256([]byte(query.Encode()))
|
||||||
|
return hex.EncodeToString(sum[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareTerminalSession(c *gin.Context) (*websocket.Conn, int, int, bool) {
|
||||||
|
if !websocket.IsWebSocketUpgrade(c.Request) {
|
||||||
|
helper.Success(c)
|
||||||
|
return nil, 0, 0, false
|
||||||
|
}
|
||||||
|
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||||
|
return nil, 0, 0, false
|
||||||
|
}
|
||||||
|
|
||||||
if global.CONF.Base.IsDemo {
|
if global.CONF.Base.IsDemo {
|
||||||
if wshandleError(wsConn, errors.New(" demo server, prohibit this operation!")) {
|
if wshandleError(wsConn, errors.New(" demo server, prohibit this operation!")) {
|
||||||
return
|
return nil, 0, 0, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
|
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
|
||||||
return
|
return nil, 0, 0, false
|
||||||
}
|
}
|
||||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
|
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
|
||||||
|
return nil, 0, 0, false
|
||||||
|
}
|
||||||
|
return wsConn, cols, rows, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) runSSHSession(c *gin.Context, kind string, connect func() (*ssh.SSHClient, error), command string) {
|
||||||
|
wsConn, cols, rows, ok := prepareTerminalSession(c)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer wsConn.Close()
|
||||||
|
identity, ok := loadTerminalIdentity(c)
|
||||||
|
if !ok {
|
||||||
|
_ = wshandleError(wsConn, errors.New("missing terminal identity"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
hostID, _ := strconv.Atoi(c.DefaultQuery("id", "0"))
|
hostID := 0
|
||||||
var client *ssh.SSHClient
|
if kind == "ssh" {
|
||||||
if hostID > 0 {
|
hostID, _ = strconv.Atoi(c.DefaultQuery("id", "0"))
|
||||||
host, err := service.GetHostInfo(uint(hostID))
|
|
||||||
if wshandleError(wsConn, errors.WithMessage(err, "load host info by id failed")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
connInfo := ssh.ConnInfo{
|
|
||||||
Addr: host.Addr,
|
|
||||||
Port: int(host.Port),
|
|
||||||
User: host.User,
|
|
||||||
AuthMode: host.AuthMode,
|
|
||||||
Password: host.Password,
|
|
||||||
PrivateKey: []byte(host.PrivateKey),
|
|
||||||
}
|
|
||||||
if len(host.PassPhrase) != 0 {
|
|
||||||
connInfo.PassPhrase = []byte(host.PassPhrase)
|
|
||||||
}
|
|
||||||
client, err = ssh.NewClient(connInfo)
|
|
||||||
if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
client, err = loadLocalConn()
|
|
||||||
if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
defer client.Close()
|
opts := terminal.SessionOptions{
|
||||||
command := c.DefaultQuery("command", "")
|
Identity: identity,
|
||||||
sws, err := terminal.NewLogicSshWsSession(cols, rows, client.Client, wsConn, command)
|
Kind: kind,
|
||||||
if wshandleError(wsConn, err) {
|
Title: sanitizeTerminalTitle(c.Query("title")),
|
||||||
|
Persistent: c.Query("terminalPersistent") == "true",
|
||||||
|
HostID: uint(max(hostID, 0)),
|
||||||
|
Cols: cols,
|
||||||
|
Rows: rows,
|
||||||
|
InitCmd: command,
|
||||||
|
}
|
||||||
|
err := terminal.Serve(wsConn, strings.TrimSpace(c.Query("session")), opts, func() (*gossh.Client, error) {
|
||||||
|
client, err := connect()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.WithMessage(err, "failed to set up the connection. Please check the host information")
|
||||||
|
}
|
||||||
|
return client.Client, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
_ = wshandleError(wsConn, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Terminal
|
||||||
|
// @Summary List the caller's live terminal sessions
|
||||||
|
// @Success 200 {array} terminal.Info
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/terminal/sessions/search [post]
|
||||||
|
func (b *BaseApi) SearchTerminalSessions(c *gin.Context) {
|
||||||
|
identity, ok := loadTerminalIdentity(c)
|
||||||
|
if !ok {
|
||||||
|
helper.BadRequest(c, errors.New("missing terminal identity"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer sws.Close()
|
helper.SuccessWithData(c, terminal.List(identity))
|
||||||
|
}
|
||||||
|
|
||||||
quitChan := make(chan bool, 3)
|
// @Tags Terminal
|
||||||
sws.Start(quitChan)
|
// @Summary Close a terminal session
|
||||||
go sws.Wait(quitChan)
|
// @Accept json
|
||||||
|
// @Param request body dto.TerminalSessionClose true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/terminal/sessions/close [post]
|
||||||
|
func (b *BaseApi) CloseTerminalSession(c *gin.Context) {
|
||||||
|
var req dto.TerminalSessionClose
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
identity, ok := loadTerminalIdentity(c)
|
||||||
|
if !ok {
|
||||||
|
helper.BadRequest(c, errors.New("missing terminal identity"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := terminal.CloseSession(req.ID, identity); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
<-quitChan
|
// @Tags Terminal
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/terminal/sessions/closeAll [post]
|
||||||
|
func (b *BaseApi) CloseAllTerminalSessions(c *gin.Context) {
|
||||||
|
identity, ok := loadTerminalIdentity(c)
|
||||||
|
if !ok {
|
||||||
|
helper.BadRequest(c, errors.New("missing terminal identity"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
terminal.Revoke("auth_session", identity.UserID, identity.AuthSessionID)
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) RevokeTerminalSessions(c *gin.Context) {
|
||||||
|
var req dto.TerminalSessionRevoke
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (req.Scope == "auth_session" && (req.UserID == "" || req.AuthSessionID == "")) ||
|
||||||
|
(req.Scope == "user" && req.UserID == "") {
|
||||||
|
helper.BadRequest(c, errors.New("missing terminal revocation identity"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
terminal.Revoke(req.Scope, req.UserID, req.AuthSessionID)
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadTerminalIdentity(c *gin.Context) (terminal.Identity, bool) {
|
||||||
|
identity := terminal.Identity{
|
||||||
|
UserID: strings.TrimSpace(c.GetHeader(terminal.HeaderUserID)),
|
||||||
|
AuthSessionID: strings.TrimSpace(c.GetHeader(terminal.HeaderAuthSessionID)),
|
||||||
|
}
|
||||||
|
if value := c.GetHeader(terminal.HeaderAuthLeaseUntil); value != "" {
|
||||||
|
millis, err := strconv.ParseInt(value, 10, 64)
|
||||||
|
if err != nil || millis <= 0 {
|
||||||
|
return terminal.Identity{}, false
|
||||||
|
}
|
||||||
|
identity.AuthLeaseUntil = time.UnixMilli(millis)
|
||||||
|
if maximum := time.Now().Add(90 * time.Second); identity.AuthLeaseUntil.After(maximum) {
|
||||||
|
identity.AuthLeaseUntil = maximum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return identity, identity.Valid()
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanitizeTerminalTitle keeps the title a short single line.
|
||||||
|
func sanitizeTerminalTitle(title string) string {
|
||||||
|
title = strings.Join(strings.Fields(title), " ")
|
||||||
|
if r := []rune(title); len(r) > 64 {
|
||||||
|
title = string(r[:64])
|
||||||
|
}
|
||||||
|
return title
|
||||||
|
}
|
||||||
|
|
||||||
|
func closeTerminalConn(wsConn *websocket.Conn) {
|
||||||
dt := time.Now().Add(time.Second)
|
dt := time.Now().Add(time.Second)
|
||||||
_ = wsConn.WriteControl(websocket.CloseMessage, nil, dt)
|
_ = wsConn.WriteControl(websocket.CloseMessage, nil, dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
|
func newHostSSHClient(host *model.Host, err error) (*ssh.SSHClient, error) {
|
||||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
return nil, errors.WithMessage(err, "load host info by id failed")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
defer wsConn.Close()
|
connInfo := ssh.ConnInfo{
|
||||||
|
Addr: host.Addr,
|
||||||
|
Port: int(host.Port),
|
||||||
|
User: host.User,
|
||||||
|
AuthMode: host.AuthMode,
|
||||||
|
Password: host.Password,
|
||||||
|
PrivateKey: []byte(host.PrivateKey),
|
||||||
|
}
|
||||||
|
if len(host.PassPhrase) != 0 {
|
||||||
|
connInfo.PassPhrase = []byte(host.PassPhrase)
|
||||||
|
}
|
||||||
|
return ssh.NewClient(connInfo)
|
||||||
|
}
|
||||||
|
|
||||||
if global.CONF.Base.IsDemo {
|
func loadContainerTerminalCommand(c *gin.Context) (*terminal.LocalCommand, error) {
|
||||||
if wshandleError(wsConn, errors.New(" demo server, prohibit this operation!")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
|
||||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
|
||||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
source := c.Query("source")
|
source := c.Query("source")
|
||||||
var initCmd []string
|
var (
|
||||||
|
initCmd []string
|
||||||
|
err error
|
||||||
|
)
|
||||||
switch source {
|
switch source {
|
||||||
case "redis", "redis-cluster":
|
case "redis", "redis-cluster":
|
||||||
initCmd, err = loadRedisInitCmd(c, source)
|
initCmd, err = loadRedisInitCmd(c, source)
|
||||||
@@ -122,33 +304,12 @@ func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
|
|||||||
case "database":
|
case "database":
|
||||||
initCmd, err = loadDatabaseInitCmd(c)
|
initCmd, err = loadDatabaseInitCmd(c)
|
||||||
default:
|
default:
|
||||||
if wshandleError(wsConn, fmt.Errorf("not support such source %s", source)) {
|
return nil, fmt.Errorf("not support such source %s", source)
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if wshandleError(wsConn, err) {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
slave, err := terminal.NewCommand("docker", initCmd...)
|
return terminal.NewCommand("docker", initCmd...)
|
||||||
if wshandleError(wsConn, err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer slave.Close()
|
|
||||||
|
|
||||||
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave, false)
|
|
||||||
if wshandleError(wsConn, err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
quitChan := make(chan bool, 3)
|
|
||||||
tty.Start(quitChan)
|
|
||||||
go slave.Wait(quitChan)
|
|
||||||
|
|
||||||
<-quitChan
|
|
||||||
|
|
||||||
global.LOG.Info("websocket finished")
|
|
||||||
dt := time.Now().Add(time.Second)
|
|
||||||
_ = wsConn.WriteControl(websocket.CloseMessage, nil, dt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadRedisInitCmd(c *gin.Context, redisType string) ([]string, error) {
|
func loadRedisInitCmd(c *gin.Context, redisType string) ([]string, error) {
|
||||||
@@ -213,19 +374,29 @@ func loadContainerInitCmd(c *gin.Context) ([]string, error) {
|
|||||||
func loadDatabaseInitCmd(c *gin.Context) ([]string, error) {
|
func loadDatabaseInitCmd(c *gin.Context) ([]string, error) {
|
||||||
database := c.Query("database")
|
database := c.Query("database")
|
||||||
databaseType := c.Query("databaseType")
|
databaseType := c.Query("databaseType")
|
||||||
if len(database) == 0 || len(databaseType) == 0 {
|
if len(databaseType) == 0 {
|
||||||
return nil, fmt.Errorf("error param of database: %s or database type: %s", database, databaseType)
|
return nil, fmt.Errorf("error param of database: %s or database type: %s", database, databaseType)
|
||||||
}
|
}
|
||||||
databaseConn, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Type: databaseType, Name: database})
|
databaseConn, err := appInstallService.LoadConnInfo(dto.OperationWithNameAndType{Type: databaseType, Name: database})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("no such database in db, err: %v", err)
|
return nil, fmt.Errorf("no such database in db, err: %v", err)
|
||||||
}
|
}
|
||||||
|
if len(databaseConn.ContainerName) == 0 {
|
||||||
|
return nil, fmt.Errorf("no such database container for database: %s or database type: %s", database, databaseType)
|
||||||
|
}
|
||||||
commands := []string{"exec", "-it", databaseConn.ContainerName}
|
commands := []string{"exec", "-it", databaseConn.ContainerName}
|
||||||
switch databaseType {
|
switch databaseType {
|
||||||
case "mysql", "mysql-cluster":
|
case "mysql", "mysql-cluster":
|
||||||
commands = append(commands, []string{"mysql", "-uroot", "-p" + databaseConn.Password}...)
|
commands = append(commands, []string{"mysql", "-uroot", "-p" + databaseConn.Password}...)
|
||||||
case "mariadb":
|
case "mariadb":
|
||||||
commands = append(commands, []string{"mariadb", "-uroot", "-p" + databaseConn.Password}...)
|
commands = append(commands, []string{"mariadb", "-uroot", "-p" + databaseConn.Password}...)
|
||||||
|
case "mongodb":
|
||||||
|
commands = append(commands, []string{
|
||||||
|
"mongosh",
|
||||||
|
"--username", databaseConn.Username,
|
||||||
|
"--password", databaseConn.Password,
|
||||||
|
"--authenticationDatabase", "admin",
|
||||||
|
}...)
|
||||||
case "postgresql", "postgresql-cluster":
|
case "postgresql", "postgresql-cluster":
|
||||||
commands = []string{"exec", "-e", fmt.Sprintf("PGPASSWORD=%s", databaseConn.Password), "-it", databaseConn.ContainerName, "psql", "-t", "-U", databaseConn.Username}
|
commands = []string{"exec", "-e", fmt.Sprintf("PGPASSWORD=%s", databaseConn.Password), "-it", databaseConn.ContainerName, "psql", "-t", "-U", databaseConn.Username}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *BaseApi) TerminalCapabilities(c *gin.Context) {
|
||||||
|
helper.SuccessWithData(c, gin.H{"apiKeyLeaseVersion": 1})
|
||||||
|
}
|
||||||
@@ -181,6 +181,7 @@ func (b *BaseApi) GetWebsite(c *gin.Context) {
|
|||||||
// @Success 200 {object} response.FileInfo
|
// @Success 200 {object} response.FileInfo
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
// @Param type path string true "type"
|
||||||
// @Router /websites/:id/config/:type [get]
|
// @Router /websites/:id/config/:type [get]
|
||||||
func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
|
func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
|
||||||
id, err := helper.GetParamID(c)
|
id, err := helper.GetParamID(c)
|
||||||
@@ -269,6 +270,7 @@ func (b *BaseApi) GetHTTPSConfig(c *gin.Context) {
|
|||||||
// @Success 200 {object} response.WebsiteHTTPS
|
// @Success 200 {object} response.WebsiteHTTPS
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
// @Param id path string true "id"
|
||||||
// @Router /websites/:id/https [post]
|
// @Router /websites/:id/https [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] https 配置","formatEN":"Update website https [domain] conf"}
|
// @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] https 配置","formatEN":"Update website https [domain] conf"}
|
||||||
func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) {
|
func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) {
|
||||||
@@ -330,25 +332,45 @@ func (b *BaseApi) UpdateWebsiteNginxConfig(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Website
|
// @Tags Website
|
||||||
// @Summary Operate website log
|
// @Summary Get website log
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body request.WebsiteLogReq true "request"
|
// @Param request body request.WebsiteLogSearchReq true "request"
|
||||||
// @Success 200 {object} response.WebsiteLog
|
// @Success 200 {object} response.WebsiteLog
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /websites/log [post]
|
// @Router /websites/log/search [post]
|
||||||
|
func (b *BaseApi) GetWebsiteLog(c *gin.Context) {
|
||||||
|
var req request.WebsiteLogSearchReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := websiteService.GetWebsiteLog(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Operate website log
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteLogReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/log/operate [post]
|
||||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain][operate] 日志","formatEN":"[domain][operate] logs"}
|
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain][operate] 日志","formatEN":"[domain][operate] logs"}
|
||||||
func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
|
func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
|
||||||
var req request.WebsiteLogReq
|
var req request.WebsiteLogReq
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res, err := websiteService.OpWebsiteLog(req)
|
if err := websiteService.OpWebsiteLog(req); err != nil {
|
||||||
if err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
helper.SuccessWithData(c, res)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Website
|
// @Tags Website
|
||||||
@@ -799,6 +821,7 @@ func (b *BaseApi) GetDirConfig(c *gin.Context) {
|
|||||||
// @Success 200 {object} response.WebsiteHtmlRes
|
// @Success 200 {object} response.WebsiteHtmlRes
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
|
// @Param type path string true "type"
|
||||||
// @Router /websites/default/html/:type [get]
|
// @Router /websites/default/html/:type [get]
|
||||||
func (b *BaseApi) GetDefaultHtml(c *gin.Context) {
|
func (b *BaseApi) GetDefaultHtml(c *gin.Context) {
|
||||||
resourceType, err := helper.GetStrParamByKey(c, "type")
|
resourceType, err := helper.GetStrParamByKey(c, "type")
|
||||||
@@ -838,11 +861,11 @@ func (b *BaseApi) UpdateDefaultHtml(c *gin.Context) {
|
|||||||
// @Tags Website
|
// @Tags Website
|
||||||
// @Summary Get website upstreams
|
// @Summary Get website upstreams
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body request.WebsiteCommonReq true "request"
|
// @Param id path integer true "id"
|
||||||
// @Success 200 {array} dto.NginxUpstream
|
// @Success 200 {array} dto.NginxUpstream
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /websites/lbs [get]
|
// @Router /websites/{id}/lbs [get]
|
||||||
func (b *BaseApi) GetLoadBalances(c *gin.Context) {
|
func (b *BaseApi) GetLoadBalances(c *gin.Context) {
|
||||||
id, err := helper.GetParamID(c)
|
id, err := helper.GetParamID(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -937,6 +960,15 @@ func (b *BaseApi) UpdateLoadBalanceFile(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Change website group
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.UpdateGroup true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/group/change [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["group","newGroup"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"网站分组 [group] 迁移到 [newGroup]","formatEN":"change website group [group] to [newGroup]"}
|
||||||
func (b *BaseApi) ChangeWebsiteGroup(c *gin.Context) {
|
func (b *BaseApi) ChangeWebsiteGroup(c *gin.Context) {
|
||||||
var req dto.UpdateGroup
|
var req dto.UpdateGroup
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -969,6 +1001,7 @@ func (b *BaseApi) UpdateProxyCache(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
// @Summary Get website proxy cache config
|
// @Summary Get website proxy cache config
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param id path int true "id"
|
// @Param id path int true "id"
|
||||||
@@ -1295,7 +1328,7 @@ func (b *BaseApi) UpdateStreamConfig(c *gin.Context) {
|
|||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /websites/batch/https [post]
|
// @Router /websites/batch/ssl [post]
|
||||||
func (b *BaseApi) BatchSetHttps(c *gin.Context) {
|
func (b *BaseApi) BatchSetHttps(c *gin.Context) {
|
||||||
var req request.BatchWebsiteHttps
|
var req request.BatchWebsiteHttps
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
@@ -210,6 +210,27 @@ func (b *BaseApi) UpdateWebsiteSSL(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website SSL
|
||||||
|
// @Summary Push ssl to nodes
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteSSLPush true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/ssl/push [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"推送证书到节点 [domain]","formatEN":"Push ssl to nodes [domain]"}
|
||||||
|
func (b *BaseApi) PushWebsiteSSLToNode(c *gin.Context) {
|
||||||
|
var req request.WebsiteSSLPush
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteSSLService.PushToNode(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Website SSL
|
// @Tags Website SSL
|
||||||
// @Summary Upload ssl
|
// @Summary Upload ssl
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -248,6 +269,8 @@ func (b *BaseApi) UploadSSLFile(c *gin.Context) {
|
|||||||
var req request.WebsiteSSLFileUpload
|
var req request.WebsiteSSLFileUpload
|
||||||
|
|
||||||
req.Description = c.PostForm("description")
|
req.Description = c.PostForm("description")
|
||||||
|
req.Nodes = c.PostForm("nodes")
|
||||||
|
req.PushNode, _ = strconv.ParseBool(c.PostForm("pushNode"))
|
||||||
sslID := c.PostForm("sslID")
|
sslID := c.PostForm("sslID")
|
||||||
if sslID != "" {
|
if sslID != "" {
|
||||||
req.SSLID, _ = strconv.ParseUint(sslID, 10, 64)
|
req.SSLID, _ = strconv.ParseUint(sslID, 10, 64)
|
||||||
@@ -283,6 +306,8 @@ func (b *BaseApi) UploadSSLFile(c *gin.Context) {
|
|||||||
Certificate: string(certificateContent),
|
Certificate: string(certificateContent),
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
SSLID: uint(req.SSLID),
|
SSLID: uint(req.SSLID),
|
||||||
|
PushNode: req.PushNode,
|
||||||
|
Nodes: req.Nodes,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := websiteSSLService.Upload(uploadReq); err != nil {
|
if err := websiteSSLService.Upload(uploadReq); err != nil {
|
||||||
@@ -333,6 +358,15 @@ func (b *BaseApi) DownloadWebsiteSSL(c *gin.Context) {
|
|||||||
http.ServeContent(c.Writer, c.Request, info.Name(), info.ModTime(), file)
|
http.ServeContent(c.Writer, c.Request, info.Name(), info.ModTime(), file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website SSL
|
||||||
|
// @Summary Import master SSL
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body model.WebsiteSSL true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/ssl/import [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["primaryDomain"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"导入主节点证书 [primaryDomain]","formatEN":"import master SSL [primaryDomain]"}
|
||||||
func (b *BaseApi) ImportMasterSSL(c *gin.Context) {
|
func (b *BaseApi) ImportMasterSSL(c *gin.Context) {
|
||||||
var req model.WebsiteSSL
|
var req model.WebsiteSSL
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
@@ -0,0 +1,259 @@
|
|||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"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/dto/request"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Page website templates
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteTemplateSearch true "request"
|
||||||
|
// @Success 200 {object} dto.PageResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/search [post]
|
||||||
|
func (b *BaseApi) PageWebsiteTemplate(c *gin.Context) {
|
||||||
|
var req request.WebsiteTemplateSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, templates, err := websiteTemplateService.PageTemplate(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{
|
||||||
|
Total: total,
|
||||||
|
Items: templates,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Create website template
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteTemplateCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建网站模板 [name]","formatEN":"Create website template [name]"}
|
||||||
|
func (b *BaseApi) CreateWebsiteTemplate(c *gin.Context) {
|
||||||
|
var req request.WebsiteTemplateCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteTemplateService.CreateTemplate(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Update website template
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteTemplateUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"更新网站模板 [name]","formatEN":"Update website template [name]"}
|
||||||
|
func (b *BaseApi) UpdateWebsiteTemplate(c *gin.Context) {
|
||||||
|
var req request.WebsiteTemplateUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteTemplateService.UpdateTemplate(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Delete website template
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.OperateByID true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_templates","output_column":"name","output_value":"name"}],"formatZH":"删除网站模板 [name]","formatEN":"Delete website template [name]"}
|
||||||
|
func (b *BaseApi) DeleteWebsiteTemplate(c *gin.Context) {
|
||||||
|
var req dto.OperateByID
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteTemplateService.DeleteTemplate(req.ID); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Get website template
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.OperateByID true "request"
|
||||||
|
// @Success 200 {object} response.WebsiteTemplateDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/get [post]
|
||||||
|
func (b *BaseApi) GetWebsiteTemplate(c *gin.Context) {
|
||||||
|
var req dto.OperateByID
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
template, err := websiteTemplateService.GetTemplate(req.ID)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, template)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Upload website template zip
|
||||||
|
// @Accept multipart/form-data
|
||||||
|
// @Param file formData file true "file"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/upload [post]
|
||||||
|
func (b *BaseApi) UploadTemplateZip(c *gin.Context) {
|
||||||
|
fileHeader, err := c.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file, err := fileHeader.Open()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
content, err := io.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filePath, variables, err := websiteTemplateService.SaveUploadZip(fileHeader.Filename, content)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, gin.H{"filePath": filePath, "variables": variables})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Preview website template
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsitePreviewReq true "request"
|
||||||
|
// @Success 200 {object} response.WebsitePreviewDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/preview [post]
|
||||||
|
func (b *BaseApi) PreviewWebsiteTemplate(c *gin.Context) {
|
||||||
|
var req request.WebsitePreviewReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
preview, err := websiteTemplateService.Preview(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, preview)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Page website template outputs
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteTemplateOutputSearch true "request"
|
||||||
|
// @Success 200 {object} dto.PageResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/outputs/search [post]
|
||||||
|
func (b *BaseApi) PageWebsiteTemplateOutput(c *gin.Context) {
|
||||||
|
var req request.WebsiteTemplateOutputSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, outputs, err := websiteTemplateService.PageOutput(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{
|
||||||
|
Total: total,
|
||||||
|
Items: outputs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Create website template output
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteTemplateOutputCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/outputs [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"生成模板产物 [name]","formatEN":"Generate template output [name]"}
|
||||||
|
func (b *BaseApi) CreateWebsiteTemplateOutput(c *gin.Context) {
|
||||||
|
var req request.WebsiteTemplateOutputCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteTemplateService.CreateOutput(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Delete website template output
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.OperateByID true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/outputs/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_template_outputs","output_column":"name","output_value":"name"}],"formatZH":"删除模板产物 [name]","formatEN":"Delete template output [name]"}
|
||||||
|
func (b *BaseApi) DeleteWebsiteTemplateOutput(c *gin.Context) {
|
||||||
|
var req dto.OperateByID
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteTemplateService.DeleteOutput(req.ID); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website Template
|
||||||
|
// @Summary Get website template output
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.OperateByID true "request"
|
||||||
|
// @Success 200 {object} response.WebsiteTemplateOutputDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/templates/outputs/get [post]
|
||||||
|
func (b *BaseApi) GetWebsiteTemplateOutput(c *gin.Context) {
|
||||||
|
var req dto.OperateByID
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
output, err := websiteTemplateService.GetOutput(req.ID)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, output)
|
||||||
|
}
|
||||||
+329
-104
@@ -3,28 +3,110 @@ package dto
|
|||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type AgentCreateReq struct {
|
type AgentCreateReq struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
AppVersion string `json:"appVersion" validate:"required"`
|
AppVersion string `json:"appVersion" validate:"required"`
|
||||||
WebUIPort int `json:"webUIPort" validate:"required"`
|
WebUIPort int `json:"webUIPort" validate:"required,min=1,max=65535"`
|
||||||
BridgePort int `json:"bridgePort"`
|
BridgePort int `json:"bridgePort"`
|
||||||
AllowedOrigins []string `json:"allowedOrigins"`
|
AllowedOrigins []string `json:"allowedOrigins"`
|
||||||
AgentType string `json:"agentType" validate:"required,oneof=openclaw copaw"`
|
AgentType string `json:"agentType" validate:"required,oneof=openclaw copaw hermes-agent"`
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
AccountID uint `json:"accountId"`
|
AccountID uint `json:"accountId"`
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
TaskID string `json:"taskID"`
|
DashboardUsername string `json:"dashboardUsername"`
|
||||||
Advanced bool `json:"advanced"`
|
DashboardPassword string `json:"dashboardPassword"`
|
||||||
ContainerName string `json:"containerName"`
|
TaskID string `json:"taskID"`
|
||||||
AllowPort bool `json:"allowPort"`
|
Advanced bool `json:"advanced"`
|
||||||
SpecifyIP string `json:"specifyIP"`
|
ContainerName string `json:"containerName"`
|
||||||
RestartPolicy string `json:"restartPolicy"`
|
AllowPort bool `json:"allowPort"`
|
||||||
CpuQuota float64 `json:"cpuQuota"`
|
SpecifyIP string `json:"specifyIP"`
|
||||||
MemoryLimit float64 `json:"memoryLimit"`
|
RestartPolicy string `json:"restartPolicy"`
|
||||||
MemoryUnit string `json:"memoryUnit"`
|
CpuQuota float64 `json:"cpuQuota"`
|
||||||
PullImage bool `json:"pullImage"`
|
MemoryLimit float64 `json:"memoryLimit"`
|
||||||
EditCompose bool `json:"editCompose"`
|
MemoryUnit string `json:"memoryUnit"`
|
||||||
DockerCompose string `json:"dockerCompose"`
|
PullImage bool `json:"pullImage"`
|
||||||
|
EditCompose bool `json:"editCompose"`
|
||||||
|
DockerCompose string `json:"dockerCompose"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentBatchInstallReq struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
AppVersion string `json:"appVersion" validate:"required"`
|
||||||
|
WebUIPort int `json:"webUIPort" validate:"required,min=1,max=65535"`
|
||||||
|
BridgePort int `json:"bridgePort"`
|
||||||
|
AllowedOrigins []string `json:"allowedOrigins"`
|
||||||
|
AgentType string `json:"agentType" validate:"required,oneof=openclaw copaw hermes-agent"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
AccountID uint `json:"accountId"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
DashboardUsername string `json:"dashboardUsername"`
|
||||||
|
DashboardPassword string `json:"dashboardPassword"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
Advanced bool `json:"advanced"`
|
||||||
|
ContainerName string `json:"containerName"`
|
||||||
|
AllowPort bool `json:"allowPort"`
|
||||||
|
SpecifyIP string `json:"specifyIP"`
|
||||||
|
RestartPolicy string `json:"restartPolicy"`
|
||||||
|
CpuQuota float64 `json:"cpuQuota"`
|
||||||
|
MemoryLimit float64 `json:"memoryLimit"`
|
||||||
|
MemoryUnit string `json:"memoryUnit"`
|
||||||
|
PullImage bool `json:"pullImage"`
|
||||||
|
EditCompose bool `json:"editCompose"`
|
||||||
|
DockerCompose string `json:"dockerCompose"`
|
||||||
|
MasterAccountID uint `json:"masterAccountId"`
|
||||||
|
FallbackAccessHost string `json:"fallbackAccessHost"`
|
||||||
|
AccountSnapshot AgentAccountInfo `json:"accountSnapshot"`
|
||||||
|
AccountModels []AgentAccountModel `json:"accountModels"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentBatchUpgradeReq struct {
|
||||||
|
AgentType string `json:"agentType" validate:"required,oneof=openclaw copaw hermes-agent"`
|
||||||
|
TargetVersion string `json:"targetVersion" validate:"required"`
|
||||||
|
Backup bool `json:"backup"`
|
||||||
|
PullImage bool `json:"pullImage"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentBatchUpgradeResult struct {
|
||||||
|
AgentID uint `json:"agentID"`
|
||||||
|
AgentName string `json:"agentName"`
|
||||||
|
AppInstallID uint `json:"appInstallID"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Skipped bool `json:"skipped"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentBatchSkillInstallReq struct {
|
||||||
|
AgentType string `json:"agentType" validate:"required,oneof=openclaw hermes-agent"`
|
||||||
|
SkillName string `json:"skillName" validate:"required"`
|
||||||
|
PackagePath string `json:"packagePath" validate:"required"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentBatchSkillInstallResult struct {
|
||||||
|
AgentID uint `json:"agentID"`
|
||||||
|
AgentName string `json:"agentName"`
|
||||||
|
AppInstallID uint `json:"appInstallID"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Skipped bool `json:"skipped"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentBatchOperateReq struct {
|
||||||
|
AgentType string `json:"agentType" validate:"required,oneof=openclaw copaw hermes-agent"`
|
||||||
|
Operate string `json:"operate" validate:"required,oneof=start stop restart delete"`
|
||||||
|
ForceDelete bool `json:"forceDelete"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentBatchOperateResult struct {
|
||||||
|
AgentID uint `json:"agentID"`
|
||||||
|
AgentName string `json:"agentName"`
|
||||||
|
AppInstallID uint `json:"appInstallID"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Skipped bool `json:"skipped"`
|
||||||
|
Message string `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentItem struct {
|
type AgentItem struct {
|
||||||
@@ -36,16 +118,17 @@ type AgentItem struct {
|
|||||||
ProviderName string `json:"providerName"`
|
ProviderName string `json:"providerName"`
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
APIType string `json:"apiType"`
|
APIType string `json:"apiType"`
|
||||||
MaxTokens int `json:"maxTokens"`
|
|
||||||
ContextWindow int `json:"contextWindow"`
|
|
||||||
BaseURL string `json:"baseUrl"`
|
BaseURL string `json:"baseUrl"`
|
||||||
APIKey string `json:"apiKey"`
|
APIKey string `json:"apiKey"`
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
|
DashboardUsername string `json:"dashboardUsername"`
|
||||||
|
DashboardPassword string `json:"dashboardPassword"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
AppInstallID uint `json:"appInstallId"`
|
AppInstallID uint `json:"appInstallId"`
|
||||||
WebsiteID uint `json:"websiteId"`
|
WebsiteID uint `json:"websiteId"`
|
||||||
WebsitePrimaryDomain string `json:"websitePrimaryDomain"`
|
WebsitePrimaryDomain string `json:"websitePrimaryDomain"`
|
||||||
|
WebsiteType string `json:"websiteType"`
|
||||||
WebsiteProtocol string `json:"websiteProtocol"`
|
WebsiteProtocol string `json:"websiteProtocol"`
|
||||||
AccountID uint `json:"accountId"`
|
AccountID uint `json:"accountId"`
|
||||||
AppVersion string `json:"appVersion"`
|
AppVersion string `json:"appVersion"`
|
||||||
@@ -79,16 +162,34 @@ type AgentWebsiteBindReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AgentModelConfigUpdateReq struct {
|
type AgentModelConfigUpdateReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
AccountID uint `json:"accountId" validate:"required"`
|
AccountID uint `json:"accountId" validate:"required"`
|
||||||
Model string `json:"model" validate:"required"`
|
Model string `json:"model" validate:"required"`
|
||||||
Fallbacks []string `json:"fallbacks"`
|
Fallbacks []string `json:"fallbacks"`
|
||||||
|
Metadata []AgentModelMetadata `json:"metadata" validate:"dive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentModelConfig struct {
|
type AgentModelConfig struct {
|
||||||
AccountID uint `json:"accountId"`
|
AccountID uint `json:"accountId"`
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
Fallbacks []string `json:"fallbacks"`
|
Fallbacks []string `json:"fallbacks"`
|
||||||
|
Metadata []AgentModelMetadata `json:"metadata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentModelMetadata struct {
|
||||||
|
Model string `json:"model" validate:"required"`
|
||||||
|
InputMode string `json:"inputMode" validate:"required,oneof=auto text image"`
|
||||||
|
ContextWindow int `json:"contextWindow" validate:"min=0"`
|
||||||
|
MaxTokens int `json:"maxTokens" validate:"min=0"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentHermesChatSessionItem struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
MessageCount int64 `json:"messageCount"`
|
||||||
|
StartedAt string `json:"startedAt"`
|
||||||
|
LastActive string `json:"lastActive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentOverviewReq struct {
|
type AgentOverviewReq struct {
|
||||||
@@ -99,6 +200,17 @@ type AgentIDReq struct {
|
|||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentHermesChatSessionRenameReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
ID string `json:"id" validate:"required"`
|
||||||
|
Title string `json:"title" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentHermesChatSessionDeleteReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
ID string `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type AgentOverview struct {
|
type AgentOverview struct {
|
||||||
Snapshot AgentOverviewSnapshot `json:"snapshot"`
|
Snapshot AgentOverviewSnapshot `json:"snapshot"`
|
||||||
}
|
}
|
||||||
@@ -187,19 +299,22 @@ type AgentOverviewSnapshot struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AgentAccountModel struct {
|
type AgentAccountModel struct {
|
||||||
RecordID uint `json:"recordId"`
|
RecordID uint `json:"recordId"`
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ContextWindow int `json:"contextWindow"`
|
|
||||||
MaxTokens int `json:"maxTokens"`
|
|
||||||
Reasoning bool `json:"reasoning"`
|
|
||||||
Input []string `json:"input"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentAccountModelReq struct {
|
type AgentAccountModelReq struct {
|
||||||
AccountID uint `json:"accountId" validate:"required"`
|
AccountID uint `json:"accountId" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentAccountModelDiscoverReq struct {
|
||||||
|
Provider string `json:"provider" validate:"required"`
|
||||||
|
BaseURL string `json:"baseURL" validate:"required"`
|
||||||
|
APIKey string `json:"apiKey" validate:"required"`
|
||||||
|
APIType string `json:"apiType" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type AgentAccountModelCreateReq struct {
|
type AgentAccountModelCreateReq struct {
|
||||||
AccountID uint `json:"accountId" validate:"required"`
|
AccountID uint `json:"accountId" validate:"required"`
|
||||||
Model AgentAccountModel `json:"model" validate:"required"`
|
Model AgentAccountModel `json:"model" validate:"required"`
|
||||||
@@ -216,31 +331,40 @@ type AgentAccountModelDeleteReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AgentAccountCreateReq struct {
|
type AgentAccountCreateReq struct {
|
||||||
Provider string `json:"provider" validate:"required"`
|
Provider string `json:"provider" validate:"required"`
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
APIKey string `json:"apiKey" validate:"required"`
|
APIKey string `json:"apiKey" validate:"required"`
|
||||||
RememberAPIKey bool `json:"rememberApiKey"`
|
RememberAPIKey bool `json:"rememberApiKey"`
|
||||||
BaseURL string `json:"baseURL"`
|
BaseURL string `json:"baseURL"`
|
||||||
Models []AgentAccountModel `json:"models"`
|
Models []AgentAccountModel `json:"models"`
|
||||||
APIType string `json:"apiType" validate:"required"`
|
APIType string `json:"apiType" validate:"required"`
|
||||||
Remark string `json:"remark"`
|
AuthMode string `json:"authMode"`
|
||||||
|
VerifyModel string `json:"verifyModel"`
|
||||||
|
ValidateAvailability *bool `json:"validateAvailability"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentAccountUpdateReq struct {
|
type AgentAccountUpdateReq struct {
|
||||||
ID uint `json:"id" validate:"required"`
|
ID uint `json:"id" validate:"required"`
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
APIKey string `json:"apiKey" validate:"required"`
|
APIKey string `json:"apiKey" validate:"required"`
|
||||||
RememberAPIKey bool `json:"rememberApiKey"`
|
RememberAPIKey bool `json:"rememberApiKey"`
|
||||||
BaseURL string `json:"baseURL"`
|
BaseURL string `json:"baseURL"`
|
||||||
APIType string `json:"apiType" validate:"required"`
|
APIType string `json:"apiType" validate:"required"`
|
||||||
Remark string `json:"remark"`
|
AuthMode string `json:"authMode"`
|
||||||
SyncAgents bool `json:"syncAgents"`
|
VerifyModel string `json:"verifyModel"`
|
||||||
|
ValidateAvailability *bool `json:"validateAvailability"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
SyncAgents bool `json:"syncAgents"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentAccountVerifyReq struct {
|
type AgentAccountVerifyReq struct {
|
||||||
Provider string `json:"provider" validate:"required"`
|
Provider string `json:"provider" validate:"required"`
|
||||||
APIKey string `json:"apiKey" validate:"required"`
|
APIKey string `json:"apiKey" validate:"required"`
|
||||||
BaseURL string `json:"baseURL"`
|
BaseURL string `json:"baseURL"`
|
||||||
|
APIType string `json:"apiType" validate:"required"`
|
||||||
|
AuthMode string `json:"authMode"`
|
||||||
|
Model string `json:"model"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentAccountDeleteReq struct {
|
type AgentAccountDeleteReq struct {
|
||||||
@@ -250,39 +374,56 @@ type AgentAccountDeleteReq struct {
|
|||||||
type AgentAccountSearch struct {
|
type AgentAccountSearch struct {
|
||||||
PageInfo
|
PageInfo
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
|
APIType string `json:"apiType"`
|
||||||
|
TextOnly bool `json:"textOnly"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentAccountProviderCountReq struct {
|
||||||
|
Providers []string `json:"providers"`
|
||||||
|
}
|
||||||
|
|
||||||
type AgentAccountInfo struct {
|
type AgentAccountInfo struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Provider string `json:"provider"`
|
MasterAccountID uint `json:"masterAccountId"`
|
||||||
ProviderName string `json:"providerName"`
|
Provider string `json:"provider"`
|
||||||
Name string `json:"name"`
|
ProviderName string `json:"providerName"`
|
||||||
APIKey string `json:"apiKey"`
|
Name string `json:"name"`
|
||||||
RememberAPIKey bool `json:"rememberApiKey"`
|
APIKey string `json:"apiKey"`
|
||||||
BaseURL string `json:"baseUrl"`
|
RememberAPIKey bool `json:"rememberApiKey"`
|
||||||
Models []AgentAccountModel `json:"models"`
|
BaseURL string `json:"baseUrl"`
|
||||||
APIType string `json:"apiType"`
|
Models []AgentAccountModel `json:"models"`
|
||||||
Verified bool `json:"verified"`
|
APIType string `json:"apiType"`
|
||||||
Remark string `json:"remark"`
|
AuthMode string `json:"authMode"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
VerifyModel string `json:"verifyModel"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProviderModelInfo struct {
|
type ProviderModelInfo struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ContextWindow int `json:"contextWindow"`
|
}
|
||||||
MaxTokens int `json:"maxTokens"`
|
|
||||||
Reasoning bool `json:"reasoning"`
|
type ProviderAPIInfo struct {
|
||||||
Input []string `json:"input"`
|
APIType string `json:"apiType"`
|
||||||
|
BaseURL string `json:"baseUrl"`
|
||||||
|
EditableBaseURL bool `json:"editableBaseUrl"`
|
||||||
|
SupportsModelDiscovery bool `json:"supportsModelDiscovery"`
|
||||||
|
DefaultAuthMode string `json:"defaultAuthMode"`
|
||||||
|
AuthModes []string `json:"authModes"`
|
||||||
|
Models []ProviderModelInfo `json:"models"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProviderInfo struct {
|
type ProviderInfo struct {
|
||||||
Sort uint `json:"-"`
|
Sort uint `json:"-"`
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
BaseURL string `json:"baseUrl"`
|
BaseURL string `json:"baseUrl"`
|
||||||
Models []ProviderModelInfo `json:"models"`
|
DefaultAPIType string `json:"defaultApiType"`
|
||||||
|
APITypes []ProviderAPIInfo `json:"apiTypes"`
|
||||||
|
Models []ProviderModelInfo `json:"models"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentFeishuConfigReq struct {
|
type AgentFeishuConfigReq struct {
|
||||||
@@ -298,14 +439,11 @@ type AgentFeishuConfigUpdateReq struct {
|
|||||||
RequireMention string `json:"requireMention" validate:"required,oneof=true false open"`
|
RequireMention string `json:"requireMention" validate:"required,oneof=true false open"`
|
||||||
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
GroupAllowFrom []string `json:"groupAllowFrom"`
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
ConnectionMode string `json:"connectionMode"`
|
||||||
Bots []AgentFeishuBot `json:"bots" validate:"required,min=1"`
|
Bots []AgentFeishuBot `json:"bots" validate:"required,min=1"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentFeishuPairingApproveReq struct {
|
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
|
||||||
PairingCode string `json:"pairingCode" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AgentFeishuConfig struct {
|
type AgentFeishuConfig struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
ThreadSession bool `json:"threadSession"`
|
ThreadSession bool `json:"threadSession"`
|
||||||
@@ -314,6 +452,8 @@ type AgentFeishuConfig struct {
|
|||||||
RequireMention string `json:"requireMention"`
|
RequireMention string `json:"requireMention"`
|
||||||
GroupPolicy string `json:"groupPolicy"`
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
GroupAllowFrom []string `json:"groupAllowFrom"`
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
ConnectionMode string `json:"connectionMode"`
|
||||||
Bots []AgentFeishuBot `json:"bots"`
|
Bots []AgentFeishuBot `json:"bots"`
|
||||||
Installed bool `json:"installed"`
|
Installed bool `json:"installed"`
|
||||||
}
|
}
|
||||||
@@ -327,6 +467,7 @@ type AgentTelegramConfigUpdateReq struct {
|
|||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
DmPolicy string `json:"dmPolicy" validate:"required,oneof=pairing open allowlist disabled"`
|
DmPolicy string `json:"dmPolicy" validate:"required,oneof=pairing open allowlist disabled"`
|
||||||
AllowFrom []string `json:"allowFrom"`
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
RequireMention bool `json:"requireMention"`
|
||||||
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
GroupAllowFrom []string `json:"groupAllowFrom"`
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
Proxy string `json:"proxy"`
|
Proxy string `json:"proxy"`
|
||||||
@@ -339,6 +480,7 @@ type AgentTelegramConfig struct {
|
|||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
DmPolicy string `json:"dmPolicy"`
|
DmPolicy string `json:"dmPolicy"`
|
||||||
AllowFrom []string `json:"allowFrom"`
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
RequireMention bool `json:"requireMention"`
|
||||||
GroupPolicy string `json:"groupPolicy"`
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
GroupAllowFrom []string `json:"groupAllowFrom"`
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
Proxy string `json:"proxy"`
|
Proxy string `json:"proxy"`
|
||||||
@@ -349,11 +491,16 @@ type AgentTelegramConfig struct {
|
|||||||
|
|
||||||
type AgentChannelPairingApproveReq struct {
|
type AgentChannelPairingApproveReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
Type string `json:"type" validate:"required,oneof=feishu telegram discord wecom"`
|
Type string `json:"type" validate:"required,oneof=feishu telegram discord wecom qqbot dingtalk"`
|
||||||
PairingCode string `json:"pairingCode" validate:"required"`
|
PairingCode string `json:"pairingCode" validate:"required"`
|
||||||
AccountID string `json:"accountId"`
|
AccountID string `json:"accountId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentChannelDeleteReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=feishu telegram discord wecom qqbot dingtalk weixin"`
|
||||||
|
}
|
||||||
|
|
||||||
type AgentWecomConfigUpdateReq struct {
|
type AgentWecomConfigUpdateReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
@@ -379,7 +526,7 @@ type AgentWecomConfig struct {
|
|||||||
type AgentDingTalkConfigUpdateReq struct {
|
type AgentDingTalkConfigUpdateReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
DmPolicy string `json:"dmPolicy" validate:"required,oneof=allowlist open disabled"`
|
DmPolicy string `json:"dmPolicy" validate:"required,oneof=pairing allowlist open disabled"`
|
||||||
AllowFrom []string `json:"allowFrom"`
|
AllowFrom []string `json:"allowFrom"`
|
||||||
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
GroupAllowFrom []string `json:"groupAllowFrom"`
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
@@ -411,16 +558,28 @@ type AgentWeixinLoginReq struct {
|
|||||||
TaskID string `json:"taskID" validate:"required"`
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentWeixinConfig struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
type AgentQQBotConfigUpdateReq struct {
|
type AgentQQBotConfigUpdateReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
Bots []AgentQQBotBot `json:"bots" validate:"required,min=1"`
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Bots []AgentQQBotBot `json:"bots" validate:"required,min=1"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentQQBotConfig struct {
|
type AgentQQBotConfig struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
Bots []AgentQQBotBot `json:"bots"`
|
DmPolicy string `json:"dmPolicy"`
|
||||||
Installed bool `json:"installed"`
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Bots []AgentQQBotBot `json:"bots"`
|
||||||
|
Installed bool `json:"installed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentPluginInstallReq struct {
|
type AgentPluginInstallReq struct {
|
||||||
@@ -454,10 +613,58 @@ type AgentPluginStatus struct {
|
|||||||
Upgradable bool `json:"upgradable"`
|
Upgradable bool `json:"upgradable"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentPluginsReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginSearchReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Keyword string `json:"keyword" validate:"required,max=100"`
|
||||||
|
Limit int `json:"limit" validate:"omitempty,min=1,max=100"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginMarketInstallReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Package string `json:"package" validate:"required,max=200"`
|
||||||
|
Version string `json:"version" validate:"required,max=100"`
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginOperateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
PluginID string `json:"pluginId" validate:"required,max=200"`
|
||||||
|
Operate string `json:"operate" validate:"required,oneof=enable disable update uninstall"`
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginItem struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Origin string `json:"origin"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginSearchItem struct {
|
||||||
|
Package string `json:"package"`
|
||||||
|
PluginID string `json:"pluginId"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Channel string `json:"channel"`
|
||||||
|
VerificationTier string `json:"verificationTier"`
|
||||||
|
Categories []string `json:"categories"`
|
||||||
|
Official bool `json:"official"`
|
||||||
|
Downloads int64 `json:"downloads"`
|
||||||
|
Score float64 `json:"score"`
|
||||||
|
}
|
||||||
|
|
||||||
type AgentDiscordConfigUpdateReq struct {
|
type AgentDiscordConfigUpdateReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
DmPolicy string `json:"dmPolicy" validate:"required"`
|
DmPolicy string `json:"dmPolicy" validate:"required"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
RequireMention bool `json:"requireMention"`
|
||||||
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
Proxy string `json:"proxy"`
|
Proxy string `json:"proxy"`
|
||||||
DefaultAccount string `json:"defaultAccount" validate:"required"`
|
DefaultAccount string `json:"defaultAccount" validate:"required"`
|
||||||
@@ -467,6 +674,8 @@ type AgentDiscordConfigUpdateReq struct {
|
|||||||
type AgentDiscordConfig struct {
|
type AgentDiscordConfig struct {
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
DmPolicy string `json:"dmPolicy"`
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
RequireMention bool `json:"requireMention"`
|
||||||
GroupPolicy string `json:"groupPolicy"`
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
Proxy string `json:"proxy"`
|
Proxy string `json:"proxy"`
|
||||||
DefaultAccount string `json:"defaultAccount"`
|
DefaultAccount string `json:"defaultAccount"`
|
||||||
@@ -529,16 +738,20 @@ type AgentSecurityConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AgentOtherConfigUpdateReq struct {
|
type AgentOtherConfigUpdateReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
UserTimezone string `json:"userTimezone" validate:"required"`
|
UserTimezone string `json:"userTimezone"`
|
||||||
BrowserEnabled bool `json:"browserEnabled"`
|
BrowserEnabled bool `json:"browserEnabled"`
|
||||||
NPMRegistry string `json:"npmRegistry" validate:"required"`
|
NPMRegistry string `json:"npmRegistry"`
|
||||||
|
DashboardUsername string `json:"dashboardUsername"`
|
||||||
|
DashboardPassword string `json:"dashboardPassword"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentOtherConfig struct {
|
type AgentOtherConfig struct {
|
||||||
UserTimezone string `json:"userTimezone"`
|
UserTimezone string `json:"userTimezone"`
|
||||||
BrowserEnabled bool `json:"browserEnabled"`
|
BrowserEnabled bool `json:"browserEnabled"`
|
||||||
NPMRegistry string `json:"npmRegistry"`
|
NPMRegistry string `json:"npmRegistry"`
|
||||||
|
DashboardUsername string `json:"dashboardUsername"`
|
||||||
|
DashboardPassword string `json:"dashboardPassword"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentConfigFileReq struct {
|
type AgentConfigFileReq struct {
|
||||||
@@ -556,25 +769,32 @@ type AgentConfigFile struct {
|
|||||||
|
|
||||||
type AgentSkillSearchReq struct {
|
type AgentSkillSearchReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
Source string `json:"source" validate:"required,oneof=clawhub-global clawhub-cn skillhub"`
|
Source string `json:"source" validate:"required,oneof=clawhub-global clawhub-cn skillhub official skills-sh local-hub"`
|
||||||
Keyword string `json:"keyword" validate:"required"`
|
Keyword string `json:"keyword" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentSkillItem struct {
|
type AgentSkillItem struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Source string `json:"source"`
|
Category string `json:"category"`
|
||||||
Bundled bool `json:"bundled"`
|
Tags []string `json:"tags"`
|
||||||
Disabled bool `json:"disabled"`
|
Source string `json:"source"`
|
||||||
|
Trust string `json:"trust"`
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
|
Bundled bool `json:"bundled"`
|
||||||
|
Disabled bool `json:"disabled"`
|
||||||
|
Uninstallable bool `json:"uninstallable"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AgentSkillSearchItem struct {
|
type AgentSkillSearchItem struct {
|
||||||
Slug string `json:"slug"`
|
Slug string `json:"slug"`
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Summary string `json:"summary"`
|
Summary string `json:"summary"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
|
Trust string `json:"trust"`
|
||||||
Score string `json:"score"`
|
Score string `json:"score"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +806,12 @@ type AgentSkillUpdateReq struct {
|
|||||||
|
|
||||||
type AgentSkillInstallReq struct {
|
type AgentSkillInstallReq struct {
|
||||||
AgentID uint `json:"agentId" validate:"required"`
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
Source string `json:"source" validate:"required,oneof=clawhub-global clawhub-cn skillhub"`
|
Source string `json:"source" validate:"required,oneof=clawhub-global clawhub-cn skillhub official skills-sh local-hub"`
|
||||||
Slug string `json:"slug" validate:"required"`
|
Slug string `json:"slug" validate:"required"`
|
||||||
TaskID string `json:"taskID" validate:"required"`
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentSkillUninstallReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
}
|
||||||
|
|||||||
+48
-18
@@ -2,8 +2,9 @@ package dto
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateOrUpdateAlert struct {
|
type CreateOrUpdateAlert struct {
|
||||||
@@ -20,6 +21,7 @@ type AlertBase struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PushAlert struct {
|
type PushAlert struct {
|
||||||
|
Result string `json:"result,omitempty"`
|
||||||
TaskName string `json:"taskName"`
|
TaskName string `json:"taskName"`
|
||||||
AlertType string `json:"alertType"`
|
AlertType string `json:"alertType"`
|
||||||
EntryID uint `json:"entryID"`
|
EntryID uint `json:"entryID"`
|
||||||
@@ -35,6 +37,15 @@ type AlertSearch struct {
|
|||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AlertConfigQuery struct {
|
||||||
|
ExcludeTypes []string `json:"excludeTypes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertConfigPageReq struct {
|
||||||
|
PageInfo
|
||||||
|
ExcludeTypes []string `json:"excludeTypes"`
|
||||||
|
}
|
||||||
|
|
||||||
type AlertDTO struct {
|
type AlertDTO struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
@@ -43,9 +54,12 @@ type AlertDTO struct {
|
|||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Project string `json:"project"`
|
Project string `json:"project"`
|
||||||
|
TaskName string `json:"taskName,omitempty"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
SendCount uint `json:"sendCount"`
|
SendCount uint `json:"sendCount"`
|
||||||
AdvancedParams string `json:"advancedParams"`
|
AdvancedParams string `json:"advancedParams"`
|
||||||
|
CreateUser string `json:"createUser"`
|
||||||
|
UpdateUser string `json:"updateUser"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
UpdatedAt time.Time `json:"updatedAt"`
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
}
|
}
|
||||||
@@ -101,8 +115,10 @@ type DiskDTO struct {
|
|||||||
|
|
||||||
type AlertLogSearch struct {
|
type AlertLogSearch struct {
|
||||||
PageInfo
|
PageInfo
|
||||||
Count uint `json:"count"`
|
Count uint `json:"count"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
|
StartTime time.Time `json:"startTime"`
|
||||||
|
EndTime time.Time `json:"endTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertLogDTO struct {
|
type AlertLogDTO struct {
|
||||||
@@ -137,16 +153,25 @@ type AlertLog struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AlertDetail struct {
|
type AlertDetail struct {
|
||||||
LicenseId string `json:"licenseId"`
|
LicenseId string `json:"licenseId"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
SubType string `json:"subType"`
|
SubType string `json:"subType"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
LicenseCode string `json:"licenseCode"`
|
LicenseCode string `json:"licenseCode"`
|
||||||
DeviceId string `json:"deviceId"`
|
DeviceId string `json:"deviceId"`
|
||||||
Project string `json:"project"`
|
Project string `json:"project"`
|
||||||
Params []Param `json:"params"`
|
Params []Param `json:"params"`
|
||||||
Phone string `json:"phone"`
|
Phone string `json:"phone"`
|
||||||
|
Task *AlertTaskMetadata `json:"task,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertTaskMetadata struct {
|
||||||
|
AlertID uint `json:"alertId"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Quota string `json:"quota"`
|
||||||
|
QuotaType string `json:"quotaType"`
|
||||||
|
Method string `json:"method"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertRule struct {
|
type AlertRule struct {
|
||||||
@@ -281,14 +306,19 @@ type OfflineQueryRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AlertConfigUpdate struct {
|
type AlertConfigUpdate struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Config string `json:"config"`
|
Config string `json:"config"`
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
Revision *time.Time `json:"revision"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertConfigTest struct {
|
type AlertConfigTest struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Config string `json:"config"`
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
Port int `json:"port"`
|
Port int `json:"port"`
|
||||||
Sender string `json:"sender"`
|
Sender string `json:"sender"`
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
const AlertCustomWebhookSchemaVersion = 1
|
||||||
|
|
||||||
|
type AlertConfigStatusUpdate struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Status string `json:"status" validate:"required,oneof=Enable Disable"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookSecretMutation struct {
|
||||||
|
Action string `json:"action,omitempty"`
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookURL struct {
|
||||||
|
AlertCustomWebhookSecretMutation
|
||||||
|
Configured bool `json:"configured"`
|
||||||
|
Masked string `json:"masked,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookBody struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Template string `json:"template,omitempty"`
|
||||||
|
Fields []AlertCustomWebhookFormField `json:"fields,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookFormField struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookHeader struct {
|
||||||
|
UID string `json:"uid"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Secret bool `json:"secret"`
|
||||||
|
Action string `json:"action,omitempty"`
|
||||||
|
Value string `json:"value,omitempty"`
|
||||||
|
Configured bool `json:"configured,omitempty"`
|
||||||
|
Masked string `json:"masked,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookConfig struct {
|
||||||
|
SchemaVersion int `json:"schemaVersion"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
Preset string `json:"preset"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
URL AlertCustomWebhookURL `json:"url"`
|
||||||
|
Body AlertCustomWebhookBody `json:"body"`
|
||||||
|
Headers []AlertCustomWebhookHeader `json:"headers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookSecretConfig struct {
|
||||||
|
SchemaVersion int `json:"schemaVersion"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Headers map[string]string `json:"headers,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookResolvedConfig struct {
|
||||||
|
SchemaVersion int
|
||||||
|
DisplayName string
|
||||||
|
Preset string
|
||||||
|
Method string
|
||||||
|
URL string
|
||||||
|
Body AlertCustomWebhookBody
|
||||||
|
Headers []AlertCustomWebhookResolvedHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertCustomWebhookResolvedHeader struct {
|
||||||
|
Key string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertConfigTestResult struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
StatusCode int `json:"statusCode,omitempty"`
|
||||||
|
Duration int64 `json:"duration,omitempty"` // milliseconds
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
Response string `json:"response,omitempty"`
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package dto
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/task"
|
"github.com/1Panel-dev/1Panel/agent/app/task"
|
||||||
)
|
)
|
||||||
@@ -132,6 +133,8 @@ type Locale struct {
|
|||||||
Ko string `json:"ko"`
|
Ko string `json:"ko"`
|
||||||
Tr string `json:"tr"`
|
Tr string `json:"tr"`
|
||||||
Es string `json:"es-es" yaml:"es-es"`
|
Es string `json:"es-es" yaml:"es-es"`
|
||||||
|
Fa string `json:"fa"`
|
||||||
|
Lo string `json:"lo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppForm struct {
|
type AppForm struct {
|
||||||
|
|||||||
+19
-17
@@ -65,27 +65,29 @@ type UploadForRecover struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CommonBackup struct {
|
type CommonBackup struct {
|
||||||
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster container compose"`
|
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mongodb mysql-cluster postgresql-cluster redis-cluster container compose"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
DetailName string `json:"detailName"`
|
DetailName string `json:"detailName"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
StopBefore bool `json:"stopBefore"`
|
IsImmediate bool `json:"isImmediate"`
|
||||||
TaskID string `json:"taskID"`
|
StopBefore bool `json:"stopBefore"`
|
||||||
FileName string `json:"fileName"`
|
TaskID string `json:"taskID"`
|
||||||
Args []string `json:"args"`
|
FileName string `json:"fileName"`
|
||||||
|
Args []string `json:"args"`
|
||||||
|
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
type CommonRecover struct {
|
type CommonRecover struct {
|
||||||
DownloadAccountID uint `json:"downloadAccountID" validate:"required"`
|
DownloadAccountID uint `json:"downloadAccountID" validate:"required"`
|
||||||
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mysql-cluster postgresql-cluster redis-cluster container compose"`
|
Type string `json:"type" validate:"required,oneof=app mysql mariadb redis website postgresql mongodb mysql-cluster postgresql-cluster redis-cluster container compose"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
DetailName string `json:"detailName"`
|
DetailName string `json:"detailName"`
|
||||||
File string `json:"file"`
|
File string `json:"file"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
TaskID string `json:"taskID"`
|
DropAllCollections bool `json:"dropAllCollections"`
|
||||||
BackupRecordID uint `json:"backupRecordID"`
|
TaskID string `json:"taskID"`
|
||||||
Timeout int `json:"timeout"`
|
BackupRecordID uint `json:"backupRecordID"`
|
||||||
|
Timeout int `json:"timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecordSearch struct {
|
type RecordSearch struct {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ package dto
|
|||||||
|
|
||||||
type SearchWithPage struct {
|
type SearchWithPage struct {
|
||||||
PageInfo
|
PageInfo
|
||||||
Info string `json:"info"`
|
Info string `json:"info"`
|
||||||
|
ExcludeAppStore bool `json:"excludeAppStore"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SearchPageWithType struct {
|
type SearchPageWithType struct {
|
||||||
|
|||||||
@@ -6,9 +6,10 @@ type PageResult struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
Code int `json:"code"`
|
Code int `json:"code"`
|
||||||
Message string `json:"message"`
|
ErrorCode string `json:"errorCode,omitempty"`
|
||||||
Data interface{} `json:"data"`
|
Message string `json:"message"`
|
||||||
|
Data interface{} `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
|||||||
@@ -134,10 +134,15 @@ type ExtraHost struct {
|
|||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
}
|
}
|
||||||
type ContainerNetwork struct {
|
type ContainerNetwork struct {
|
||||||
Network string `json:"network"`
|
Network string `json:"network"`
|
||||||
Ipv4 string `json:"ipv4"`
|
Ipv4 string `json:"ipv4"`
|
||||||
Ipv6 string `json:"ipv6"`
|
Ipv6 string `json:"ipv6"`
|
||||||
MacAddr string `json:"macAddr"`
|
MacAddr string `json:"macAddr"`
|
||||||
|
Links []string `json:"links"`
|
||||||
|
Aliases []string `json:"aliases"`
|
||||||
|
DriverOpts map[string]string `json:"driverOpts"`
|
||||||
|
GwPriority int `json:"gwPriority"`
|
||||||
|
LinkLocalIPs []string `json:"linkLocalIPs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContainerCreateByCommand struct {
|
type ContainerCreateByCommand struct {
|
||||||
@@ -295,6 +300,7 @@ type ComposeInfo struct {
|
|||||||
ConfigFile string `json:"configFile"`
|
ConfigFile string `json:"configFile"`
|
||||||
Workdir string `json:"workdir"`
|
Workdir string `json:"workdir"`
|
||||||
ComposeFileExists bool `json:"composeFileExists"`
|
ComposeFileExists bool `json:"composeFileExists"`
|
||||||
|
IsPinned bool `json:"isPinned"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Containers []ComposeContainer `json:"containers"`
|
Containers []ComposeContainer `json:"containers"`
|
||||||
Env string `json:"env"`
|
Env string `json:"env"`
|
||||||
@@ -309,6 +315,7 @@ type ComposeContainer struct {
|
|||||||
type ComposeCreate struct {
|
type ComposeCreate struct {
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
DirName string `json:"dirName"`
|
||||||
From string `json:"from" validate:"required,oneof=edit path template"`
|
From string `json:"from" validate:"required,oneof=edit path template"`
|
||||||
File string `json:"file"`
|
File string `json:"file"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
@@ -319,7 +326,7 @@ type ComposeCreate struct {
|
|||||||
type ComposeOperation struct {
|
type ComposeOperation struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Operation string `json:"operation" validate:"required,oneof=up start restart stop down delete"`
|
Operation string `json:"operation" validate:"required,oneof=up start restart stop down delete rebuild"`
|
||||||
WithFile bool `json:"withFile"`
|
WithFile bool `json:"withFile"`
|
||||||
Force bool `json:"force"`
|
Force bool `json:"force"`
|
||||||
}
|
}
|
||||||
@@ -332,6 +339,10 @@ type ComposeUpdate struct {
|
|||||||
Env string `json:"env"`
|
Env string `json:"env"`
|
||||||
ForcePull bool `json:"forcePull"`
|
ForcePull bool `json:"forcePull"`
|
||||||
}
|
}
|
||||||
|
type ComposePin struct {
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
IsPinned bool `json:"isPinned"`
|
||||||
|
}
|
||||||
type ComposeLogClean struct {
|
type ComposeLogClean struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
|
|||||||
@@ -51,9 +51,10 @@ type CronjobOperate struct {
|
|||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
Args string `json:"args"`
|
Args string `json:"args"`
|
||||||
|
|
||||||
AlertCount uint `json:"alertCount"`
|
AlertCount uint `json:"alertCount"`
|
||||||
AlertTitle string `json:"alertTitle"`
|
AlertTitle string `json:"alertTitle"`
|
||||||
AlertMethod string `json:"alertMethod"`
|
AlertMethod string `json:"alertMethod"`
|
||||||
|
AlertTriggerMode string `json:"alertTriggerMode" validate:"omitempty,oneof=failed success both"`
|
||||||
|
|
||||||
CleanLogConfig
|
CleanLogConfig
|
||||||
}
|
}
|
||||||
@@ -126,7 +127,8 @@ type CronjobInfo struct {
|
|||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
Args string `json:"args"`
|
Args string `json:"args"`
|
||||||
|
|
||||||
AlertCount uint `json:"alertCount"`
|
AlertCount uint `json:"alertCount"`
|
||||||
|
AlertTriggerMode string `json:"alertTriggerMode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CronjobImport struct {
|
type CronjobImport struct {
|
||||||
@@ -169,9 +171,10 @@ type CronjobTrans struct {
|
|||||||
SourceAccounts []string `json:"sourceAccounts"`
|
SourceAccounts []string `json:"sourceAccounts"`
|
||||||
DownloadAccount string `json:"downloadAccount"`
|
DownloadAccount string `json:"downloadAccount"`
|
||||||
|
|
||||||
AlertCount uint `json:"alertCount"`
|
AlertCount uint `json:"alertCount"`
|
||||||
AlertTitle string `json:"alertTitle"`
|
AlertTitle string `json:"alertTitle"`
|
||||||
AlertMethod string `json:"alertMethod"`
|
AlertMethod string `json:"alertMethod"`
|
||||||
|
AlertTriggerMode string `json:"alertTriggerMode" validate:"omitempty,oneof=failed success both"`
|
||||||
}
|
}
|
||||||
type TransHelper struct {
|
type TransHelper struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
@@ -197,6 +200,7 @@ type SearchRecord struct {
|
|||||||
|
|
||||||
type Record struct {
|
type Record struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
|
CronjobID uint `json:"cronjobID"`
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
StartTime string `json:"startTime"`
|
StartTime string `json:"startTime"`
|
||||||
Records string `json:"records"`
|
Records string `json:"records"`
|
||||||
|
|||||||
@@ -79,8 +79,9 @@ type NodeCurrent struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DashboardCurrent struct {
|
type DashboardCurrent struct {
|
||||||
Uptime uint64 `json:"uptime"`
|
Uptime uint64 `json:"uptime"`
|
||||||
TimeSinceUptime string `json:"timeSinceUptime"`
|
TimeSinceUptime string `json:"timeSinceUptime"`
|
||||||
|
RunningTime RunningTime `json:"runningTime"`
|
||||||
|
|
||||||
Procs uint64 `json:"procs"`
|
Procs uint64 `json:"procs"`
|
||||||
|
|
||||||
@@ -120,6 +121,7 @@ type DashboardCurrent struct {
|
|||||||
NetBytesRecv uint64 `json:"netBytesRecv"`
|
NetBytesRecv uint64 `json:"netBytesRecv"`
|
||||||
|
|
||||||
GPUData []GPUInfo `json:"gpuData"`
|
GPUData []GPUInfo `json:"gpuData"`
|
||||||
|
NPUData []NPUInfo `json:"npuData"`
|
||||||
XPUData []XPUInfo `json:"xpuData"`
|
XPUData []XPUInfo `json:"xpuData"`
|
||||||
|
|
||||||
TopCPUItems []Process `json:"topCPUItems"`
|
TopCPUItems []Process `json:"topCPUItems"`
|
||||||
@@ -128,6 +130,13 @@ type DashboardCurrent struct {
|
|||||||
ShotTime time.Time `json:"shotTime"`
|
ShotTime time.Time `json:"shotTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RunningTime struct {
|
||||||
|
Days uint64 `json:"days"`
|
||||||
|
Hours uint64 `json:"hours"`
|
||||||
|
Minutes uint64 `json:"minutes"`
|
||||||
|
Seconds uint64 `json:"seconds"`
|
||||||
|
}
|
||||||
|
|
||||||
type AppLauncherSync struct {
|
type AppLauncherSync struct {
|
||||||
Keys []string `json:"keys"`
|
Keys []string `json:"keys"`
|
||||||
}
|
}
|
||||||
@@ -148,8 +157,12 @@ type DiskInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GPUInfo struct {
|
type GPUInfo struct {
|
||||||
|
Type string `json:"type"`
|
||||||
Index uint `json:"index"`
|
Index uint `json:"index"`
|
||||||
|
NPUIndex uint `json:"npuIndex"`
|
||||||
|
ChipIndex uint `json:"chipIndex"`
|
||||||
ProductName string `json:"productName"`
|
ProductName string `json:"productName"`
|
||||||
|
BusID string `json:"busID"`
|
||||||
GPUUtil string `json:"gpuUtil"`
|
GPUUtil string `json:"gpuUtil"`
|
||||||
Temperature string `json:"temperature"`
|
Temperature string `json:"temperature"`
|
||||||
PerformanceState string `json:"performanceState"`
|
PerformanceState string `json:"performanceState"`
|
||||||
@@ -162,6 +175,27 @@ type GPUInfo struct {
|
|||||||
FanSpeed string `json:"fanSpeed"`
|
FanSpeed string `json:"fanSpeed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NPUInfo struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Index uint `json:"index"`
|
||||||
|
NPUIndex uint `json:"npuIndex"`
|
||||||
|
ChipIndex uint `json:"chipIndex"`
|
||||||
|
ProductName string `json:"productName"`
|
||||||
|
BusID string `json:"busID"`
|
||||||
|
Health string `json:"health"`
|
||||||
|
Temperature string `json:"temperature"`
|
||||||
|
PowerDraw string `json:"powerDraw"`
|
||||||
|
AICore string `json:"aiCore"`
|
||||||
|
MemUsed string `json:"memUsed"`
|
||||||
|
MemTotal string `json:"memTotal"`
|
||||||
|
MemoryUsed string `json:"memoryUsed"`
|
||||||
|
MemoryTotal string `json:"memoryTotal"`
|
||||||
|
HBMUsed string `json:"hbmUsed"`
|
||||||
|
HBMTotal string `json:"hbmTotal"`
|
||||||
|
HugepagesUsed string `json:"hugepagesUsed"`
|
||||||
|
HugepagesTotal string `json:"hugepagesTotal"`
|
||||||
|
}
|
||||||
|
|
||||||
type AppLauncher struct {
|
type AppLauncher struct {
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
@@ -194,11 +228,13 @@ type LauncherOption struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type XPUInfo struct {
|
type XPUInfo struct {
|
||||||
DeviceID int `json:"deviceID"`
|
DeviceID int `json:"deviceID"`
|
||||||
DeviceName string `json:"deviceName"`
|
DeviceName string `json:"deviceName"`
|
||||||
Memory string `json:"memory"`
|
PciBdfAddress string `json:"pciBdfAddress"`
|
||||||
Temperature string `json:"temperature"`
|
Memory string `json:"memory"`
|
||||||
MemoryUsed string `json:"memoryUsed"`
|
Temperature string `json:"temperature"`
|
||||||
Power string `json:"power"`
|
GPUUtil string `json:"gpuUtil"`
|
||||||
MemoryUtil string `json:"memoryUtil"`
|
MemoryUsed string `json:"memoryUsed"`
|
||||||
|
Power string `json:"power"`
|
||||||
|
MemoryUtil string `json:"memoryUtil"`
|
||||||
}
|
}
|
||||||
|
|||||||
+147
-11
@@ -11,7 +11,7 @@ type DBConfUpdateByFile struct {
|
|||||||
type ChangeDBInfo struct {
|
type ChangeDBInfo struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
From string `json:"from" validate:"required,oneof=local remote"`
|
From string `json:"from" validate:"required,oneof=local remote"`
|
||||||
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis mysql-cluster postgresql-cluster redis-cluster"`
|
Type string `json:"type" validate:"required,oneof=mysql mariadb postgresql redis mongodb mysql-cluster postgresql-cluster redis-cluster"`
|
||||||
Database string `json:"database" validate:"required"`
|
Database string `json:"database" validate:"required"`
|
||||||
Value string `json:"value" validate:"required"`
|
Value string `json:"value" validate:"required"`
|
||||||
}
|
}
|
||||||
@@ -60,25 +60,84 @@ type MysqlDBCreate struct {
|
|||||||
Database string `json:"database" validate:"required"`
|
Database string `json:"database" validate:"required"`
|
||||||
Format string `json:"format" validate:"required"`
|
Format string `json:"format" validate:"required"`
|
||||||
Collation string `json:"collation"`
|
Collation string `json:"collation"`
|
||||||
Username string `json:"username" validate:"required"`
|
Username string `json:"username"`
|
||||||
Password string `json:"password" validate:"required"`
|
Password string `json:"password"`
|
||||||
Permission string `json:"permission" validate:"required"`
|
Permission string `json:"permission" validate:"required"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MysqlUser struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
IsDelete bool `json:"isDelete"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlGrant struct {
|
||||||
|
Database string `json:"database"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlGrantSummarySearch struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
DBs []string `json:"dbs" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlUserSearch struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlUserCreate struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
Host string `json:"host" validate:"required"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
DBs []string `json:"dbs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlUserDelete struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Host string `json:"host" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlUserUpdate struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Host string `json:"host" validate:"required"`
|
||||||
|
NewHost string `json:"newHost" validate:"required"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlUserPassword struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Host string `json:"host" validate:"required"`
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlGrantCreate struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
DB string `json:"db" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Host string `json:"host" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MysqlGrantDelete struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
DB string `json:"db" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Host string `json:"host" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type MysqlFormatCollationOption struct {
|
type MysqlFormatCollationOption struct {
|
||||||
Format string `json:"format"`
|
Format string `json:"format"`
|
||||||
Collations []string `json:"collations"`
|
Collations []string `json:"collations"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BindUser struct {
|
|
||||||
Database string `json:"database" validate:"required"`
|
|
||||||
DB string `json:"db" validate:"required"`
|
|
||||||
Username string `json:"username" validate:"required"`
|
|
||||||
Password string `json:"password" validate:"required"`
|
|
||||||
Permission string `json:"permission" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MysqlLoadDB struct {
|
type MysqlLoadDB struct {
|
||||||
From string `json:"from" validate:"required,oneof=local remote"`
|
From string `json:"from" validate:"required,oneof=local remote"`
|
||||||
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
|
Type string `json:"type" validate:"required,oneof=mysql mariadb mysql-cluster"`
|
||||||
@@ -137,6 +196,83 @@ type MysqlStatus struct {
|
|||||||
Position string `json:"Position"`
|
Position string `json:"Position"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mongodb
|
||||||
|
type MongodbDBSearch struct {
|
||||||
|
PageInfo
|
||||||
|
Info string `json:"info"`
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
OrderBy string `json:"orderBy" validate:"required,oneof=name createdAt"`
|
||||||
|
Order string `json:"order" validate:"required,oneof=null ascending descending"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbDBInfo struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
From string `json:"from"`
|
||||||
|
MongodbName string `json:"mongodbName"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
IsDelete bool `json:"isDelete"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbDBCreate struct {
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
From string `json:"from" validate:"required,oneof=local remote"`
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
Permission string `json:"permission" validate:"required,oneof=dbOwner read readWrite userAdmin"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbLoadDB struct {
|
||||||
|
From string `json:"from" validate:"required,oneof=local remote"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=mongodb"`
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbDBDeleteCheck struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=mongodb"`
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbDBDelete struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=mongodb"`
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
ForceDelete bool `json:"forceDelete"`
|
||||||
|
DeleteBackup bool `json:"deleteBackup"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbBind struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbPassword struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbPrivileges struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
Permission string `json:"permission" validate:"required,oneof=dbOwner read readWrite userAdmin"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MongodbPrivilegesLoad struct {
|
||||||
|
Database string `json:"database" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Username string `json:"username" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type MysqlVariables struct {
|
type MysqlVariables struct {
|
||||||
BinlogCacheSize string `json:"binlog_cache_size"`
|
BinlogCacheSize string `json:"binlog_cache_size"`
|
||||||
InnodbBufferPoolSize string `json:"innodb_buffer_pool_size"`
|
InnodbBufferPoolSize string `json:"innodb_buffer_pool_size"`
|
||||||
|
|||||||
+325
-84
@@ -1,113 +1,354 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
type FirewallBaseInfo struct {
|
import (
|
||||||
Name string `json:"name"`
|
"github.com/1Panel-dev/1Panel/agent/utils/firewall"
|
||||||
IsExist bool `json:"isExist"`
|
dockerfirewall "github.com/1Panel-dev/1Panel/agent/utils/firewall/docker_guard"
|
||||||
IsActive bool `json:"isActive"`
|
"github.com/1Panel-dev/1Panel/agent/utils/firewall/filter"
|
||||||
IsInit bool `json:"isInit"`
|
"github.com/1Panel-dev/1Panel/agent/utils/firewall/forwarding"
|
||||||
IsBind bool `json:"isBind"`
|
)
|
||||||
Version string `json:"version"`
|
|
||||||
PingStatus string `json:"pingStatus"`
|
type FirewallSubsystemStatus struct {
|
||||||
|
IPv6Enabled bool `json:"ipv6Enabled"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Backend string `json:"backend"`
|
||||||
|
ConflictBackend string `json:"conflictBackend,omitempty"`
|
||||||
|
IsExist bool `json:"isExist"`
|
||||||
|
IsActive bool `json:"isActive"`
|
||||||
|
IsInit bool `json:"isInit"`
|
||||||
|
IsBind bool `json:"isBind"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
PingStatus string `json:"pingStatus"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
Reason string `json:"reason,omitempty"`
|
||||||
|
LifecycleTaskID string `json:"lifecycleTaskID,omitempty"`
|
||||||
|
IPv4 FirewallBackendFamilyStatus `json:"ipv4"`
|
||||||
|
IPv6 FirewallBackendFamilyStatus `json:"ipv6"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuleSearch struct {
|
type FirewallLifecycleOperation struct {
|
||||||
PageInfo
|
|
||||||
Info string `json:"info"`
|
|
||||||
Status string `json:"status"`
|
|
||||||
Strategy string `json:"strategy"`
|
|
||||||
Type string `json:"type" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type FirewallOperation struct {
|
|
||||||
Operation string `json:"operation" validate:"required,oneof=start stop restart disableBanPing enableBanPing"`
|
Operation string `json:"operation" validate:"required,oneof=start stop restart disableBanPing enableBanPing"`
|
||||||
WithDockerRestart bool `json:"withDockerRestart"`
|
WithDockerRestart bool `json:"withDockerRestart"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PortRuleOperate struct {
|
type FirewallLifecycleOperationResponse struct {
|
||||||
ID uint `json:"id"`
|
TaskID string `json:"taskID,omitempty"`
|
||||||
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
Queued bool `json:"queued"`
|
||||||
Chain string `json:"chain"`
|
|
||||||
Address string `json:"address"`
|
|
||||||
Port string `json:"port" validate:"required"`
|
|
||||||
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
|
|
||||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
|
||||||
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ForwardRuleOperate struct {
|
type FirewallBackendOption struct {
|
||||||
ForceDelete bool `json:"forceDelete"`
|
Name string `json:"name"`
|
||||||
Rules []struct {
|
Installed bool `json:"installed"`
|
||||||
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
Active bool `json:"active"`
|
||||||
Num string `json:"num"`
|
Initialized bool `json:"initialized"`
|
||||||
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
|
Bound bool `json:"bound"`
|
||||||
Interface string `json:"interface"`
|
Supported bool `json:"supported"`
|
||||||
Port string `json:"port" validate:"required"`
|
SupportReason string `json:"supportReason,omitempty"`
|
||||||
TargetIP string `json:"targetIP"`
|
Implementation string `json:"implementation,omitempty"`
|
||||||
TargetPort string `json:"targetPort" validate:"required"`
|
Message string `json:"message,omitempty"`
|
||||||
} `json:"rules"`
|
IPv4 FirewallBackendFamilyStatus `json:"ipv4"`
|
||||||
|
IPv6 FirewallBackendFamilyStatus `json:"ipv6"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateFirewallDescription struct {
|
type FirewallBackendFamilyStatus struct {
|
||||||
Type string `json:"type"`
|
Partial bool `json:"partial"`
|
||||||
Chain string `json:"chain"`
|
Available bool `json:"available"`
|
||||||
SrcIP string `json:"srcIP"`
|
Initialized bool `json:"initialized"`
|
||||||
DstIP string `json:"dstIP"`
|
Bound bool `json:"bound"`
|
||||||
SrcPort string `json:"srcPort"`
|
Reason string `json:"reason,omitempty"`
|
||||||
DstPort string `json:"dstPort"`
|
ForwardPolicy string `json:"forwardPolicy,omitempty"`
|
||||||
Protocol string `json:"protocol"`
|
RAInterfaces []string `json:"raInterfaces,omitempty"`
|
||||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
|
||||||
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddrRuleOperate struct {
|
type FirewallBackendGroup struct {
|
||||||
ID uint `json:"id"`
|
Selected string `json:"selected"`
|
||||||
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
Current string `json:"current,omitempty"`
|
||||||
Address string `json:"address" validate:"required"`
|
Options []FirewallBackendOption `json:"options"`
|
||||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
|
||||||
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type PortRuleUpdate struct {
|
type FirewallSettings struct {
|
||||||
OldRule PortRuleOperate `json:"oldRule"`
|
IPv6Enabled bool `json:"ipv6Enabled"`
|
||||||
NewRule PortRuleOperate `json:"newRule"`
|
System FirewallBackendGroup `json:"system"`
|
||||||
|
Forwarding FirewallBackendGroup `json:"forwarding"`
|
||||||
|
Docker FirewallBackendGroup `json:"docker"`
|
||||||
|
PingStatus string `json:"pingStatus"`
|
||||||
|
PortWhitelist []filter.PortWhitelist `json:"portWhiteList"`
|
||||||
|
PanelPort string `json:"panelPort"`
|
||||||
|
SSHPort string `json:"sshPort"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AddrRuleUpdate struct {
|
type FirewallPortWhitelistCreate struct {
|
||||||
OldRule AddrRuleOperate `json:"oldRule"`
|
Rule filter.PortWhitelist `json:"rule" validate:"required"`
|
||||||
NewRule AddrRuleOperate `json:"newRule"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type BatchRuleOperate struct {
|
type FirewallPortWhitelistUpdate struct {
|
||||||
Type string `json:"type" validate:"required"`
|
OldRule filter.PortWhitelist `json:"oldRule" validate:"required"`
|
||||||
Rules []PortRuleOperate `json:"rules"`
|
Rule filter.PortWhitelist `json:"rule" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IptablesOp struct {
|
type FirewallPortWhitelistDelete struct {
|
||||||
Name string `json:"name" validate:"required,oneof=1PANEL_INPUT 1PANEL_OUTPUT 1PANEL_BASIC"`
|
Rule *filter.PortWhitelist `json:"rule" validate:"required"`
|
||||||
Operate string `json:"operate" validate:"required,oneof=init-base init-forward init-advance bind-base unbind-base bind unbind"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type IptablesRuleOp struct {
|
type FirewallBackendOperation struct {
|
||||||
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
Subsystem string `json:"subsystem" validate:"required,oneof=system forwarding docker"`
|
||||||
ID uint `json:"id"`
|
Backend string `json:"backend" validate:"required,oneof=firewalld ufw iptables nftables"`
|
||||||
Chain string `json:"chain" validate:"required,oneof=1PANEL_BASIC 1PANEL_BASIC_BEFORE 1PANEL_INPUT 1PANEL_OUTPUT"`
|
Operation string `json:"operation" validate:"required,oneof=select initialize cleanup"`
|
||||||
Protocol string `json:"protocol"`
|
|
||||||
SrcIP string `json:"srcIP"`
|
|
||||||
SrcPort uint `json:"srcPort"`
|
|
||||||
DstIP string `json:"dstIP"`
|
|
||||||
DstPort uint `json:"dstPort"`
|
|
||||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop reject"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type IptablesBatchOperate struct {
|
type FirewallIPv6Operation struct {
|
||||||
Rules []IptablesRuleOp `json:"rules"`
|
Status string `json:"status" validate:"required,oneof=Enable Disable"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IptablesChainStatus struct {
|
type FirewallFamilyOperation struct {
|
||||||
IsBind bool `json:"isBind"`
|
Subsystem string `json:"subsystem" validate:"required,oneof=system forwarding docker"`
|
||||||
DefaultStrategy string `json:"defaultStrategy"`
|
Backend string `json:"backend" validate:"required,oneof=iptables nftables"`
|
||||||
|
Family string `json:"family" validate:"required,oneof=ipv4 ipv6"`
|
||||||
|
Operation string `json:"operation" validate:"required,oneof=initialize repair bind"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterChainOperation struct {
|
||||||
|
Name string `json:"name" validate:"required,eq=1PANEL_BASIC"`
|
||||||
|
Operate string `json:"operate" validate:"required,oneof=init-base bind-base unbind-base"`
|
||||||
|
TaskID string `json:"taskID,omitempty" validate:"omitempty,max=64"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterChainOperationResponse struct {
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
Queued bool `json:"queued"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallInitializationTask struct {
|
||||||
|
BackupFile string `json:"backupFile,omitempty" validate:"omitempty,max=255"`
|
||||||
|
TaskID string `json:"taskID,omitempty" validate:"omitempty,max=64"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallSystemPort = firewall.SystemPort
|
||||||
|
|
||||||
|
type FirewallRuleInventoryResponse struct {
|
||||||
|
IPv4Range filter.PositionRange `json:"ipv4Range"`
|
||||||
|
IPv6Range filter.PositionRange `json:"ipv6Range"`
|
||||||
|
Total int64 `json:"total"`
|
||||||
|
AllTotal int64 `json:"allTotal"`
|
||||||
|
Items []filter.InventoryItem `json:"items"`
|
||||||
|
Notices []filter.ScopeNotice `json:"notices,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleBackup struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Provider filter.Provider `json:"provider"`
|
||||||
|
RuleCount int `json:"ruleCount"`
|
||||||
|
ModifiedAt int64 `json:"modifiedAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleBackups struct {
|
||||||
|
Directory string `json:"directory"`
|
||||||
|
Files []FirewallRuleBackup `json:"files"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleResetResponse struct {
|
||||||
|
BackupPath string `json:"backupPath"`
|
||||||
|
Removed int `json:"removed"`
|
||||||
|
Disabled bool `json:"disabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleReset struct {
|
||||||
|
Subsystem string `json:"subsystem,omitempty" validate:"omitempty,oneof=system forwarding docker"`
|
||||||
|
Backup *bool `json:"backup,omitempty" default:"true"`
|
||||||
|
Provider filter.Provider `json:"provider,omitempty" validate:"omitempty,oneof=firewalld ufw iptables nftables"`
|
||||||
|
WithDockerRestart bool `json:"withDockerRestart"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleInventory struct {
|
||||||
|
PageInfo
|
||||||
|
Scope filter.Scope `json:"scope,omitempty"`
|
||||||
|
Scopes []filter.Scope `json:"scopes,omitempty" validate:"max=16"`
|
||||||
|
All bool `json:"all,omitempty"`
|
||||||
|
Info string `json:"info"`
|
||||||
|
Families []filter.Family `json:"families,omitempty" validate:"omitempty,dive,oneof=ipv4 ipv6"`
|
||||||
|
Actions []string `json:"actions,omitempty" validate:"omitempty,dive,oneof=accept deny"`
|
||||||
|
ExcludeChains []string `json:"excludeChains,omitempty" validate:"omitempty,dive,oneof=1PANEL_BASIC_BEFORE 1PANEL_BASIC 1PANEL_BASIC_AFTER"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallNativeDetail struct {
|
||||||
|
Provider filter.Provider `json:"provider" validate:"required,oneof=firewalld ufw"`
|
||||||
|
NativeKind filter.NativeKind `json:"nativeKind" validate:"required,oneof=zone_service ufw_application"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Permanent bool `json:"permanent"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardBase struct {
|
||||||
|
IPv6Enabled bool `json:"ipv6Enabled"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
IsExist bool `json:"isExist"`
|
||||||
|
Initialized bool `json:"initialized"`
|
||||||
|
Bound bool `json:"bound"`
|
||||||
|
IPv4 DockerPortGuardFamilyStatus `json:"ipv4"`
|
||||||
|
IPv6 DockerPortGuardFamilyStatus `json:"ipv6"`
|
||||||
|
Backend string `json:"backend"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardFamilyStatus struct {
|
||||||
|
Partial bool `json:"partial"`
|
||||||
|
State string `json:"state"`
|
||||||
|
Reason string `json:"reason,omitempty"`
|
||||||
|
Initialized bool `json:"initialized"`
|
||||||
|
Bound bool `json:"bound"`
|
||||||
|
Effective bool `json:"effective"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardEndpoint struct {
|
||||||
|
Family string `json:"family"`
|
||||||
|
HostIP string `json:"hostIP"`
|
||||||
|
HostPort uint16 `json:"hostPort"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
ContainerID string `json:"containerID"`
|
||||||
|
ContainerName string `json:"containerName"`
|
||||||
|
ContainerState string `json:"containerState,omitempty"`
|
||||||
|
ContainerPort uint16 `json:"containerPort"`
|
||||||
|
Compose string `json:"compose,omitempty"`
|
||||||
|
Application string `json:"application,omitempty"`
|
||||||
|
PolicyUUID string `json:"policyUUID,omitempty"`
|
||||||
|
Mode string `json:"mode,omitempty"`
|
||||||
|
Sources []string `json:"sources"`
|
||||||
|
Effective bool `json:"effective"`
|
||||||
|
TrafficPath string `json:"trafficPath"`
|
||||||
|
ManagementTarget string `json:"managementTarget"`
|
||||||
|
ManagementReason string `json:"managementReason,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardPortGroup struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Label string `json:"label"`
|
||||||
|
Endpoint DockerPortGuardEndpoint `json:"endpoint"`
|
||||||
|
Endpoints []DockerPortGuardEndpoint `json:"endpoints"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardContainer struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Compose string `json:"compose,omitempty"`
|
||||||
|
Application string `json:"application,omitempty"`
|
||||||
|
Endpoints []DockerPortGuardEndpoint `json:"endpoints"`
|
||||||
|
PortGroups []DockerPortGuardPortGroup `json:"portGroups"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardList struct {
|
||||||
|
Base DockerPortGuardBase `json:"base"`
|
||||||
|
Containers []DockerPortGuardContainer `json:"containers"`
|
||||||
|
OrphanPolicies []DockerPortGuardEndpoint `json:"orphanPolicies"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardEndpointIdentity struct {
|
||||||
|
Family string `json:"family" validate:"required,oneof=ipv4 ipv6"`
|
||||||
|
HostIP string `json:"hostIP" validate:"required,max=45"`
|
||||||
|
HostPort uint16 `json:"hostPort" validate:"required,min=1"`
|
||||||
|
Protocol string `json:"protocol" validate:"required,oneof=tcp udp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardPolicyBatch struct {
|
||||||
|
Policies []DockerPortGuardPolicy `json:"policies" validate:"required,min=1,dive"`
|
||||||
|
Import bool `json:"import"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardPolicyBatchDelete struct {
|
||||||
|
UUIDs []string `json:"uuids" validate:"required,min=1,dive,required,max=64"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardPolicy struct {
|
||||||
|
DockerPortGuardEndpointIdentity
|
||||||
|
Mode string `json:"mode" validate:"required,oneof=deny_sources allow_sources deny_all accept_sources accept_all"`
|
||||||
|
Sources []string `json:"sources" validate:"dive,required,max=64"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DockerPortGuardOperation struct {
|
||||||
|
BackupFile string `json:"backupFile,omitempty" validate:"omitempty,max=255"`
|
||||||
|
Operation string `json:"operation" validate:"required,oneof=initialize bind unbind"`
|
||||||
|
TaskID string `json:"taskID,omitempty" validate:"omitempty,max=64"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleCreateItem struct {
|
||||||
|
Raw string `json:"raw,omitempty"`
|
||||||
|
ParseStatus filter.ParseStatus `json:"parseStatus,omitempty"`
|
||||||
|
Rule filter.FirewallRule `json:"rule" validate:"required"`
|
||||||
|
SourceKind string `json:"sourceKind" validate:"omitempty,oneof=user imported"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleCreate struct {
|
||||||
|
BackupFile string `json:"backupFile,omitempty" validate:"omitempty,max=255"`
|
||||||
|
Initialize bool `json:"initialize"`
|
||||||
|
Items []FirewallRuleCreateItem `json:"items" validate:"dive"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleCreateResponse struct {
|
||||||
|
TaskID string `json:"taskID,omitempty"`
|
||||||
|
Queued bool `json:"queued,omitempty"`
|
||||||
|
Succeeded int `json:"succeeded"`
|
||||||
|
Failed int `json:"failed"`
|
||||||
|
Skipped int `json:"skipped"`
|
||||||
|
Errors []FirewallRuleCreateFailure `json:"errors,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleCreateFailure struct {
|
||||||
|
Index int `json:"index"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Rule filter.FirewallRule `json:"rule"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleDelete struct {
|
||||||
|
Targets []FirewallRuleDeleteItem `json:"targets" validate:"required,min=1,dive"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleDeleteItem struct {
|
||||||
|
FirewallRuleDeleteTarget
|
||||||
|
Observed filter.ObservedRule `json:"observed" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleDeleteTarget struct {
|
||||||
|
Scope filter.Scope `json:"scope" validate:"required"`
|
||||||
|
InstanceKey string `json:"instanceKey" validate:"required,max=128"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleDeleteResponse struct {
|
||||||
|
TaskID string `json:"taskID,omitempty"`
|
||||||
|
Queued bool `json:"queued,omitempty"`
|
||||||
|
Succeeded int `json:"succeeded"`
|
||||||
|
Failed int `json:"failed"`
|
||||||
|
Errors []FirewallRuleDeleteFailure `json:"errors,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleDeleteFailure struct {
|
||||||
|
Index int `json:"index"`
|
||||||
|
InstanceKey string `json:"instanceKey"`
|
||||||
|
Error string `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleUpdate struct {
|
||||||
|
FirewallRuleDeleteTarget
|
||||||
|
Rule *filter.FirewallRule `json:"rule,omitempty" validate:"required_without_all=Description OrderIndex Priority,excluded_with=Description OrderIndex Priority"`
|
||||||
|
Description *string `json:"description,omitempty" validate:"excluded_with=Rule"`
|
||||||
|
OrderIndex *int64 `json:"orderIndex,omitempty" validate:"excluded_with=Rule Priority"`
|
||||||
|
Priority *int `json:"priority,omitempty" validate:"excluded_with=Rule OrderIndex"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleReorder struct {
|
||||||
|
FirewallRuleDeleteTarget
|
||||||
|
TargetPosition *int64 `json:"targetPosition"`
|
||||||
|
Priority *int `json:"priority"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallRuleExportItem struct {
|
||||||
|
filter.FirewallRule
|
||||||
|
Raw string `json:"raw,omitempty"`
|
||||||
|
ParseStatus filter.ParseStatus `json:"parseStatus,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallSubsystemBackup struct {
|
||||||
|
Families []string `json:"families,omitempty"`
|
||||||
|
Subsystem string `json:"subsystem"`
|
||||||
|
Provider filter.Provider `json:"provider"`
|
||||||
|
Forwarding []forwarding.Rule `json:"forwarding"`
|
||||||
|
Docker *dockerfirewall.PolicyInventory `json:"docker,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
type ForwardRuleSearch struct {
|
||||||
|
PageInfo
|
||||||
|
All bool `json:"all,omitempty"`
|
||||||
|
Info string `json:"info"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Strategy string `json:"strategy"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ForwardRule struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Chain string `json:"chain"`
|
||||||
|
Family string `json:"family"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Port string `json:"port"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
Strategy string `json:"strategy"`
|
||||||
|
|
||||||
|
Num string `json:"num"`
|
||||||
|
TargetIP string `json:"targetIP"`
|
||||||
|
TargetPort string `json:"targetPort"`
|
||||||
|
Interface string `json:"interface"`
|
||||||
|
|
||||||
|
UsedStatus string `json:"usedStatus"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ForwardRuleOperate struct {
|
||||||
|
Import bool `json:"import"`
|
||||||
|
Rules []ForwardRuleOperation `json:"rules" validate:"required,min=1,dive"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ForwardRuleOperation struct {
|
||||||
|
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
||||||
|
Num string `json:"num"`
|
||||||
|
Family string `json:"family" validate:"omitempty,oneof=ipv4 ipv6"`
|
||||||
|
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
|
||||||
|
Interface string `json:"interface"`
|
||||||
|
Port string `json:"port" validate:"required"`
|
||||||
|
TargetIP string `json:"targetIP"`
|
||||||
|
TargetPort string `json:"targetPort" validate:"required"`
|
||||||
|
}
|
||||||
@@ -1,15 +1,52 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SearchTaskLogReq struct {
|
type SearchTaskLogReq struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
PageInfo
|
PageInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
type TaskDTO struct {
|
type TaskDTO struct {
|
||||||
model.Task
|
model.Task
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SystemLogReq struct {
|
||||||
|
PageSize int `json:"pageSize" validate:"omitempty,min=1,max=500"`
|
||||||
|
Cursor string `json:"cursor"`
|
||||||
|
StartTime time.Time `json:"startTime"`
|
||||||
|
EndTime time.Time `json:"endTime"`
|
||||||
|
Keyword string `json:"keyword"`
|
||||||
|
Priority string `json:"priority"`
|
||||||
|
Service string `json:"service"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemLogRes struct {
|
||||||
|
Source string `json:"source"`
|
||||||
|
Items []SystemLogItem `json:"items"`
|
||||||
|
HasMore bool `json:"hasMore"`
|
||||||
|
NextCursor string `json:"nextCursor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemLogStatus struct {
|
||||||
|
Source string `json:"source"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
KeywordFilterSupported bool `json:"keywordFilterSupported"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SystemLogItem struct {
|
||||||
|
Timestamp int64 `json:"-"`
|
||||||
|
Cursor string `json:"-"`
|
||||||
|
Time string `json:"time"`
|
||||||
|
Priority string `json:"priority"`
|
||||||
|
Service string `json:"service"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Raw string `json:"raw"`
|
||||||
|
}
|
||||||
|
|||||||
+89
-18
@@ -1,6 +1,10 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
)
|
||||||
|
|
||||||
type MonitorSearch struct {
|
type MonitorSearch struct {
|
||||||
Param string `json:"param" validate:"required,oneof=all cpu memory load io network"`
|
Param string `json:"param" validate:"required,oneof=all cpu memory load io network"`
|
||||||
@@ -26,50 +30,92 @@ type Process struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MonitorSetting struct {
|
type MonitorSetting struct {
|
||||||
MonitorStatus string `json:"monitorStatus"`
|
GPUMonitorStatus string `json:"gpuMonitorStatus"`
|
||||||
MonitorStoreDays string `json:"monitorStoreDays"`
|
GPUMonitorStoreDays string `json:"gpuMonitorStoreDays"`
|
||||||
MonitorInterval string `json:"monitorInterval"`
|
GPUMonitorInterval string `json:"gpuMonitorInterval"`
|
||||||
DefaultNetwork string `json:"defaultNetwork"`
|
VLLMMonitorStatus string `json:"vllmMonitorStatus"`
|
||||||
DefaultIO string `json:"defaultIO"`
|
VLLMMonitorStoreDays string `json:"vllmMonitorStoreDays"`
|
||||||
|
VLLMMonitorInterval string `json:"vllmMonitorInterval"`
|
||||||
|
MonitorStatus string `json:"monitorStatus"`
|
||||||
|
MonitorStoreDays string `json:"monitorStoreDays"`
|
||||||
|
MonitorInterval string `json:"monitorInterval"`
|
||||||
|
DefaultNetwork string `json:"defaultNetwork"`
|
||||||
|
DefaultIO string `json:"defaultIO"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MonitorSettingUpdate struct {
|
type MonitorSettingUpdate struct {
|
||||||
Key string `json:"key" validate:"required,oneof=MonitorStatus MonitorStoreDays MonitorInterval DefaultNetwork DefaultIO"`
|
Key string `json:"key" validate:"required,oneof=MonitorStatus MonitorStoreDays MonitorInterval GPUMonitorStatus GPUMonitorStoreDays GPUMonitorInterval VLLMMonitorStatus VLLMMonitorStoreDays VLLMMonitorInterval DefaultNetwork DefaultIO"`
|
||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MonitorGPUOptions struct {
|
type MonitorGPUOptions struct {
|
||||||
|
Supported bool `json:"supported"`
|
||||||
GPUType string `json:"gpuType"`
|
GPUType string `json:"gpuType"`
|
||||||
ChartHide []GPUChartHide `json:"chartHide"`
|
ChartHide []GPUChartHide `json:"chartHide"`
|
||||||
Options []string `json:"options"`
|
Options []string `json:"options"`
|
||||||
}
|
}
|
||||||
type GPUChartHide struct {
|
type GPUChartHide struct {
|
||||||
|
DeviceID string `json:"deviceID"`
|
||||||
|
Legacy bool `json:"legacy"`
|
||||||
ProductName string `json:"productName"`
|
ProductName string `json:"productName"`
|
||||||
|
Type string `json:"type"`
|
||||||
Process bool `json:"process"`
|
Process bool `json:"process"`
|
||||||
GPU bool `json:"gpu"`
|
GPU bool `json:"gpu"`
|
||||||
Memory bool `json:"memory"`
|
Memory bool `json:"memory"`
|
||||||
Power bool `json:"power"`
|
Power bool `json:"power"`
|
||||||
|
PowerLimit bool `json:"powerLimit"`
|
||||||
Temperature bool `json:"temperature"`
|
Temperature bool `json:"temperature"`
|
||||||
Speed bool `json:"speed"`
|
Speed bool `json:"speed"`
|
||||||
}
|
}
|
||||||
type MonitorGPUSearch struct {
|
type MonitorGPUSearch struct {
|
||||||
|
Aggregation string `json:"aggregation" validate:"omitempty,oneof=avg max"`
|
||||||
|
DeviceID string `json:"deviceID"`
|
||||||
|
Legacy bool `json:"legacy"`
|
||||||
ProductName string `json:"productName"`
|
ProductName string `json:"productName"`
|
||||||
StartTime time.Time `json:"startTime"`
|
StartTime time.Time `json:"startTime"`
|
||||||
EndTime time.Time `json:"endTime"`
|
EndTime time.Time `json:"endTime"`
|
||||||
}
|
}
|
||||||
type MonitorGPUData struct {
|
type MonitorGPUData struct {
|
||||||
Date []time.Time `json:"date"`
|
MemoryActivity []*float64 `json:"memoryActivity"`
|
||||||
GPUValue []float64 `json:"gpuValue"`
|
EncoderUtil []*float64 `json:"encoderUtil"`
|
||||||
TemperatureValue []float64 `json:"temperatureValue"`
|
DecoderUtil []*float64 `json:"decoderUtil"`
|
||||||
PowerTotal []float64 `json:"powerTotal"`
|
JPEGUtil []*float64 `json:"jpegUtil"`
|
||||||
PowerUsed []float64 `json:"powerUsed"`
|
OFAUtil []*float64 `json:"ofaUtil"`
|
||||||
PowerPercent []float64 `json:"powerPercent"`
|
MediaUtil []*float64 `json:"mediaUtil"`
|
||||||
MemoryTotal []float64 `json:"memoryTotal"`
|
ComputeUtil []*float64 `json:"computeUtil"`
|
||||||
MemoryUsed []float64 `json:"memoryUsed"`
|
CopyUtil []*float64 `json:"copyUtil"`
|
||||||
MemoryPercent []float64 `json:"memoryPercent"`
|
HotspotTemperature []*float64 `json:"hotspotTemperature"`
|
||||||
SpeedValue []int `json:"speedValue"`
|
FanRPM []*float64 `json:"fanRPM"`
|
||||||
|
AICPUUtil []*float64 `json:"aiCPUUtil"`
|
||||||
|
CtrlCPUUtil []*float64 `json:"ctrlCPUUtil"`
|
||||||
|
DDRUsed []*float64 `json:"ddrUsed"`
|
||||||
|
DDRTotal []*float64 `json:"ddrTotal"`
|
||||||
|
HBMUsed []*float64 `json:"hbmUsed"`
|
||||||
|
HBMTotal []*float64 `json:"hbmTotal"`
|
||||||
|
DDRBandwidth []*float64 `json:"ddrBandwidth"`
|
||||||
|
HBMBandwidth []*float64 `json:"hbmBandwidth"`
|
||||||
|
MemoryBandwidth []*float64 `json:"memoryBandwidth"`
|
||||||
|
MediaFrequency []*float64 `json:"mediaFrequency"`
|
||||||
|
HugepagesUsed []*float64 `json:"hugepagesUsed"`
|
||||||
|
HugepagesTotal []*float64 `json:"hugepagesTotal"`
|
||||||
|
|
||||||
ProcessCount []int `json:"processCount"`
|
BucketSeconds int64 `json:"bucketSeconds"`
|
||||||
|
SampleCount int64 `json:"sampleCount"`
|
||||||
|
MemoryTemperatureValue []*float64 `json:"memoryTemperatureValue"`
|
||||||
|
FrequencyValue []*float64 `json:"frequencyValue"`
|
||||||
|
MemoryFrequencyValue []*float64 `json:"memoryFrequencyValue"`
|
||||||
|
Date []time.Time `json:"date"`
|
||||||
|
GPUValue []*float64 `json:"gpuValue"`
|
||||||
|
TemperatureValue []*float64 `json:"temperatureValue"`
|
||||||
|
PowerTotal []*float64 `json:"powerTotal"`
|
||||||
|
PowerUsed []*float64 `json:"powerUsed"`
|
||||||
|
PowerPercent []*float64 `json:"powerPercent"`
|
||||||
|
MemoryTotal []*float64 `json:"memoryTotal"`
|
||||||
|
MemoryUsed []*float64 `json:"memoryUsed"`
|
||||||
|
MemoryPercent []*float64 `json:"memoryPercent"`
|
||||||
|
SpeedValue []*float64 `json:"speedValue"`
|
||||||
|
|
||||||
|
ProcessCount []*float64 `json:"processCount"`
|
||||||
GPUProcesses [][]GPUProcess `json:"gpuProcesses"`
|
GPUProcesses [][]GPUProcess `json:"gpuProcesses"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,3 +125,28 @@ type GPUProcess struct {
|
|||||||
ProcessName string `json:"processName"`
|
ProcessName string `json:"processName"`
|
||||||
UsedMemory string `json:"usedMemory"`
|
UsedMemory string `json:"usedMemory"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MonitorVLLMSearch struct {
|
||||||
|
AppInstallID uint `json:"appInstallID" validate:"required"`
|
||||||
|
StartTime time.Time `json:"startTime" validate:"required"`
|
||||||
|
EndTime time.Time `json:"endTime" validate:"required"`
|
||||||
|
Aggregation string `json:"aggregation" validate:"omitempty,oneof=avg max"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MonitorVLLMData struct {
|
||||||
|
SampleCount int64 `json:"sampleCount"`
|
||||||
|
BucketSeconds int64 `json:"bucketSeconds"`
|
||||||
|
Points []model.MonitorVLLM `json:"points"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MonitorVLLMCurrent struct {
|
||||||
|
AppInstallID uint `json:"appInstallID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MonitorVLLMClean struct {
|
||||||
|
AppInstallID uint `json:"appInstallID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MonitorClean struct {
|
||||||
|
Type string `json:"type" validate:"required,oneof=host gpu"`
|
||||||
|
}
|
||||||
|
|||||||
+46
-6
@@ -1,6 +1,8 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx/components"
|
"github.com/1Panel-dev/1Panel/agent/utils/nginx/components"
|
||||||
)
|
)
|
||||||
@@ -49,13 +51,19 @@ const (
|
|||||||
CACHE NginxKey = "cache"
|
CACHE NginxKey = "cache"
|
||||||
HttpPer NginxKey = "http-per"
|
HttpPer NginxKey = "http-per"
|
||||||
ProxyCache NginxKey = "proxy-cache"
|
ProxyCache NginxKey = "proxy-cache"
|
||||||
|
Brotli NginxKey = "brotli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// BrotliKeys are served from the panel-managed http.d file rather than
|
||||||
|
// nginx.conf, because the module is optional: its directives must disappear
|
||||||
|
// together with the module, otherwise nginx refuses to start.
|
||||||
|
var BrotliKeys = []string{"brotli", "brotli_comp_level", "brotli_min_length", "brotli_types"}
|
||||||
|
|
||||||
var ScopeKeyMap = map[NginxKey][]string{
|
var ScopeKeyMap = map[NginxKey][]string{
|
||||||
Index: {"index"},
|
Index: {"index"},
|
||||||
LimitConn: {"limit_conn", "limit_rate", "limit_conn_zone"},
|
LimitConn: {"limit_conn", "limit_rate", "limit_conn_zone"},
|
||||||
SSL: {"ssl_certificate", "ssl_certificate_key"},
|
SSL: {"ssl_certificate", "ssl_certificate_key"},
|
||||||
HttpPer: {"server_names_hash_bucket_size", "client_header_buffer_size", "client_max_body_size", "keepalive_timeout", "gzip", "gzip_min_length", "gzip_comp_level"},
|
HttpPer: {"server_names_hash_bucket_size", "client_header_buffer_size", "client_max_body_size", "keepalive_timeout", "gzip", "gzip_min_length", "gzip_comp_level", "gzip_types", "gzip_vary", "gzip_proxied"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var StaticFileKeyMap = map[NginxKey]struct {
|
var StaticFileKeyMap = map[NginxKey]struct {
|
||||||
@@ -87,9 +95,41 @@ var LBAlgorithms = map[string]struct{}{"ip_hash": {}, "least_conn": {}}
|
|||||||
var RealIPKeys = map[string]struct{}{"X-Forwarded-For": {}, "X-Real-IP": {}, "CF-Connecting-IP": {}}
|
var RealIPKeys = map[string]struct{}{"X-Forwarded-For": {}, "X-Real-IP": {}, "CF-Connecting-IP": {}}
|
||||||
|
|
||||||
type NginxModule struct {
|
type NginxModule struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Script string `json:"script"`
|
Custom bool `json:"custom,omitempty"`
|
||||||
Packages []string `json:"packages"`
|
Script string `json:"script"`
|
||||||
Params string `json:"params"`
|
Packages []string `json:"packages"`
|
||||||
Enable bool `json:"enable"`
|
Params string `json:"params"`
|
||||||
|
Enable bool `json:"enable"`
|
||||||
|
BuildMode string `json:"buildMode,omitempty"`
|
||||||
|
Provider string `json:"provider,omitempty"`
|
||||||
|
LoadOrder int `json:"loadOrder,omitempty"`
|
||||||
|
Builds []NginxModuleBuild `json:"builds,omitempty"`
|
||||||
|
LastError string `json:"lastError,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NginxModuleBuild struct {
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
BuildMode string `json:"buildMode"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Hash string `json:"hash"`
|
||||||
|
Target NginxModuleTarget `json:"target"`
|
||||||
|
Artifacts []NginxModuleArtifact `json:"artifacts,omitempty"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
BuiltAt time.Time `json:"builtAt,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NginxModuleTarget struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
OpenRestyVersion string `json:"openrestyVersion"`
|
||||||
|
Architecture string `json:"architecture"`
|
||||||
|
Image string `json:"image,omitempty"`
|
||||||
|
ImageDigest string `json:"imageDigest,omitempty"`
|
||||||
|
BuilderDigest string `json:"builderDigest,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NginxModuleArtifact struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Checksum string `json:"checksum"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ type AppContainerConfig struct {
|
|||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
SpecifyIP string `json:"specifyIP"`
|
SpecifyIP string `json:"specifyIP"`
|
||||||
RestartPolicy string `json:"restartPolicy" validate:"omitempty,oneof=always unless-stopped no on-failure"`
|
RestartPolicy string `json:"restartPolicy" validate:"omitempty,oneof=always unless-stopped no on-failure"`
|
||||||
|
|
||||||
|
KeepServiceName bool `json:"-"`
|
||||||
|
SkipComposeCommonConfig bool `json:"-"`
|
||||||
|
UseLifecycleScripts bool `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppInstalledSearch struct {
|
type AppInstalledSearch struct {
|
||||||
@@ -92,6 +96,8 @@ type AppInstalledOperate struct {
|
|||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
DeleteImage bool `json:"deleteImage"`
|
DeleteImage bool `json:"deleteImage"`
|
||||||
Favorite bool `json:"favorite"`
|
Favorite bool `json:"favorite"`
|
||||||
|
|
||||||
|
UseLifecycleScripts bool `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppInstallUpgrade struct {
|
type AppInstallUpgrade struct {
|
||||||
@@ -99,6 +105,7 @@ type AppInstallUpgrade struct {
|
|||||||
DetailID uint `json:"detailId"`
|
DetailID uint `json:"detailId"`
|
||||||
Backup bool `json:"backup"`
|
Backup bool `json:"backup"`
|
||||||
PullImage bool `json:"pullImage"`
|
PullImage bool `json:"pullImage"`
|
||||||
|
DeleteImage bool `json:"deleteImage"`
|
||||||
DockerCompose string `json:"dockerCompose"`
|
DockerCompose string `json:"dockerCompose"`
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
}
|
}
|
||||||
@@ -110,11 +117,14 @@ type AppInstallDelete struct {
|
|||||||
DeleteDB bool `json:"deleteDB"`
|
DeleteDB bool `json:"deleteDB"`
|
||||||
DeleteImage bool `json:"deleteImage"`
|
DeleteImage bool `json:"deleteImage"`
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
|
|
||||||
|
UseLifecycleScripts bool `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppInstalledUpdate struct {
|
type AppInstalledUpdate struct {
|
||||||
InstallId uint `json:"installId" validate:"required"`
|
InstallId uint `json:"installId" validate:"required"`
|
||||||
Params map[string]interface{} `json:"params" validate:"required"`
|
Params map[string]interface{} `json:"params" validate:"required"`
|
||||||
|
TaskID string `json:"-"`
|
||||||
AppContainerConfig
|
AppContainerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ type FileCompress struct {
|
|||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Replace bool `json:"replace"`
|
Replace bool `json:"replace"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileCompressStopReq struct {
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileDeCompress struct {
|
type FileDeCompress struct {
|
||||||
@@ -85,6 +90,11 @@ type FileDeCompress struct {
|
|||||||
Type string `json:"type" validate:"required"`
|
Type string `json:"type" validate:"required"`
|
||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileDeCompressStopReq struct {
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileEdit struct {
|
type FileEdit struct {
|
||||||
@@ -111,6 +121,8 @@ type FileWget struct {
|
|||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
IgnoreCertificate bool `json:"ignoreCertificate"`
|
IgnoreCertificate bool `json:"ignoreCertificate"`
|
||||||
|
UseProxy bool `json:"useProxy"`
|
||||||
|
UseServerFilename bool `json:"useServerFilename"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileMove struct {
|
type FileMove struct {
|
||||||
@@ -120,6 +132,11 @@ type FileMove struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Cover bool `json:"cover"`
|
Cover bool `json:"cover"`
|
||||||
CoverPaths []string `json:"coverPaths"`
|
CoverPaths []string `json:"coverPaths"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileMoveStopReq struct {
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileDownload struct {
|
type FileDownload struct {
|
||||||
@@ -142,6 +159,10 @@ type FileProcessReq struct {
|
|||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FileProcessRemoveReq struct {
|
||||||
|
Keys []string `json:"keys" validate:"required,min=1,max=1000"`
|
||||||
|
}
|
||||||
|
|
||||||
type FileRoleUpdate struct {
|
type FileRoleUpdate struct {
|
||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
User string `json:"user" validate:"required"`
|
User string `json:"user" validate:"required"`
|
||||||
@@ -152,13 +173,20 @@ type FileRoleUpdate struct {
|
|||||||
type FileReadByLineReq struct {
|
type FileReadByLineReq struct {
|
||||||
Page int `json:"page" validate:"required"`
|
Page int `json:"page" validate:"required"`
|
||||||
PageSize int `json:"pageSize" validate:"required"`
|
PageSize int `json:"pageSize" validate:"required"`
|
||||||
Type string `json:"type" validate:"required"`
|
Type string `json:"type"`
|
||||||
ID uint `json:"ID"`
|
ID uint `json:"ID"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Latest bool `json:"latest"`
|
Latest bool `json:"latest"`
|
||||||
TaskReq
|
TaskReq
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TaskLogReadReq struct {
|
||||||
|
Page int `json:"page" validate:"required,min=1"`
|
||||||
|
PageSize int `json:"pageSize" validate:"required,min=1"`
|
||||||
|
Latest bool `json:"latest"`
|
||||||
|
TaskReq
|
||||||
|
}
|
||||||
|
|
||||||
type TaskReq struct {
|
type TaskReq struct {
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
TaskType string `json:"taskType"`
|
TaskType string `json:"taskType"`
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileHistorySearchReq struct {
|
||||||
|
dto.PageInfo
|
||||||
|
Path string `json:"path"`
|
||||||
|
Scope string `json:"scope" validate:"required,oneof=current all"`
|
||||||
|
Operation string `json:"operation"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileHistoryContentReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileHistoryIDs []uint
|
||||||
|
|
||||||
|
func (ids *FileHistoryIDs) UnmarshalJSON(data []byte) error {
|
||||||
|
type alias []uint
|
||||||
|
var direct alias
|
||||||
|
if err := json.Unmarshal(data, &direct); err == nil {
|
||||||
|
*ids = FileHistoryIDs(direct)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapped struct {
|
||||||
|
IDs []uint `json:"ids"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(data, &wrapped); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*ids = FileHistoryIDs(wrapped.IDs)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileHistoryDeleteReq struct {
|
||||||
|
IDs FileHistoryIDs `json:"ids" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileHistoryRestoreReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileHistorySettingUpdate struct {
|
||||||
|
Enable string `json:"enable" validate:"required,oneof=Enable Disable"`
|
||||||
|
MaxPerPath int `json:"maxPerPath" validate:"min=0,max=1000"`
|
||||||
|
DiskQuotaMB int `json:"diskQuotaMB" validate:"min=0,max=1048576"`
|
||||||
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
package request
|
package request
|
||||||
|
|
||||||
type HostToolReq struct {
|
type HostToolTypeReq struct {
|
||||||
|
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostToolOperateReq struct {
|
||||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||||
Operate string `json:"operate" validate:"oneof=status restart start stop"`
|
Operate string `json:"operate" validate:"required,oneof=restart start stop"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HostToolCreate struct {
|
type HostToolCreate struct {
|
||||||
@@ -15,13 +19,8 @@ type SupervisorConfig struct {
|
|||||||
ServiceName string `json:"serviceName"`
|
ServiceName string `json:"serviceName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type HostToolLogReq struct {
|
type HostToolConfigUpdate struct {
|
||||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type HostToolConfig struct {
|
|
||||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||||
Operate string `json:"operate" validate:"oneof=get set"`
|
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,3 +42,15 @@ type SupervisorProcessFileReq struct {
|
|||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
File string `json:"file" validate:"required,oneof=out.log err.log config"`
|
File string `json:"file" validate:"required,oneof=out.log err.log config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type HostSupervisorProcessFileGetReq struct {
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
File string `json:"file" validate:"required,oneof=out.log err.log config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostSupervisorProcessFileOperateReq struct {
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Operate string `json:"operate" validate:"required,oneof=clear update"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
File string `json:"file" validate:"required,oneof=out.log err.log config"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ type McpServerCreate struct {
|
|||||||
StreamableHttpPath string `json:"streamableHttpPath"`
|
StreamableHttpPath string `json:"streamableHttpPath"`
|
||||||
OutputTransport string `json:"outputTransport" validate:"required"`
|
OutputTransport string `json:"outputTransport" validate:"required"`
|
||||||
Type string `json:"type" validate:"required"`
|
Type string `json:"type" validate:"required"`
|
||||||
|
GatewayImage string `json:"gatewayImage"`
|
||||||
|
ProtocolVersion string `json:"protocolVersion"`
|
||||||
|
GatewayArgs string `json:"gatewayArgs" validate:"max=4096"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type McpServerUpdate struct {
|
type McpServerUpdate struct {
|
||||||
@@ -32,11 +36,23 @@ type McpServerDelete struct {
|
|||||||
ID uint `json:"id" validate:"required"`
|
ID uint `json:"id" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type McpServerDetail struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type McpServerStatusSync struct {
|
||||||
|
IDs []uint `json:"ids"`
|
||||||
|
}
|
||||||
|
|
||||||
type McpServerOperate struct {
|
type McpServerOperate struct {
|
||||||
ID uint `json:"id" validate:"required"`
|
ID uint `json:"id" validate:"required"`
|
||||||
Operate string `json:"operate" validate:"required"`
|
Operate string `json:"operate" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type McpServerConnectionTest struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type McpBindDomain struct {
|
type McpBindDomain struct {
|
||||||
Domain string `json:"domain" validate:"required"`
|
Domain string `json:"domain" validate:"required"`
|
||||||
SSLID uint `json:"sslID"`
|
SSLID uint `json:"sslID"`
|
||||||
|
|||||||
@@ -114,17 +114,22 @@ type NginxRedirectUpdate struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NginxBuildReq struct {
|
type NginxBuildReq struct {
|
||||||
TaskID string `json:"taskID" validate:"required"`
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
Mirror string `json:"mirror" validate:"required"`
|
Mirror string `json:"mirror" validate:"required"`
|
||||||
|
Modules []string `json:"modules"`
|
||||||
|
Force bool `json:"force"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NginxModuleUpdate struct {
|
type NginxModuleUpdate struct {
|
||||||
Operate string `json:"operate" validate:"required,oneof=create delete update"`
|
Operate string `json:"operate" validate:"required,oneof=create delete update"`
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Script string `json:"script"`
|
Script string `json:"script"`
|
||||||
Packages string `json:"packages"`
|
Packages string `json:"packages"`
|
||||||
Enable bool `json:"enable"`
|
Enable bool `json:"enable"`
|
||||||
Params string `json:"params"`
|
Params string `json:"params"`
|
||||||
|
BuildMode string `json:"buildMode" validate:"omitempty,oneof=dynamic static"`
|
||||||
|
Provider string `json:"provider" validate:"omitempty,oneof=local prebuilt"`
|
||||||
|
LoadOrder int `json:"loadOrder" validate:"omitempty,min=0,max=9999"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NginxOperateReq struct {
|
type NginxOperateReq struct {
|
||||||
|
|||||||
@@ -21,13 +21,14 @@ type RuntimeCreate struct {
|
|||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
CodeDir string `json:"codeDir"`
|
CodeDir string `json:"codeDir"`
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
|
||||||
Params map[string]interface{} `json:"params"`
|
Params map[string]interface{} `json:"params"`
|
||||||
NodeConfig
|
NodeConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeConfig struct {
|
type NodeConfig struct {
|
||||||
Install bool `json:"install"`
|
Install *bool `json:"install"`
|
||||||
Clean bool `json:"clean"`
|
Clean bool `json:"clean"`
|
||||||
ExposedPorts []ExposedPort `json:"exposedPorts"`
|
ExposedPorts []ExposedPort `json:"exposedPorts"`
|
||||||
Environments []Environment `json:"environments"`
|
Environments []Environment `json:"environments"`
|
||||||
@@ -42,12 +43,14 @@ type Environment struct {
|
|||||||
type Volume struct {
|
type Volume struct {
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
Target string `json:"target"`
|
Target string `json:"target"`
|
||||||
|
Mode string `json:"mode"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExposedPort struct {
|
type ExposedPort struct {
|
||||||
HostPort int `json:"hostPort"`
|
HostPort int `json:"hostPort"`
|
||||||
ContainerPort int `json:"containerPort"`
|
ContainerPort int `json:"containerPort"`
|
||||||
HostIP string `json:"hostIP"`
|
HostIP string `json:"hostIP"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExtraHost struct {
|
type ExtraHost struct {
|
||||||
@@ -56,19 +59,22 @@ type ExtraHost struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RuntimeDelete struct {
|
type RuntimeDelete struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
ForceDelete bool `json:"forceDelete"`
|
ForceDelete bool `json:"forceDelete"`
|
||||||
|
DeleteImage bool `json:"deleteImage"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RuntimeUpdate struct {
|
type RuntimeUpdate struct {
|
||||||
Name string `json:"name"`
|
AppDetailID uint `json:"appDetailId"`
|
||||||
ID uint `json:"id"`
|
Name string `json:"name"`
|
||||||
Image string `json:"image"`
|
ID uint `json:"id"`
|
||||||
Version string `json:"version"`
|
Image string `json:"image"`
|
||||||
Rebuild bool `json:"rebuild"`
|
Version string `json:"version"`
|
||||||
Source string `json:"source"`
|
Rebuild bool `json:"rebuild"`
|
||||||
CodeDir string `json:"codeDir"`
|
Source string `json:"source"`
|
||||||
Remark string `json:"remark"`
|
CodeDir string `json:"codeDir"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
|
||||||
Params map[string]interface{} `json:"params"`
|
Params map[string]interface{} `json:"params"`
|
||||||
NodeConfig
|
NodeConfig
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
package request
|
|
||||||
@@ -34,6 +34,8 @@ type WebsiteCreate struct {
|
|||||||
|
|
||||||
SiteDir string `json:"siteDir"`
|
SiteDir string `json:"siteDir"`
|
||||||
|
|
||||||
|
TemplateOutputID uint `json:"templateOutputID"`
|
||||||
|
|
||||||
RuntimeConfig
|
RuntimeConfig
|
||||||
FtpConfig
|
FtpConfig
|
||||||
DataBaseConfig
|
DataBaseConfig
|
||||||
@@ -223,9 +225,14 @@ type WebsiteNginxUpdate struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteLogReq struct {
|
type WebsiteLogReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Operate string `json:"operate" validate:"required,oneof=enable disable delete"`
|
||||||
|
LogType string `json:"logType" validate:"required,oneof=access.log error.log"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteLogSearchReq struct {
|
||||||
ID uint `json:"id" validate:"required"`
|
ID uint `json:"id" validate:"required"`
|
||||||
Operate string `json:"operate" validate:"required"`
|
LogType string `json:"logType" validate:"required,oneof=access.log error.log"`
|
||||||
LogType string `json:"logType" validate:"required"`
|
|
||||||
Page int `json:"page"`
|
Page int `json:"page"`
|
||||||
PageSize int `json:"pageSize"`
|
PageSize int `json:"pageSize"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ type WebsiteSSLSearch struct {
|
|||||||
dto.PageInfo
|
dto.PageInfo
|
||||||
AcmeAccountID string `json:"acmeAccountID"`
|
AcmeAccountID string `json:"acmeAccountID"`
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
OrderBy string `json:"orderBy" validate:"omitempty,oneof=created_at expire_date"`
|
OrderBy string `json:"orderBy" validate:"omitempty,oneof=created_at updated_at expire_date"`
|
||||||
Order string `json:"order" validate:"omitempty,oneof=null ascending descending"`
|
Order string `json:"order" validate:"omitempty,oneof=null ascending descending"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ type WebsiteSSLObtain struct {
|
|||||||
type WebsiteAcmeAccountCreate struct {
|
type WebsiteAcmeAccountCreate struct {
|
||||||
Email string `json:"email" validate:"required"`
|
Email string `json:"email" validate:"required"`
|
||||||
Type string `json:"type" validate:"required,oneof=letsencrypt zerossl buypass google custom"`
|
Type string `json:"type" validate:"required,oneof=letsencrypt zerossl buypass google custom"`
|
||||||
KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"`
|
KeyType string `json:"keyType" validate:"required,oneof=EC256 EC384 RSA2048 RSA3072 RSA4096 RSA8192"`
|
||||||
EabKid string `json:"eabKid"`
|
EabKid string `json:"eabKid"`
|
||||||
EabHmacKey string `json:"eabHmacKey"`
|
EabHmacKey string `json:"eabHmacKey"`
|
||||||
UseProxy bool `json:"useProxy"`
|
UseProxy bool `json:"useProxy"`
|
||||||
@@ -126,6 +126,16 @@ type WebsiteSSLUpload struct {
|
|||||||
Type string `json:"type" validate:"required,oneof=paste local"`
|
Type string `json:"type" validate:"required,oneof=paste local"`
|
||||||
SSLID uint `json:"sslID"`
|
SSLID uint `json:"sslID"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
PushNode bool `json:"pushNode"`
|
||||||
|
Nodes string `json:"nodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteSSLPush struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
PushNode bool `json:"pushNode"`
|
||||||
|
Nodes string `json:"nodes"`
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
|
Sync bool `json:"sync"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteCASearch struct {
|
type WebsiteCASearch struct {
|
||||||
@@ -138,7 +148,7 @@ type WebsiteCACreate struct {
|
|||||||
Organization string `json:"organization" validate:"required"`
|
Organization string `json:"organization" validate:"required"`
|
||||||
OrganizationUint string `json:"organizationUint"`
|
OrganizationUint string `json:"organizationUint"`
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"`
|
KeyType string `json:"keyType" validate:"required,oneof=EC256 EC384 RSA2048 RSA3072 RSA4096 RSA8192"`
|
||||||
Province string `json:"province" `
|
Province string `json:"province" `
|
||||||
City string `json:"city"`
|
City string `json:"city"`
|
||||||
}
|
}
|
||||||
@@ -146,7 +156,7 @@ type WebsiteCACreate struct {
|
|||||||
type WebsiteCAObtain struct {
|
type WebsiteCAObtain struct {
|
||||||
ID uint `json:"id" validate:"required"`
|
ID uint `json:"id" validate:"required"`
|
||||||
Domains string `json:"domains" validate:"required"`
|
Domains string `json:"domains" validate:"required"`
|
||||||
KeyType string `json:"keyType" validate:"required,oneof=P256 P384 2048 3072 4096 8192"`
|
KeyType string `json:"keyType" validate:"required,oneof=EC256 EC384 RSA2048 RSA3072 RSA4096 RSA8192"`
|
||||||
Time int `json:"time" validate:"required"`
|
Time int `json:"time" validate:"required"`
|
||||||
Unit string `json:"unit" validate:"required"`
|
Unit string `json:"unit" validate:"required"`
|
||||||
PushDir bool `json:"pushDir"`
|
PushDir bool `json:"pushDir"`
|
||||||
@@ -157,6 +167,8 @@ type WebsiteCAObtain struct {
|
|||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
ExecShell bool `json:"execShell"`
|
ExecShell bool `json:"execShell"`
|
||||||
Shell string `json:"shell"`
|
Shell string `json:"shell"`
|
||||||
|
PushNode bool `json:"pushNode"`
|
||||||
|
Nodes string `json:"nodes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteCARenew struct {
|
type WebsiteCARenew struct {
|
||||||
@@ -167,4 +179,6 @@ type WebsiteSSLFileUpload struct {
|
|||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
SSLID uint64 `json:"sslID"`
|
SSLID uint64 `json:"sslID"`
|
||||||
|
PushNode bool `json:"pushNode"`
|
||||||
|
Nodes string `json:"nodes"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WebsiteTemplateSearch struct {
|
||||||
|
dto.PageInfo
|
||||||
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteTemplateCreate struct {
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=single multi"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
FilePath string `json:"filePath"`
|
||||||
|
Variables string `json:"variables"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteTemplateUpdate struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=single multi"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
FilePath string `json:"filePath"`
|
||||||
|
Variables string `json:"variables"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteTemplateOutputSearch struct {
|
||||||
|
dto.PageInfo
|
||||||
|
TemplateID uint `json:"templateID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteTemplateOutputCreate struct {
|
||||||
|
TemplateID uint `json:"templateID" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
VariableValues map[string]string `json:"variableValues"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsitePreviewReq struct {
|
||||||
|
TemplateID uint `json:"templateID" validate:"required"`
|
||||||
|
VariableValues map[string]string `json:"variableValues"`
|
||||||
|
}
|
||||||
@@ -104,34 +104,36 @@ type AppDetail struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AppInstallDTO struct {
|
type AppInstallDTO struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
AppID uint `json:"appID"`
|
AppID uint `json:"appID"`
|
||||||
AppDetailID uint `json:"appDetailID"`
|
AppDetailID uint `json:"appDetailID"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
HttpPort int `json:"httpPort"`
|
HttpPort int `json:"httpPort"`
|
||||||
HttpsPort int `json:"httpsPort"`
|
HttpsPort int `json:"httpsPort"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
CanUpdate bool `json:"canUpdate"`
|
CanUpdate bool `json:"canUpdate"`
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
AppName string `json:"appName"`
|
AppName string `json:"appName"`
|
||||||
Ready int `json:"ready"`
|
Ready int `json:"ready"`
|
||||||
Total int `json:"total"`
|
Total int `json:"total"`
|
||||||
AppKey string `json:"appKey"`
|
AppKey string `json:"appKey"`
|
||||||
AppType string `json:"appType"`
|
AppType string `json:"appType"`
|
||||||
AppStatus string `json:"appStatus"`
|
AppStatus string `json:"appStatus"`
|
||||||
DockerCompose string `json:"dockerCompose"`
|
DockerCompose string `json:"dockerCompose"`
|
||||||
WebUI string `json:"webUI"`
|
WebUI string `json:"webUI"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
Favorite bool `json:"favorite"`
|
Favorite bool `json:"favorite"`
|
||||||
SortOrder int `json:"sortOrder"`
|
SortOrder int `json:"sortOrder"`
|
||||||
App AppDetail `json:"app"`
|
App AppDetail `json:"app"`
|
||||||
Container string `json:"container"`
|
Container string `json:"container"`
|
||||||
IsEdit bool `json:"isEdit"`
|
IsEdit bool `json:"isEdit"`
|
||||||
LinkDB bool `json:"linkDB"`
|
LinkDB bool `json:"linkDB"`
|
||||||
ServiceName string `json:"serviceName"`
|
ResourceKeys []string `json:"resourceKeys"`
|
||||||
|
ServiceName string `json:"serviceName"`
|
||||||
|
Env map[string]interface{} `json:"env"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppInstallInfo struct {
|
type AppInstallInfo struct {
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package response
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type FileHistoryInfo struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
FileID string `json:"fileId"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
CurrentPath string `json:"currentPath"`
|
||||||
|
PreviousID uint `json:"previousId"`
|
||||||
|
SourcePath string `json:"sourcePath"`
|
||||||
|
TargetPath string `json:"targetPath"`
|
||||||
|
FileName string `json:"fileName"`
|
||||||
|
Extension string `json:"extension"`
|
||||||
|
FileMode string `json:"fileMode"`
|
||||||
|
Operation string `json:"operation"`
|
||||||
|
Deleted bool `json:"deleted"`
|
||||||
|
ContentSize int64 `json:"contentSize"`
|
||||||
|
ContentSHA string `json:"contentSHA"`
|
||||||
|
StoragePath string `json:"storagePath,omitempty"`
|
||||||
|
Content string `json:"content,omitempty"`
|
||||||
|
CurrentContent string `json:"currentContent,omitempty"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
UpdatedAt time.Time `json:"updatedAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileHistorySettingInfo struct {
|
||||||
|
Enable string `json:"enable"`
|
||||||
|
MaxPerPath int `json:"maxPerPath"`
|
||||||
|
DiskQuotaMB int `json:"diskQuotaMB"`
|
||||||
|
}
|
||||||
@@ -16,6 +16,12 @@ type McpServerDTO struct {
|
|||||||
Volumes []request.Volume `json:"volumes"`
|
Volumes []request.Volume `json:"volumes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type McpServerStatusDTO struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
type McpBindDomainRes struct {
|
type McpBindDomainRes struct {
|
||||||
Domain string `json:"domain"`
|
Domain string `json:"domain"`
|
||||||
SSLID uint `json:"sslID"`
|
SSLID uint `json:"sslID"`
|
||||||
@@ -24,3 +30,11 @@ type McpBindDomainRes struct {
|
|||||||
WebsiteID uint `json:"websiteID"`
|
WebsiteID uint `json:"websiteID"`
|
||||||
ConnUrl string `json:"connUrl"`
|
ConnUrl string `json:"connUrl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type McpServerConnectionTestRes struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Endpoint string `json:"endpoint"`
|
||||||
|
OutputTransport string `json:"outputTransport"`
|
||||||
|
ProtocolVersion string `json:"protocolVersion,omitempty"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,17 @@ type NginxParam struct {
|
|||||||
Params []string `json:"params"`
|
Params []string `json:"params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NginxBrotliRes carries the brotli settings together with where they live.
|
||||||
|
// ManagedExternally is true when the user defined brotli by hand, in which
|
||||||
|
// case the panel only reports the values and must not write its own copy.
|
||||||
|
// ManagedUnavailable is true when the panel could not wire the managed
|
||||||
|
// configuration into nginx.conf at all, so the reported values are inert.
|
||||||
|
type NginxBrotliRes struct {
|
||||||
|
Params []NginxParam `json:"params"`
|
||||||
|
ManagedExternally bool `json:"managedExternally"`
|
||||||
|
ManagedUnavailable bool `json:"managedUnavailable"`
|
||||||
|
}
|
||||||
|
|
||||||
type NginxAuthRes struct {
|
type NginxAuthRes struct {
|
||||||
Enable bool `json:"enable"`
|
Enable bool `json:"enable"`
|
||||||
Items []dto.NginxAuth `json:"items"`
|
Items []dto.NginxAuth `json:"items"`
|
||||||
@@ -69,16 +80,25 @@ type NginxProxyCache struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NginxModule struct {
|
type NginxModule struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Script string `json:"script"`
|
Custom bool `json:"custom"`
|
||||||
Packages string `json:"packages"`
|
Script string `json:"script"`
|
||||||
Params string `json:"params"`
|
Packages string `json:"packages"`
|
||||||
Enable bool `json:"enable"`
|
Params string `json:"params"`
|
||||||
|
Enable bool `json:"enable"`
|
||||||
|
BuildMode string `json:"buildMode"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
LoadOrder int `json:"loadOrder"`
|
||||||
|
BuildStatus string `json:"buildStatus"`
|
||||||
|
LoadStatus string `json:"loadStatus"`
|
||||||
|
Artifacts []dto.NginxModuleArtifact `json:"artifacts"`
|
||||||
|
LastError string `json:"lastError"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NginxBuildConfig struct {
|
type NginxBuildConfig struct {
|
||||||
Mirror string `json:"mirror"`
|
Mirror string `json:"mirror"`
|
||||||
Modules []NginxModule `json:"modules"`
|
DynamicSupported bool `json:"dynamicSupported"`
|
||||||
|
Modules []NginxModule `json:"modules"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NginxConfigRes struct {
|
type NginxConfigRes struct {
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package response
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WebsiteTemplateDTO struct {
|
||||||
|
model.WebsiteTemplate
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteTemplateOutputDTO struct {
|
||||||
|
model.WebsiteTemplateOutput
|
||||||
|
TemplateName string `json:"templateName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsitePreviewDTO struct {
|
||||||
|
HTML string `json:"html"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type RuntimeDiagnosticsSummary struct {
|
||||||
|
RSS uint64 `json:"rss"`
|
||||||
|
HeapAlloc uint64 `json:"heapAlloc"`
|
||||||
|
HeapObjects uint64 `json:"heapObjects"`
|
||||||
|
Goroutines int `json:"goroutines"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RuntimeGoroutineGroup struct {
|
||||||
|
State string `json:"state"`
|
||||||
|
Top string `json:"top"`
|
||||||
|
Count int `json:"count"`
|
||||||
|
Stack []string `json:"stack"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RuntimeGoroutineSnapshot struct {
|
||||||
|
Total int `json:"total"`
|
||||||
|
GroupCount int `json:"groupCount"`
|
||||||
|
Truncated bool `json:"truncated"`
|
||||||
|
CapturedAt time.Time `json:"capturedAt"`
|
||||||
|
Goroutines []RuntimeGoroutineGroup `json:"goroutines"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RuntimeProfileCreate struct {
|
||||||
|
Type string `json:"type" validate:"required,oneof=cpu heap goroutine mutex block"`
|
||||||
|
Duration int `json:"duration" validate:"omitempty,min=5,max=30"`
|
||||||
|
}
|
||||||
@@ -23,7 +23,10 @@ type SettingInfo struct {
|
|||||||
AppStoreLastModified string `json:"appStoreLastModified"`
|
AppStoreLastModified string `json:"appStoreLastModified"`
|
||||||
AppStoreSyncStatus string `json:"appStoreSyncStatus"`
|
AppStoreSyncStatus string `json:"appStoreSyncStatus"`
|
||||||
|
|
||||||
FileRecycleBin string `json:"fileRecycleBin"`
|
FileRecycleBin string `json:"fileRecycleBin"`
|
||||||
|
LocalSSHConnShow string `json:"localSSHConnShow"`
|
||||||
|
|
||||||
|
FirewallPortWhiteList string `json:"firewallPortWhiteList"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SettingUpdate struct {
|
type SettingUpdate struct {
|
||||||
@@ -31,6 +34,11 @@ type SettingUpdate struct {
|
|||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentSettingUpdate struct {
|
||||||
|
Key string `json:"key" validate:"required,oneof=SystemIP DockerSockPath FileRecycleBin"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
type SyncTime struct {
|
type SyncTime struct {
|
||||||
NtpSite string `json:"ntpSite" validate:"required"`
|
NtpSite string `json:"ntpSite" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ type RootCertOperate struct {
|
|||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
EncryptionMode string `json:"encryptionMode" validate:"required,oneof=rsa ed25519 ecdsa dsa"`
|
EncryptionMode string `json:"encryptionMode"`
|
||||||
PassPhrase string `json:"passPhrase"`
|
PassPhrase string `json:"passPhrase"`
|
||||||
PublicKey string `json:"publicKey"`
|
PublicKey string `json:"publicKey"`
|
||||||
PrivateKey string `json:"privateKey"`
|
PrivateKey string `json:"privateKey"`
|
||||||
@@ -57,8 +57,10 @@ type SSHConfUpdate struct {
|
|||||||
}
|
}
|
||||||
type SearchSSHLog struct {
|
type SearchSSHLog struct {
|
||||||
PageInfo
|
PageInfo
|
||||||
Info string `json:"info"`
|
Info string `json:"info"`
|
||||||
Status string `json:"Status" validate:"required,oneof=Success Failed All"`
|
Status string `json:"Status" validate:"required,oneof=Success Failed All"`
|
||||||
|
StartTime time.Time `json:"startTime"`
|
||||||
|
EndTime time.Time `json:"endTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SSHHistory struct {
|
type SSHHistory struct {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
type TerminalSessionClose struct {
|
||||||
|
ID string `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TerminalSessionRevoke struct {
|
||||||
|
Scope string `json:"scope" validate:"required,oneof=auth_session user all"`
|
||||||
|
UserID string `json:"userId"`
|
||||||
|
AuthSessionID string `json:"authSessionId"`
|
||||||
|
}
|
||||||
@@ -2,14 +2,17 @@ package model
|
|||||||
|
|
||||||
type AgentAccount struct {
|
type AgentAccount struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
Provider string `json:"provider"`
|
Provider string `json:"provider"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
APIKey string `json:"apiKey"`
|
APIKey string `json:"apiKey"`
|
||||||
BaseURL string `json:"baseUrl"`
|
BaseURL string `json:"baseUrl"`
|
||||||
APIType string `json:"apiType"`
|
APIType string `json:"apiType"`
|
||||||
RememberAPIKey bool `json:"rememberApiKey"`
|
AuthMode string `json:"authMode"`
|
||||||
Verified bool `json:"verified"`
|
VerifyModel string `json:"verifyModel"`
|
||||||
Remark string `json:"remark"`
|
RememberAPIKey bool `json:"rememberApiKey"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
MasterAccountID uint `json:"masterAccountId" gorm:"index"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (AgentAccount) TableName() string {
|
func (AgentAccount) TableName() string {
|
||||||
|
|||||||
@@ -2,14 +2,10 @@ package model
|
|||||||
|
|
||||||
type AgentAccountModel struct {
|
type AgentAccountModel struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
AccountID uint `json:"accountId" gorm:"index"`
|
AccountID uint `json:"accountId" gorm:"index"`
|
||||||
Model string `json:"model" gorm:"index"`
|
Model string `json:"model" gorm:"index"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ContextWindow int `json:"contextWindow"`
|
SortOrder int `json:"sortOrder" gorm:"index"`
|
||||||
MaxTokens int `json:"maxTokens"`
|
|
||||||
Reasoning bool `json:"reasoning"`
|
|
||||||
Input string `json:"input" gorm:"type:text"`
|
|
||||||
SortOrder int `json:"sortOrder" gorm:"index"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (AgentAccountModel) TableName() string {
|
func (AgentAccountModel) TableName() string {
|
||||||
|
|||||||
+31
-10
@@ -1,5 +1,12 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
type Alert struct {
|
type Alert struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
@@ -9,17 +16,20 @@ type Alert struct {
|
|||||||
Count uint `gorm:"type:integer;not null" json:"count"`
|
Count uint `gorm:"type:integer;not null" json:"count"`
|
||||||
Project string `gorm:"type:varchar(64)" json:"project"`
|
Project string `gorm:"type:varchar(64)" json:"project"`
|
||||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||||
Method string `gorm:"type:varchar(64);not null" json:"method"`
|
Method string `gorm:"type:text;not null" json:"method"`
|
||||||
SendCount uint `gorm:"type:integer" json:"sendCount"`
|
SendCount uint `gorm:"type:integer" json:"sendCount"`
|
||||||
AdvancedParams string `gorm:"type:longText" json:"advancedParams"`
|
AdvancedParams string `gorm:"type:longText" json:"advancedParams"`
|
||||||
|
CreateUser string `gorm:"type:varchar(256)" json:"createUser"`
|
||||||
|
UpdateUser string `gorm:"type:varchar(256)" json:"updateUser"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertTask struct {
|
type AlertTask struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||||
Quota string `gorm:"type:varchar(64)" json:"quota"`
|
Quota string `gorm:"type:varchar(64)" json:"quota"`
|
||||||
QuotaType string `gorm:"type:varchar(64)" json:"quotaType"`
|
QuotaType string `gorm:"type:varchar(64)" json:"quotaType"`
|
||||||
Method string `gorm:"type:varchar(64);not null;default:'sms'" json:"method"`
|
Method string `gorm:"type:varchar(128);not null;default:'sms'" json:"method"`
|
||||||
|
DeliveryLogID *uint `gorm:"uniqueIndex" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertLog struct {
|
type AlertLog struct {
|
||||||
@@ -34,15 +44,26 @@ type AlertLog struct {
|
|||||||
Message string `gorm:"type:varchar(256);" json:"message"`
|
Message string `gorm:"type:varchar(256);" json:"message"`
|
||||||
RecordId uint `gorm:"type:integer;" json:"recordId"`
|
RecordId uint `gorm:"type:integer;" json:"recordId"`
|
||||||
LicenseId string `gorm:"type:varchar(256);not null;" json:"licenseId" `
|
LicenseId string `gorm:"type:varchar(256);not null;" json:"licenseId" `
|
||||||
Method string `gorm:"type:varchar(64);not null;default:'sms'" json:"method"`
|
Method string `gorm:"type:varchar(128);not null;default:'sms'" json:"method"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertConfig struct {
|
type AlertConfig struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
UID string `gorm:"type:varchar(64);not null;uniqueIndex" json:"uid"`
|
||||||
Title string `gorm:"type:varchar(64);not null" json:"title"`
|
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
Title string `gorm:"type:varchar(64);not null" json:"title"`
|
||||||
Config string `gorm:"type:varchar(256);not null" json:"config"`
|
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||||
|
Config string `gorm:"type:text;not null" json:"config"`
|
||||||
|
SecretConfig string `gorm:"type:text;not null;default:''" json:"-"`
|
||||||
|
CreateUser string `gorm:"type:varchar(256)" json:"createUser"`
|
||||||
|
UpdateUser string `gorm:"type:varchar(256)" json:"updateUser"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AlertConfig) BeforeCreate(_ *gorm.DB) error {
|
||||||
|
if strings.TrimSpace(a.UID) == "" {
|
||||||
|
a.UID = uuid.NewString()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoginLog struct {
|
type LoginLog struct {
|
||||||
|
|||||||
@@ -31,4 +31,5 @@ type BackupRecord struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
Args string `gorm:"not null;default:''" json:"args"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ type ComposeTemplate struct {
|
|||||||
type Compose struct {
|
type Compose struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
|
IsPinned bool `json:"isPinned"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type DatabaseMongodb struct {
|
||||||
|
BaseModel
|
||||||
|
Name string `json:"name" gorm:"not null"`
|
||||||
|
From string `json:"from" gorm:"not null;default:local"`
|
||||||
|
MongodbName string `json:"mongodbName" gorm:"not null"`
|
||||||
|
Username string `json:"username" gorm:"not null"`
|
||||||
|
Password string `json:"password" gorm:"not null"`
|
||||||
|
IsDelete bool `json:"isDelete"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type DatabaseUser struct {
|
||||||
|
BaseModel
|
||||||
|
Type string `json:"type" gorm:"not null;uniqueIndex:idx_database_user"`
|
||||||
|
Database string `json:"database" gorm:"not null;uniqueIndex:idx_database_user"`
|
||||||
|
Username string `json:"username" gorm:"not null;uniqueIndex:idx_database_user"`
|
||||||
|
Host string `json:"host" gorm:"uniqueIndex:idx_database_user"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
IsDelete bool `json:"isDelete"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DatabaseUserGrant struct {
|
||||||
|
BaseModel
|
||||||
|
Type string `json:"type" gorm:"not null;uniqueIndex:idx_database_user_grant"`
|
||||||
|
Database string `json:"database" gorm:"not null;uniqueIndex:idx_database_user_grant"`
|
||||||
|
DBName string `json:"dbName" gorm:"not null;uniqueIndex:idx_database_user_grant"`
|
||||||
|
Username string `json:"username" gorm:"not null;uniqueIndex:idx_database_user_grant"`
|
||||||
|
Host string `json:"host" gorm:"not null;uniqueIndex:idx_database_user_grant"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type FileHistory struct {
|
||||||
|
BaseModel
|
||||||
|
FileID string `json:"fileId" gorm:"not null;index:idx_file_history_file_id_created_at,priority:1;index:idx_file_history_file_id_deleted_created_at,priority:1"`
|
||||||
|
Path string `json:"path" gorm:"not null;index:idx_file_history_path_created_at,priority:1;index:idx_file_history_path_hash_created_at,priority:1;index:idx_file_history_related_path,priority:1"`
|
||||||
|
PathHash string `json:"pathHash" gorm:"not null;index:idx_file_history_path_created_at,priority:2;index:idx_file_history_path_hash_created_at,priority:2"`
|
||||||
|
PreviousID uint `json:"previousId" gorm:"index"`
|
||||||
|
SourcePath string `json:"sourcePath" gorm:"index:idx_file_history_related_path,priority:2"`
|
||||||
|
TargetPath string `json:"targetPath" gorm:"index:idx_file_history_related_path,priority:3"`
|
||||||
|
FileName string `json:"fileName" gorm:"not null"`
|
||||||
|
Extension string `json:"extension"`
|
||||||
|
FileMode string `json:"fileMode"`
|
||||||
|
Operation string `json:"operation" gorm:"not null;index:idx_file_history_operation_created_at,priority:1"`
|
||||||
|
Deleted bool `json:"deleted" gorm:"not null;default:false;index:idx_file_history_deleted_created_at,priority:1;index:idx_file_history_file_id_deleted_created_at,priority:2"`
|
||||||
|
ContentSize int64 `json:"contentSize" gorm:"not null"`
|
||||||
|
ContentSHA string `json:"contentSHA" gorm:"not null;index"`
|
||||||
|
StoragePath string `json:"storagePath" gorm:"not null;uniqueIndex"`
|
||||||
|
}
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type Firewall struct {
|
|
||||||
BaseModel
|
|
||||||
|
|
||||||
Type string `json:"type"`
|
|
||||||
Port string `json:"port"` // Deprecated
|
|
||||||
Address string `json:"address"` // Deprecated
|
|
||||||
|
|
||||||
Chain string `json:"chain"`
|
|
||||||
Protocol string `json:"protocol"`
|
|
||||||
SrcIP string `json:"srcIP"`
|
|
||||||
SrcPort string `json:"srcPort"`
|
|
||||||
DstIP string `json:"dstIP"`
|
|
||||||
DstPort string `json:"dstPort"`
|
|
||||||
Strategy string `gorm:"not null" json:"strategy"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
|
||||||
@@ -8,4 +8,6 @@ type Ftp struct {
|
|||||||
Status string `gorm:"not null" json:"status"`
|
Status string `gorm:"not null" json:"status"`
|
||||||
Path string `gorm:"not null" json:"path"`
|
Path string `gorm:"not null" json:"path"`
|
||||||
Description string `gorm:"not null" json:"description"`
|
Description string `gorm:"not null" json:"description"`
|
||||||
|
UID uint `gorm:"column:uid;not null;default:1000" json:"-"`
|
||||||
|
GID uint `gorm:"column:gid;not null;default:1000" json:"-"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,7 @@ type McpServer struct {
|
|||||||
StreamableHttpPath string `json:"streamableHttpPath"`
|
StreamableHttpPath string `json:"streamableHttpPath"`
|
||||||
OutputTransport string `json:"outputTransport"`
|
OutputTransport string `json:"outputTransport"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
GatewayImage string `json:"gatewayImage"`
|
||||||
|
ProtocolVersion string `json:"protocolVersion"`
|
||||||
|
GatewayArgs string `json:"gatewayArgs"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
type MonitorBase struct {
|
type MonitorBase struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
Cpu float64 `json:"cpu"`
|
Cpu float64 `json:"cpu"`
|
||||||
@@ -33,14 +35,78 @@ type MonitorNetwork struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MonitorGPU struct {
|
type MonitorGPU struct {
|
||||||
|
MemoryUtil *float64 `json:"memoryUtil"`
|
||||||
|
MemoryActivity *float64 `json:"memoryActivity"`
|
||||||
|
EncoderUtil *float64 `json:"encoderUtil"`
|
||||||
|
DecoderUtil *float64 `json:"decoderUtil"`
|
||||||
|
JPEGUtil *float64 `json:"jpegUtil"`
|
||||||
|
OFAUtil *float64 `json:"ofaUtil"`
|
||||||
|
MediaUtil *float64 `json:"mediaUtil"`
|
||||||
|
ComputeUtil *float64 `json:"computeUtil"`
|
||||||
|
CopyUtil *float64 `json:"copyUtil"`
|
||||||
|
HotspotTemperature *float64 `json:"hotspotTemperature"`
|
||||||
|
FanRPM *float64 `json:"fanRPM"`
|
||||||
|
AICPUUtil *float64 `json:"aiCPUUtil"`
|
||||||
|
CtrlCPUUtil *float64 `json:"ctrlCPUUtil"`
|
||||||
|
DDRUsed *float64 `json:"ddrUsed"`
|
||||||
|
DDRTotal *float64 `json:"ddrTotal"`
|
||||||
|
HBMUsed *float64 `json:"hbmUsed"`
|
||||||
|
HBMTotal *float64 `json:"hbmTotal"`
|
||||||
|
DDRBandwidth *float64 `json:"ddrBandwidth"`
|
||||||
|
HBMBandwidth *float64 `json:"hbmBandwidth"`
|
||||||
|
MemoryBandwidth *float64 `json:"memoryBandwidth"`
|
||||||
|
MediaFrequency *float64 `json:"mediaFrequency"`
|
||||||
|
HugepagesUsed *float64 `json:"hugepagesUsed"`
|
||||||
|
HugepagesTotal *float64 `json:"hugepagesTotal"`
|
||||||
|
|
||||||
|
MemoryTemperature *float64 `json:"memoryTemperature"`
|
||||||
|
DeviceID string `json:"deviceID"`
|
||||||
|
DeviceType string `json:"deviceType"`
|
||||||
|
ProcessStatus string `json:"processStatus"`
|
||||||
|
Frequency *float64 `json:"frequency"`
|
||||||
|
MemoryFrequency *float64 `json:"memoryFrequency"`
|
||||||
|
IntervalSeconds int `json:"intervalSeconds"`
|
||||||
BaseModel
|
BaseModel
|
||||||
ProductName string `json:"productName"`
|
ProductName string `json:"productName"`
|
||||||
GPUUtil float64 `json:"gpuUtil"`
|
GPUUtil *float64 `json:"gpuUtil"`
|
||||||
Temperature float64 `json:"temperature"`
|
Temperature *float64 `json:"temperature"`
|
||||||
PowerDraw float64 `json:"powerDraw"`
|
PowerDraw *float64 `json:"powerDraw"`
|
||||||
MaxPowerLimit float64 `json:"maxPowerLimit"`
|
MaxPowerLimit *float64 `json:"maxPowerLimit"`
|
||||||
MemUsed float64 `json:"memUsed"`
|
MemUsed *float64 `json:"memUsed"`
|
||||||
MemTotal float64 `json:"memTotal"`
|
MemTotal *float64 `json:"memTotal"`
|
||||||
FanSpeed int `json:"fanSpeed"`
|
FanSpeed *float64 `json:"fanSpeed"`
|
||||||
Processes string `json:"processes"`
|
Processes string `json:"processes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MonitorVLLM struct {
|
||||||
|
ID uint `json:"-" gorm:"primarykey;autoIncrement"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
AppInstallID uint `json:"appInstallID"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
RawMetrics string `json:"-"`
|
||||||
|
HistogramDeltas string `json:"-"`
|
||||||
|
|
||||||
|
Running *float64 `json:"running"`
|
||||||
|
Waiting *float64 `json:"waiting"`
|
||||||
|
CacheUsage *float64 `json:"cacheUsage"`
|
||||||
|
PromptThroughput *float64 `json:"promptThroughput"`
|
||||||
|
GenerationThroughput *float64 `json:"generationThroughput"`
|
||||||
|
RequestThroughput *float64 `json:"requestThroughput"`
|
||||||
|
TimeToFirstToken *float64 `json:"timeToFirstToken"`
|
||||||
|
TimePerOutputToken *float64 `json:"timePerOutputToken"`
|
||||||
|
RequestLatency *float64 `json:"requestLatency"`
|
||||||
|
PrefillTime *float64 `json:"prefillTime"`
|
||||||
|
DecodeTime *float64 `json:"decodeTime"`
|
||||||
|
TimeToFirstTokenP50 *float64 `json:"timeToFirstTokenP50"`
|
||||||
|
TimeToFirstTokenP90 *float64 `json:"timeToFirstTokenP90"`
|
||||||
|
TimeToFirstTokenP95 *float64 `json:"timeToFirstTokenP95"`
|
||||||
|
TimeToFirstTokenP99 *float64 `json:"timeToFirstTokenP99"`
|
||||||
|
TimePerOutputTokenP50 *float64 `json:"timePerOutputTokenP50"`
|
||||||
|
TimePerOutputTokenP90 *float64 `json:"timePerOutputTokenP90"`
|
||||||
|
TimePerOutputTokenP95 *float64 `json:"timePerOutputTokenP95"`
|
||||||
|
TimePerOutputTokenP99 *float64 `json:"timePerOutputTokenP99"`
|
||||||
|
RequestLatencyP50 *float64 `json:"requestLatencyP50"`
|
||||||
|
RequestLatencyP90 *float64 `json:"requestLatencyP90"`
|
||||||
|
RequestLatencyP95 *float64 `json:"requestLatencyP95"`
|
||||||
|
RequestLatencyP99 *float64 `json:"requestLatencyP99"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ type WebsiteAcmeAccount struct {
|
|||||||
Type string `gorm:"not null;default:letsencrypt" json:"type"`
|
Type string `gorm:"not null;default:letsencrypt" json:"type"`
|
||||||
EabKid string `json:"eabKid"`
|
EabKid string `json:"eabKid"`
|
||||||
EabHmacKey string `json:"eabHmacKey"`
|
EabHmacKey string `json:"eabHmacKey"`
|
||||||
KeyType string `gorm:"not null;default:2048" json:"keyType"`
|
KeyType string `gorm:"not null;default:RSA2048" json:"keyType"`
|
||||||
UseProxy bool `gorm:"default:false" json:"useProxy"`
|
UseProxy bool `gorm:"default:false" json:"useProxy"`
|
||||||
CaDirURL string `json:"caDirURL"`
|
CaDirURL string `json:"caDirURL"`
|
||||||
UseEAB bool `json:"useEAB"`
|
UseEAB bool `json:"useEAB"`
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user