mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-10 16:00:31 +00:00
Compare commits
733
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a888d289f | ||
|
|
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 | ||
|
|
6ea07421ac | ||
|
|
326d52e311 | ||
|
|
6e3f751dba | ||
|
|
6982fd22d4 | ||
|
|
04fd456b63 | ||
|
|
bea4bfeee8 | ||
|
|
fa6157b610 | ||
|
|
30af26779c | ||
|
|
16d5c00b9a | ||
|
|
3f14f8f30e | ||
|
|
218f92a960 | ||
|
|
75be8d3a23 | ||
|
|
e2d8125b3d | ||
|
|
7ec3c517c2 | ||
|
|
e186e30d8c | ||
|
|
67a8ba2421 | ||
|
|
24fc15beaf | ||
|
|
c1fe70b53e | ||
|
|
30bf4a8d46 | ||
|
|
9e501ce02b | ||
|
|
d74692a68b | ||
|
|
57fd80fb3d | ||
|
|
39d2c34682 | ||
|
|
3e4a48c892 | ||
|
|
2c8f8f32fd | ||
|
|
3cf6d9ac51 | ||
|
|
64d8fe8bd0 | ||
|
|
8129260508 | ||
|
|
a40786a7fa | ||
|
|
368193a777 | ||
|
|
61ef725892 | ||
|
|
0c49c41085 | ||
|
|
2a498de96e | ||
|
|
d055cbb053 | ||
|
|
4b3f8a9fd0 | ||
|
|
4c26945910 | ||
|
|
55b6104b56 | ||
|
|
12dc8aae81 | ||
|
|
37e2b93693 | ||
|
|
62daf1e019 | ||
|
|
f5e75d4bfa | ||
|
|
32fed45c1e | ||
|
|
8b7597abef | ||
|
|
01fb9a461b | ||
|
|
bc022a4d21 | ||
|
|
973cab2837 | ||
|
|
5ce155eee6 | ||
|
|
d83b49cc70 | ||
|
|
ec981f8153 | ||
|
|
b2853277e7 | ||
|
|
f573a0fa0e | ||
|
|
f787734feb | ||
|
|
52778f520a | ||
|
|
b5aba18248 | ||
|
|
bc9882da50 | ||
|
|
0ba7e98e8d | ||
|
|
e6dc44d135 | ||
|
|
a9f30e9f5f | ||
|
|
f3bf9d0905 | ||
|
|
05ea384a00 | ||
|
|
62c50aafe1 | ||
|
|
6e052b8ef2 | ||
|
|
1d40bdc11b | ||
|
|
3b62197f29 | ||
|
|
2d78ca5a86 | ||
|
|
a9b65b7ce5 | ||
|
|
291b40a45d | ||
|
|
a959da7d44 | ||
|
|
26c4e8323f | ||
|
|
0534badce7 | ||
|
|
594d818db0 | ||
|
|
04dceb93a7 | ||
|
|
7b554c0d61 | ||
|
|
bb642cd8a8 | ||
|
|
40249b527d | ||
|
|
74ff7ddc19 | ||
|
|
096ec8edc7 | ||
|
|
0d19069059 | ||
|
|
0da833302b | ||
|
|
4a69cf0ff5 | ||
|
|
39704ef4e5 | ||
|
|
e52cfeeb78 | ||
|
|
476429005c | ||
|
|
6fb41dc711 | ||
|
|
2cb2058cfa | ||
|
|
8533dd1d33 | ||
|
|
0cfbcd25fc | ||
|
|
b91ca8bdb3 | ||
|
|
72764863bc | ||
|
|
a7b9fd0181 | ||
|
|
2b3164fe82 | ||
|
|
2c6307049a | ||
|
|
acc1b9270f | ||
|
|
60e4143525 | ||
|
|
99bcd6d059 | ||
|
|
c4259dd004 | ||
|
|
1c5a4bc978 | ||
|
|
42f6e9a9a6 | ||
|
|
569363530a | ||
|
|
ec9eba0b9a | ||
|
|
5376d54089 | ||
|
|
c10e5747b0 | ||
|
|
5a80931a49 | ||
|
|
f541379daa | ||
|
|
0018335d64 | ||
|
|
df90286253 | ||
|
|
8dfa7945d7 | ||
|
|
1f4292d9cf | ||
|
|
e635a7beba | ||
|
|
59c657e403 | ||
|
|
ff8f79ed52 | ||
|
|
57a7edf481 | ||
|
|
bbd33c66f1 | ||
|
|
b05ed1a0ca | ||
|
|
b645c4edb4 | ||
|
|
9f61aac8be | ||
|
|
11d78644ee | ||
|
|
b96428e1d6 | ||
|
|
6432c35b1a | ||
|
|
fa843f0940 | ||
|
|
5c7ffc561b | ||
|
|
c2f0c8c6ac | ||
|
|
5bf6d17451 | ||
|
|
7f799004c3 | ||
|
|
c68251cada | ||
|
|
23e7d03d8d | ||
|
|
5085db7a2f | ||
|
|
a9cf7a7d1d | ||
|
|
cf18995182 | ||
|
|
24d7dc0786 | ||
|
|
142c9b9a71 | ||
|
|
f3c7603f6e | ||
|
|
db26da1700 | ||
|
|
d5ff59f4e7 | ||
|
|
85b88db99e | ||
|
|
f7053934b5 | ||
|
|
bf1339bb40 | ||
|
|
43c5e62c23 | ||
|
|
28634ce631 | ||
|
|
72263dfdda | ||
|
|
479d36e25f | ||
|
|
2f3ad3537e | ||
|
|
2dfe5096f0 | ||
|
|
4375722aef | ||
|
|
bde4d06842 | ||
|
|
17a486b2c4 | ||
|
|
8499c09571 | ||
|
|
7cb70f785a | ||
|
|
f3781320de | ||
|
|
869ee75020 | ||
|
|
1d5a26373d | ||
|
|
176fd0f8ad | ||
|
|
341a55ae63 | ||
|
|
fb87cf545f | ||
|
|
6db2a9352e | ||
|
|
21826bcc1a | ||
|
|
eedbc2e95c | ||
|
|
46763df7bb | ||
|
|
175162753e | ||
|
|
d114933fe9 | ||
|
|
432412e596 | ||
|
|
1b577e3d41 | ||
|
|
eda9641d35 | ||
|
|
6808e4892c | ||
|
|
0d71cd4db2 | ||
|
|
b6b3304a71 | ||
|
|
59a0a573ed | ||
|
|
e82d686940 | ||
|
|
b48bb88aa1 | ||
|
|
5ce9ec5b64 | ||
|
|
740f3549ad | ||
|
|
aa8a9e8b1e | ||
|
|
14218e3495 | ||
|
|
c526eb2962 | ||
|
|
1ff8292be4 | ||
|
|
d4394616af | ||
|
|
462ca6b373 | ||
|
|
657c3ad37a | ||
|
|
90d11a3b74 | ||
|
|
883f3db725 | ||
|
|
75da72c265 | ||
|
|
78eef15f5b | ||
|
|
735cf3cc71 | ||
|
|
99c5d9a8b2 | ||
|
|
3a0d2039d0 | ||
|
|
98e2d6390a | ||
|
|
975e7f9f58 | ||
|
|
77c90a26f8 | ||
|
|
17cb12df8b | ||
|
|
c986b04667 | ||
|
|
754e016f20 | ||
|
|
f67ce75492 | ||
|
|
e236ca5607 | ||
|
|
10e74c4fe4 | ||
|
|
473c0a5ff2 | ||
|
|
7fbe6e4091 | ||
|
|
65dbb53a07 | ||
|
|
c21910c203 | ||
|
|
1728511bad | ||
|
|
e63f6672f8 | ||
|
|
7fa9754ce7 | ||
|
|
475e4ca629 | ||
|
|
32dee74edf | ||
|
|
6715559925 | ||
|
|
2f380c9f2f | ||
|
|
0aebb0d2db | ||
|
|
b7cf9aab2b | ||
|
|
ea2f1875bc | ||
|
|
83524940ed | ||
|
|
8c33eb8409 | ||
|
|
644655af86 | ||
|
|
8082f4d2ca | ||
|
|
3c896bc5f8 | ||
|
|
5c7ce6d8d4 | ||
|
|
222702f66b | ||
|
|
b3b3feb1b9 | ||
|
|
133140040b | ||
|
|
d70f903432 | ||
|
|
f77f305316 | ||
|
|
13b5908442 | ||
|
|
d1335db986 | ||
|
|
1e8836ad95 | ||
|
|
d155217ce3 | ||
|
|
9ddb996a44 | ||
|
|
226eccf5f1 | ||
|
|
4b2d6f0ef2 | ||
|
|
f1c9ad45a7 | ||
|
|
93489c85fa | ||
|
|
8cead06d7b | ||
|
|
625cd9f32f | ||
|
|
9aab3b42af | ||
|
|
6684cd57d7 | ||
|
|
00d95d6e19 | ||
|
|
36f03e5daf | ||
|
|
7c395a6bf8 | ||
|
|
e9a7cac5fd | ||
|
|
9f00b431d4 | ||
|
|
1705d44378 | ||
|
|
537e2c730c | ||
|
|
b4dc6b1ab0 | ||
|
|
1f22285cf4 | ||
|
|
1d546236e4 | ||
|
|
982e0bbd3e | ||
|
|
5a67a62733 | ||
|
|
961ebd30a1 | ||
|
|
9819546694 | ||
|
|
5c8d391a73 | ||
|
|
0e84b9a2a7 | ||
|
|
1f58da501e | ||
|
|
0041184a3e | ||
|
|
112468949d | ||
|
|
7e03e94460 | ||
|
|
fd9b299b14 | ||
|
|
37932d7fb2 | ||
|
|
f0f2087f54 | ||
|
|
f3de09e5d7 | ||
|
|
1a8c1613a4 | ||
|
|
5209275f28 | ||
|
|
924e59d948 | ||
|
|
87a39cab3a | ||
|
|
f9a70757a1 | ||
|
|
741acee393 | ||
|
|
c964a02088 | ||
|
|
ba71613ae6 | ||
|
|
5493b41381 | ||
|
|
c3f45d4787 | ||
|
|
a8a92da483 | ||
|
|
a77e61a861 | ||
|
|
e589728987 | ||
|
|
cc3cdef5f3 | ||
|
|
7101af0594 | ||
|
|
df6cda7143 | ||
|
|
62beb534d2 | ||
|
|
9a70bf1c2d | ||
|
|
6f4559c7cd | ||
|
|
8b2bcdc814 | ||
|
|
0f6ddf26fd | ||
|
|
ebe472a9db | ||
|
|
c1a87baad7 | ||
|
|
c7f185a184 | ||
|
|
4ca2ba5482 | ||
|
|
727b74895d | ||
|
|
6c3f56516f | ||
|
|
4833cf2d3c | ||
|
|
b5ca015632 | ||
|
|
1c82034111 | ||
|
|
e45d723f3d | ||
|
|
627e6852db | ||
|
|
1725767789 | ||
|
|
3e1f2b4934 | ||
|
|
140d20a21d | ||
|
|
6e933fc83c | ||
|
|
79ff565995 | ||
|
|
39691698c9 | ||
|
|
4bedddb557 | ||
|
|
f9547752f5 | ||
|
|
96b37cb024 | ||
|
|
30d874bc91 | ||
|
|
32bc8d922b | ||
|
|
a95d9aa27a | ||
|
|
7f4f5a0a47 | ||
|
|
65a7193bc6 | ||
|
|
64f79b4fdd | ||
|
|
31d2af554e | ||
|
|
e0f2910710 | ||
|
|
f89ab607b4 | ||
|
|
61fa07b8f2 | ||
|
|
9653df185a | ||
|
|
8f7d3df76d | ||
|
|
2aa89699c1 | ||
|
|
46b8d3bd80 | ||
|
|
8a7be481b0 | ||
|
|
21bd94d3a3 | ||
|
|
d337190b59 | ||
|
|
7073e83d94 | ||
|
|
537ff49c0b | ||
|
|
4b1f643c70 | ||
|
|
b8b873836d | ||
|
|
021334c2c8 | ||
|
|
635d86a1a5 | ||
|
|
607eae3ca8 | ||
|
|
66428c0a8e | ||
|
|
c0404a4ec5 | ||
|
|
77ef3b7096 | ||
|
|
498052f4c9 | ||
|
|
958c55eab8 | ||
|
|
d3cddd175a | ||
|
|
6cd130677e | ||
|
|
33b90e3979 | ||
|
|
e1e2b97e88 | ||
|
|
8e4e1dc749 | ||
|
|
1eb5830238 | ||
|
|
5db2ccbb22 | ||
|
|
47e04a14ad | ||
|
|
a13c58eb18 | ||
|
|
15d77ceb46 | ||
|
|
af8fa6763f | ||
|
|
ed66d22bdb | ||
|
|
5209db3abc | ||
|
|
35ea1a1d6c | ||
|
|
b0a053b397 | ||
|
|
a8b3390ce9 | ||
|
|
4266e39d84 | ||
|
|
5620b6e736 | ||
|
|
289e4190ff | ||
|
|
9250412296 | ||
|
|
9c5370508e | ||
|
|
a145bfdc5b | ||
|
|
db2b38eedb | ||
|
|
9303ee399f | ||
|
|
d64cb3dc58 | ||
|
|
62871acfbb | ||
|
|
7401906b03 | ||
|
|
5aa3c29684 | ||
|
|
91745f592f | ||
|
|
564333ea03 | ||
|
|
7b543ea5fe | ||
|
|
fc5e583481 | ||
|
|
1767b1a9c1 | ||
|
|
930c340e37 | ||
|
|
58531d3995 | ||
|
|
4b7c1390fb | ||
|
|
2337d6f13a | ||
|
|
cb8ecd55ed | ||
|
|
33ad31dba2 | ||
|
|
294c3f128b | ||
|
|
0899f4e9db | ||
|
|
788f4d8307 | ||
|
|
2451d6bed2 | ||
|
|
c547de875a | ||
|
|
ffead783aa | ||
|
|
d742c7d333 | ||
|
|
1025cd3535 | ||
|
|
de402ea724 | ||
|
|
3af07a42d6 | ||
|
|
e5b7e99cce | ||
|
|
365936bf57 | ||
|
|
2b7562f546 | ||
|
|
e7f4e312b9 | ||
|
|
98d3870477 | ||
|
|
b1ceb2e53d | ||
|
|
075d2468ea | ||
|
|
8b9e7aef4a | ||
|
|
15e499c1e9 | ||
|
|
55ccb9fe61 | ||
|
|
a5816f1dc9 | ||
|
|
95a613f59f | ||
|
|
6777941dee | ||
|
|
e55128b7fa | ||
|
|
9ac11002f8 | ||
|
|
1cc7bfb4a9 | ||
|
|
e59534e54f | ||
|
|
8c2368c1d2 | ||
|
|
8e8f181cae | ||
|
|
2fcab77565 | ||
|
|
d29f0c6c31 | ||
|
|
79f1b1458b | ||
|
|
b279ee6b82 | ||
|
|
c64a58d814 | ||
|
|
57c60ab3f8 | ||
|
|
e37d90d6e1 | ||
|
|
22055ed99a | ||
|
|
e263331b94 | ||
|
|
eb3d613e3d | ||
|
|
cc23444776 | ||
|
|
1931d3f262 | ||
|
|
79cbbbdf0a | ||
|
|
38cd785aa3 | ||
|
|
dabec3f87a | ||
|
|
6c94cb2bdf | ||
|
|
f67bdf0c22 | ||
|
|
6c51b31270 | ||
|
|
ef6e342737 | ||
|
|
ac0ef98dde | ||
|
|
523775e56b | ||
|
|
b6e741a150 | ||
|
|
54357fbe2b | ||
|
|
040dda5bec | ||
|
|
77b4d58fb8 | ||
|
|
0c9e551492 | ||
|
|
2ba1e2e22e | ||
|
|
d8a08a6c0c | ||
|
|
2c92226f88 | ||
|
|
cd9cb9b9c9 | ||
|
|
b2777055bc | ||
|
|
c8673b60bb | ||
|
|
21975dff2d | ||
|
|
6ab14185e0 | ||
|
|
1f70646952 | ||
|
|
c90ed9e873 | ||
|
|
e4ee07d36b | ||
|
|
8fb3e78554 | ||
|
|
01ab004876 | ||
|
|
6205eac51c | ||
|
|
d9a5418029 | ||
|
|
74a8e61f3e | ||
|
|
e18472f1a3 | ||
|
|
e3dea80cb7 | ||
|
|
50947f4ddc | ||
|
|
d302bc07b3 | ||
|
|
c6df20e565 | ||
|
|
6f9a1321d1 | ||
|
|
eb4eb31578 | ||
|
|
f8f5fcfca2 | ||
|
|
4e7b654090 | ||
|
|
e8059d3676 | ||
|
|
ffadc6721b | ||
|
|
e2e774d215 | ||
|
|
f23d3678fb | ||
|
|
dfade50bd8 | ||
|
|
d25b5f4f2a | ||
|
|
9a17bc74b0 | ||
|
|
015605526d | ||
|
|
099896dc96 | ||
|
|
aa1bc6fa8e | ||
|
|
f27a429fc5 |
@@ -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,47 +0,0 @@
|
|||||||
name: Create Release And Upload assets
|
|
||||||
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: '22.19.0'
|
|
||||||
- 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.24'
|
|
||||||
- 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
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
name: Create Release And Upload Cloudflare 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: '22.19.0'
|
|
||||||
- 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.24'
|
|
||||||
- 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 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
|
|
||||||
+21
-5
@@ -9,7 +9,6 @@ build/1panel-core
|
|||||||
|
|
||||||
# Mac
|
# Mac
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*/.DS_Store
|
|
||||||
|
|
||||||
# VS Code
|
# VS Code
|
||||||
.vscode
|
.vscode
|
||||||
@@ -41,15 +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/utils/xpack/xpack_xpack.go
|
agent/server/init_enterprise.go
|
||||||
|
agent/utils/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/utils/xpack/xpack_xpack.go
|
core/server/init_enterprise.go
|
||||||
xpack
|
core/utils/xpack/xpack.go
|
||||||
|
core/utils/xpack/enterprise.go
|
||||||
|
|
||||||
.history/
|
.history/
|
||||||
dist/
|
dist/
|
||||||
@@ -62,4 +69,13 @@ cmd/server/fileList.txt
|
|||||||
1Panel.code-workspace
|
1Panel.code-workspace
|
||||||
|
|
||||||
core/.golangci.yml
|
core/.golangci.yml
|
||||||
agent/.golangci.yml
|
agent/.golangci.yml
|
||||||
|
|
||||||
|
.opencode
|
||||||
|
openspec
|
||||||
|
CLAUDE.md
|
||||||
|
AGENTS.md
|
||||||
|
opencode.json
|
||||||
|
superpowers
|
||||||
|
.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,17 +1,23 @@
|
|||||||
<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>
|
||||||
<p align="center"><b>Top-Rated Web-based Linux Server Management Tool</b><br>Best VPS control panel<br>新一代的 Linux 服务器运维管理面板</p>
|
|
||||||
|
<h3 align="center">The open-source VPS control panel with native AI agent support</h3>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
Trusted by <strong>2,000,000+</strong> self-hosters worldwide
|
||||||
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://trendshift.io/repositories/2462" target="_blank"><img src="https://trendshift.io/api/badge/repositories/2462" alt="1Panel-dev%2F1Panel | Trendshift" style="width: 240px; height: auto;" /></a>
|
<a href="https://trendshift.io/repositories/2462" target="_blank"><img src="https://trendshift.io/api/badge/repositories/2462" alt="1Panel-dev%2F1Panel | Trendshift" style="width: 240px; height: auto;" /></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<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?utm_source=github.com&utm_medium=referral&utm_content=1Panel-dev/1Panel&utm_campaign=Badge_Grade_Dashboard"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></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" target="_blank">
|
<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>
|
||||||
<img src="https://img.shields.io/discord/1318846410149335080?logo=discord&labelColor=%20%235462eb&logoColor=%20%23f5f5f5&color=%20%235462eb"
|
|
||||||
alt="chat on 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><br>
|
<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>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="/README.md"><img alt="English" src="https://img.shields.io/badge/English-d9d9d9"></a>
|
<a href="/README.md"><img alt="English" src="https://img.shields.io/badge/English-d9d9d9"></a>
|
||||||
<a href="/docs/README.zh-Hans.md"><img alt="中文(简体)" src="https://img.shields.io/badge/中文(简体)-d9d9d9"></a>
|
<a href="/docs/README.zh-Hans.md"><img alt="中文(简体)" src="https://img.shields.io/badge/中文(简体)-d9d9d9"></a>
|
||||||
@@ -19,58 +25,91 @@
|
|||||||
<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><br>
|
<a href="/docs/README.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>
|
||||||
<a href="/docs/README.zh-Hant.md"><img alt="中文(繁體)" src="https://img.shields.io/badge/中文(繁體)-d9d9d9"></a>
|
<a href="/docs/README.zh-Hant.md"><img alt="中文(繁體)" src="https://img.shields.io/badge/中文(繁體)-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.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/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-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>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
------------------------------
|
---
|
||||||
|
|
||||||
1Panel is an open-source, modern web-based control panel for Linux server management.
|
## What is 1Panel?
|
||||||
|
|
||||||
- **Efficient Management**: Through a user-friendly web graphical interface, 1Panel enables users to effortlessly manage their Linux servers. Key features include host monitoring, file management, database administration, container management, LLMs management.
|
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.
|
||||||
- **Rapid Website Deployment**: With deep integration of the popular open-source website building software WordPress, 1Panel streamlines the process of domain binding and SSL certificate configuration, all achievable with just one click.
|
|
||||||
- **Application Store**: 1Panel curates a wide range of high-quality open-source tools and applications, facilitating easy installation and updates for its users.
|
👉 Watch the [2-minute introduction](https://www.youtube.com/watch?v=Jl_wqp-XA08)
|
||||||
- **Security and Reliability**: By leveraging containerization and secure application deployment practices, 1Panel minimizes vulnerability exposure. It further enhances security through integrated firewall management and log auditing capabilities.
|
|
||||||
- **One-Click Backup & Restore**: Data protection is made simple with 1Panel's one-click backup and restore functionality, supporting various cloud storage solutions to ensure data integrity and availability.
|
## Why 1Panel?
|
||||||
|
|
||||||
|
| | 1Panel | cPanel / Plesk | aaPanel | Webmin |
|
||||||
|
|--|--------|----------------|---------|--------|
|
||||||
|
| Free & open source | ✅ | ❌ | Partial | ✅ |
|
||||||
|
| Native AI agent runtime | ✅ | ❌ | ❌ | ❌ |
|
||||||
|
| One-click app marketplace | ✅ 165+ apps | ❌ | ✅ | ❌ |
|
||||||
|
| Modern UI (post-2020) | ✅ | ❌ | Partial | ❌ |
|
||||||
|
| Docker / container management | ✅ | ❌ | ❌ | ❌ |
|
||||||
|
| 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
|
||||||
|
|
||||||
Execute the script below and follow the prompts to install 1Panel:
|
> **Requirements:** Linux VPS (Debian / Ubuntu / CentOS / Rocky), 1 GB RAM, internet access.
|
||||||
|
> Takes ~60 seconds.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sSL https://resource.1panel.pro/quick_start.sh -o quick_start.sh && bash quick_start.sh
|
bash -c "$(curl -sSL https://resource.1panel.pro/v2/quick_start.sh)"
|
||||||
```
|
```
|
||||||
|
|
||||||
Please refer to our [documentation](https://docs.1panel.pro/quick_start/) for more details.
|
After installation, open `http://<your-server-ip>:<port>/<security-path>` in your browser.
|
||||||
|
Run `1pctl user-info` via SSH if you need to retrieve your access credentials.
|
||||||
中国用户请使用这个 [安装脚本](https://1panel.cn/docs/installation/online_installation/),其应用数量比国际版本更丰富。
|
|
||||||
|
|
||||||
## Screenshot
|
## Screenshot
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Pro Edition
|
||||||
|
|
||||||
|
1Panel OSS is free forever. Pro adds features built for teams and production workloads:
|
||||||
|
|
||||||
|
| Feature | OSS | Pro |
|
||||||
|
|---------|:---:|:---:|
|
||||||
|
| One-click app installs | ✅ | ✅ |
|
||||||
|
| AI agents (OpenClaw) | 1 agent | Unlimited |
|
||||||
|
| WAF & advanced security | Basic | ✅ |
|
||||||
|
| Website tamper protection | ❌ | ✅ |
|
||||||
|
| Website uptime monitoring | ❌ | ✅ |
|
||||||
|
| Multi-node management | ❌ | ✅ |
|
||||||
|
| Custom logo & theme | ❌ | ✅ |
|
||||||
|
| Priority support | ❌ | ✅ |
|
||||||
|
|
||||||
|
**From $80/year.** [Compare plans & start 30-day free trial →](https://1panel.pro/pricing)
|
||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
||||||
|
|
||||||
## Pro Edition
|
## Community & Support
|
||||||
|
|
||||||
Compared to the OSS Edition, 1Panel Pro Edition provides users with a wealth of enhanced features and technical support services. Enhanced features include WAF enhancement, website tamper protection, website monitoring, GPU monitoring, custom logo and theme color, etc. [Click to view the detailed introduction of the Pro Edition](https://1panel.pro/pricing).
|
- **Discord** — [Join the community](https://discord.gg/bUpUqWqdRr) for help, feature requests, and show-and-tell
|
||||||
|
- **Docs** — [1panel.pro/docs](https://1panel.pro/docs)
|
||||||
|
- **Issues** — [GitHub Issues](https://github.com/1Panel-dev/1Panel/issues) for bug reports
|
||||||
|
|
||||||
## Security Information
|
## Security
|
||||||
|
|
||||||
If you discover any security issues, please refer to [SECURITY.md](/SECURITY.md).
|
Found a vulnerability? Please read [SECURITY.md](/SECURITY.md) before disclosing.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
Licensed under the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.html).
|
||||||
|
|
||||||
<https://www.gnu.org/licenses/gpl-3.0.html>
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+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 {
|
||||||
|
|||||||
+159
-4
@@ -2,11 +2,24 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"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/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 +45,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 +67,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 +89,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 +124,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 +146,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 +161,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 +185,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 +200,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 +215,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 +236,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 +255,71 @@ 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 {
|
||||||
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,6 +333,14 @@ 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 {
|
||||||
|
|||||||
+51
-12
@@ -2,12 +2,12 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"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"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
"github.com/1Panel-dev/1Panel/agent/i18n"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/appicon"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -164,7 +164,7 @@ func (b *BaseApi) InstallApp(c *gin.Context) {
|
|||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
install, err := appService.Install(req)
|
install, err := appService.Install(req, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
@@ -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,24 +205,57 @@ 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
|
||||||
// @Router /apps/icon/:appId [get]
|
// @Router /apps/icon/:key [get]
|
||||||
func (b *BaseApi) GetAppIcon(c *gin.Context) {
|
func (b *BaseApi) GetAppIcon(c *gin.Context) {
|
||||||
appID, err := helper.GetIntParamByKey(c, "appID")
|
appKey, err := helper.GetStrParamByKey(c, "key")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.BadRequest(c, err)
|
helper.BadRequest(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
iconBytes, err := appService.GetAppIcon(appID)
|
iconBytes, filename, etag, err := appService.GetAppIcon(appKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.Header("Content-Type", "image/png")
|
|
||||||
c.Header("Cache-Control", "public, max-age=31536000, immutable")
|
if len(iconBytes) == 0 {
|
||||||
c.Header("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
|
c.Status(http.StatusNoContent)
|
||||||
c.Data(http.StatusOK, "image/png", iconBytes)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Header("Cache-Control", "public, max-age=2592000")
|
||||||
|
|
||||||
|
if etag != "" && filename != "" {
|
||||||
|
c.Header("ETag", etag)
|
||||||
|
if c.GetHeader("If-None-Match") == etag {
|
||||||
|
c.Status(http.StatusNotModified)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data(http.StatusOK, appicon.ContentTypePNG, iconBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags App
|
||||||
|
// @Summary Search app detail by appkey and version
|
||||||
|
// @Accept json
|
||||||
|
// @Param appKey path string true "app key"
|
||||||
|
// @Param version path string true "app version"
|
||||||
|
// @Success 200 {object} response.AppDetailSimpleDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /apps/detail/node/:appKey/:version [get]
|
||||||
|
func (b *BaseApi) GetAppDetailForNode(c *gin.Context) {
|
||||||
|
appKey := c.Param("appKey")
|
||||||
|
version := c.Param("version")
|
||||||
|
appDetailDTO, err := appService.GetAppDetailByKey(appKey, version)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, appDetailDTO)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ func (b *BaseApi) LoadPort(c *gin.Context) {
|
|||||||
// @Success 200 {object} response.DatabaseConn
|
// @Success 200 {object} response.DatabaseConn
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /apps/installed/conninfo [POST]
|
// @Router /apps/installed/conninfo [post]
|
||||||
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
|
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
|
||||||
var req dto.OperationWithNameAndType
|
var req dto.OperationWithNameAndType
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -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
|
||||||
@@ -294,7 +293,7 @@ func (b *BaseApi) GetParams(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /apps/installed/params/update [post]
|
// @Router /apps/installed/params/update [post]
|
||||||
// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"应用参数修改 [installId]","formatEN":"Application param update [installId]"}
|
// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"installId","isList":false,"db":"app_installs","output_column":"name","output_value":"name"}],"formatZH":"应用参数修改 [name]","formatEN":"Application param update [name]"}
|
||||||
func (b *BaseApi) UpdateInstalled(c *gin.Context) {
|
func (b *BaseApi) UpdateInstalled(c *gin.Context) {
|
||||||
var req request.AppInstalledUpdate
|
var req request.AppInstalledUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -349,3 +348,24 @@ 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) {
|
||||||
|
var req request.AppInstallSort
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := appInstallService.UpdateSort(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -415,6 +422,11 @@ func (b *BaseApi) Backup(c *gin.Context) {
|
|||||||
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)
|
||||||
@@ -430,6 +442,16 @@ func (b *BaseApi) Backup(c *gin.Context) {
|
|||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case "container":
|
||||||
|
if err := backupService.ContainerBackup(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "compose":
|
||||||
|
if err := backupService.ComposeBackup(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
@@ -465,6 +487,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)
|
||||||
@@ -485,6 +512,16 @@ func (b *BaseApi) Recover(c *gin.Context) {
|
|||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case "container":
|
||||||
|
if err := backupService.ContainerRecover(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "compose":
|
||||||
|
if err := backupService.ComposeRecover(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
@@ -510,6 +547,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)
|
||||||
@@ -525,6 +567,16 @@ func (b *BaseApi) RecoverByUpload(c *gin.Context) {
|
|||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case "container":
|
||||||
|
if err := backupService.ContainerRecover(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case "compose":
|
||||||
|
if err := backupService.ComposeRecover(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
+199
-22
@@ -1,7 +1,11 @@
|
|||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"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"
|
||||||
@@ -53,6 +57,162 @@ func (b *BaseApi) LoadContainerUsers(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, containerService.LoadUsers(req))
|
helper.SuccessWithData(c, containerService.LoadUsers(req))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
|
// @Summary List container files
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ContainerFileReq true "request"
|
||||||
|
// @Success 200 {array} dto.ContainerFileInfo
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/files/search [post]
|
||||||
|
func (b *BaseApi) ListContainerFiles(c *gin.Context) {
|
||||||
|
var req dto.ContainerFileReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
files, err := containerService.ListContainerFiles(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, files)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
|
// @Summary Upload container file
|
||||||
|
// @Accept multipart/form-data
|
||||||
|
// @Param containerID formData string true "containerID"
|
||||||
|
// @Param path formData string true "path"
|
||||||
|
// @Param file formData file true "file"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/files/upload [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["containerID","path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"容器 [containerID] 上传文件到 [path]","formatEN":"Upload file to [path] in container [containerID]"}
|
||||||
|
func (b *BaseApi) UploadContainerFile(c *gin.Context) {
|
||||||
|
form, err := c.MultipartForm()
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
containerIDs := form.Value["containerID"]
|
||||||
|
paths := form.Value["path"]
|
||||||
|
uploadFiles := form.File["file"]
|
||||||
|
if len(containerIDs) == 0 || len(paths) == 0 || len(uploadFiles) == 0 {
|
||||||
|
helper.BadRequest(c, errors.New("invalid container file upload params"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req := dto.ContainerFileReq{
|
||||||
|
ContainerID: containerIDs[0],
|
||||||
|
Path: paths[0],
|
||||||
|
}
|
||||||
|
for _, uploadFile := range uploadFiles {
|
||||||
|
file, err := uploadFile.Open()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = containerService.UploadContainerFile(req, path.Base(uploadFile.Filename), uploadFile.Size, file)
|
||||||
|
_ = file.Close()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
|
// @Summary Get container file content
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ContainerFileReq true "request"
|
||||||
|
// @Success 200 {object} dto.ContainerFileContent
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/files/content [post]
|
||||||
|
func (b *BaseApi) GetContainerFileContent(c *gin.Context) {
|
||||||
|
var req dto.ContainerFileReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
content, err := containerService.GetContainerFileContent(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
|
// @Summary Get container file size
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ContainerFileReq true "request"
|
||||||
|
// @Success 200 {int} size
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/files/size [post]
|
||||||
|
func (b *BaseApi) GetContainerFileSize(c *gin.Context) {
|
||||||
|
var req dto.ContainerFileReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
size, err := containerService.GetContainerFileSize(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
|
// @Summary Delete container file
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ContainerFileBatchDeleteReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/files/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["containerID","paths"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"删除容器 [containerID] 文件 [paths]","formatEN":"Delete files [paths] in container [containerID]"}
|
||||||
|
func (b *BaseApi) DeleteContainerFile(c *gin.Context) {
|
||||||
|
var req dto.ContainerFileBatchDeleteReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := containerService.DeleteContainerFile(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Container
|
||||||
|
// @Summary Download container file
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ContainerFileReq true "request"
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/files/download [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["containerID","path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"下载容器 [containerID] 文件 [path]","formatEN":"Download file [path] from container [containerID]"}
|
||||||
|
func (b *BaseApi) DownloadContainerFile(c *gin.Context) {
|
||||||
|
var req dto.ContainerFileReq
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if req.ContainerID == "" || req.Path == "" {
|
||||||
|
helper.BadRequest(c, errors.New("invalid container file download params"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reader, fileName, contentType, err := containerService.DownloadContainerFile(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer reader.Close()
|
||||||
|
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(fileName))
|
||||||
|
c.DataFromReader(http.StatusOK, -1, contentType, reader, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Container
|
// @Tags Container
|
||||||
// @Summary List containers
|
// @Summary List containers
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -235,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
|
||||||
@@ -249,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
|
||||||
@@ -263,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"
|
||||||
@@ -306,27 +469,6 @@ func (b *BaseApi) ContainerCreate(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Container
|
|
||||||
// @Summary Create container by command
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body dto.ContainerCreateByCommand true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Security Timestamp
|
|
||||||
// @Router /containers/command [post]
|
|
||||||
func (b *BaseApi) ContainerCreateByCommand(c *gin.Context) {
|
|
||||||
var req dto.ContainerCreateByCommand
|
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := containerService.ContainerCreateByCommand(req); err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.Success(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Container
|
// @Tags Container
|
||||||
// @Summary Upgrade container
|
// @Summary Upgrade container
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -524,12 +666,20 @@ 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 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := containerService.DownloadContainerLogs(req.ContainerType, req.Container, req.Since, strconv.Itoa(int(req.Tail)), c)
|
err := containerService.DownloadContainerLogs(req.ContainerType, req.Container, req.Since, strconv.Itoa(int(req.Tail)), req.Timestamp, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.InternalServer(c, err)
|
helper.InternalServer(c, err)
|
||||||
}
|
}
|
||||||
@@ -731,17 +881,42 @@ func (b *BaseApi) ComposeUpdate(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Container Compose
|
||||||
|
// @Summary Load compose environment variables
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FilePath true "request"
|
||||||
|
// @Success 200 {array} string
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /containers/compose/env [post]
|
||||||
|
func (b *BaseApi) LoadComposeEnv(c *gin.Context) {
|
||||||
|
var req dto.FilePath
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := containerService.LoadComposeEnv(req.Path)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, data)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Container
|
// @Tags Container
|
||||||
// @Summary Container logs
|
// @Summary Container logs
|
||||||
// @Param container query string false "容器名称"
|
// @Param container query string false "容器名称"
|
||||||
// @Param since query string false "时间筛选"
|
// @Param since query string false "时间筛选"
|
||||||
// @Param follow query string false "是否追踪"
|
// @Param follow query string false "是否追踪"
|
||||||
// @Param tail query string false "显示行号"
|
// @Param tail query string false "显示行号"
|
||||||
|
// @Param timestamp query string false "是否显示时间"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @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")
|
||||||
@@ -750,6 +925,7 @@ func (b *BaseApi) ContainerStreamLogs(c *gin.Context) {
|
|||||||
since := c.Query("since")
|
since := c.Query("since")
|
||||||
follow := c.Query("follow") == "true"
|
follow := c.Query("follow") == "true"
|
||||||
tail := c.Query("tail")
|
tail := c.Query("tail")
|
||||||
|
timestamp := c.Query("timestamp") == "true"
|
||||||
|
|
||||||
container := c.Query("container")
|
container := c.Query("container")
|
||||||
compose := c.Query("compose")
|
compose := c.Query("compose")
|
||||||
@@ -759,6 +935,7 @@ func (b *BaseApi) ContainerStreamLogs(c *gin.Context) {
|
|||||||
Since: since,
|
Since: since,
|
||||||
Follow: follow,
|
Follow: follow,
|
||||||
Tail: tail,
|
Tail: tail,
|
||||||
|
Timestamp: timestamp,
|
||||||
Type: "container",
|
Type: "container",
|
||||||
}
|
}
|
||||||
if compose != "" {
|
if compose != "" {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
// @Tags Container Docker
|
// @Tags Container Docker
|
||||||
// @Summary Load docker status
|
// @Summary Load docker status
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {string} dto.DockerStatus
|
// @Success 200 {object} dto.DockerStatus
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /containers/docker/status [get]
|
// @Router /containers/docker/status [get]
|
||||||
@@ -24,7 +24,7 @@ func (b *BaseApi) LoadDockerStatus(c *gin.Context) {
|
|||||||
// @Tags Container Docker
|
// @Tags Container Docker
|
||||||
// @Summary Load docker daemon.json
|
// @Summary Load docker daemon.json
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} string
|
// @Success 200 {string} string
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /containers/daemonjson/file [get]
|
// @Router /containers/daemonjson/file [get]
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ var (
|
|||||||
aiToolService = service.NewIAIToolService()
|
aiToolService = service.NewIAIToolService()
|
||||||
mcpServerService = service.NewIMcpServerService()
|
mcpServerService = service.NewIMcpServerService()
|
||||||
tensorrtLLMService = service.NewITensorRTLLMService()
|
tensorrtLLMService = service.NewITensorRTLLMService()
|
||||||
|
agentService = service.NewIAgentService()
|
||||||
|
|
||||||
containerService = service.NewIContainerService()
|
containerService = service.NewIContainerService()
|
||||||
composeTemplateService = service.NewIComposeTemplateService()
|
composeTemplateService = service.NewIComposeTemplateService()
|
||||||
@@ -30,17 +31,20 @@ 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()
|
||||||
sshService = service.NewISSHService()
|
fileHistoryService = service.NewIFileHistoryService()
|
||||||
firewallService = service.NewIFirewallService()
|
fileShareService = service.NewIFileShareService()
|
||||||
iptablesService = service.NewIIptablesService()
|
sshService = service.NewISSHService()
|
||||||
monitorService = service.NewIMonitorService()
|
firewallService = service.NewIFirewallService()
|
||||||
systemService = service.NewISystemService()
|
iptablesService = service.NewIIptablesService()
|
||||||
|
monitorService = service.NewIMonitorService()
|
||||||
|
systemService = service.NewISystemService()
|
||||||
|
|
||||||
deviceService = service.NewIDeviceService()
|
deviceService = service.NewIDeviceService()
|
||||||
fail2banService = service.NewIFail2BanService()
|
fail2banService = service.NewIFail2BanService()
|
||||||
@@ -69,6 +73,7 @@ var (
|
|||||||
|
|
||||||
recycleBinService = service.NewIRecycleBinService()
|
recycleBinService = service.NewIRecycleBinService()
|
||||||
favoriteService = service.NewIFavoriteService()
|
favoriteService = service.NewIFavoriteService()
|
||||||
|
hostService = service.NewIHostService()
|
||||||
|
|
||||||
websiteCAService = service.NewIWebsiteCAService()
|
websiteCAService = service.NewIWebsiteCAService()
|
||||||
taskService = service.NewITaskService()
|
taskService = service.NewITaskService()
|
||||||
|
|||||||
+415
-18
@@ -25,6 +25,7 @@ import (
|
|||||||
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"
|
"github.com/gorilla/websocket"
|
||||||
|
qrcode "github.com/skip2/go-qrcode"
|
||||||
)
|
)
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
@@ -48,6 +49,31 @@ func (b *BaseApi) ListFiles(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, fileList)
|
helper.SuccessWithData(c, fileList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary File search: content grep + optional AI summary
|
||||||
|
// @Description When file-management AI is enabled, returns mode=ai with summary and hits. When disabled, returns mode=grep with hits only. Scans file contents only. Supports match options, extension/size/time filters, and scan limits.
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileAISearch true "request"
|
||||||
|
// @Success 200 {object} response.FileAISearchResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/ai-search [post]
|
||||||
|
func (b *BaseApi) FileAISearch(c *gin.Context) {
|
||||||
|
var req request.FileAISearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(req.ResponseLanguage) == "" {
|
||||||
|
req.ResponseLanguage = strings.TrimSpace(c.GetHeader("Accept-Language"))
|
||||||
|
}
|
||||||
|
res, err := fileService.AISearch(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Page file
|
// @Summary Page file
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -167,7 +193,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 {
|
||||||
@@ -189,7 +215,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 {
|
||||||
@@ -224,6 +250,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
|
||||||
@@ -246,6 +292,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
|
||||||
@@ -345,7 +411,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) {
|
||||||
@@ -386,8 +452,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
|
||||||
@@ -410,7 +482,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)
|
||||||
@@ -515,6 +587,29 @@ func (b *BaseApi) WgetFile(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Stop wget file download
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileProcessReq true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/wget/stop [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["key"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"停止下载任务 [key]","formatEN":"Stop wget task [key]"}
|
||||||
|
func (b *BaseApi) StopWget(c *gin.Context) {
|
||||||
|
var req request.FileProcessReq
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(req.Key) == "" {
|
||||||
|
helper.BadRequest(c, errors.New("key is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
files.CancelDownload(req.Key)
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Move file
|
// @Summary Move file
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -545,6 +640,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)
|
||||||
@@ -580,6 +679,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 {
|
||||||
@@ -698,12 +801,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)
|
||||||
@@ -725,6 +829,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
|
||||||
}
|
}
|
||||||
@@ -829,7 +934,17 @@ var wsUpgrade = websocket.Upgrader{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @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
|
||||||
@@ -839,6 +954,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-")
|
||||||
@@ -858,16 +979,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)
|
||||||
@@ -900,16 +1025,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
|
||||||
@@ -978,3 +1093,285 @@ func (b *BaseApi) ConvertLog(c *gin.Context) {
|
|||||||
Total: total,
|
Total: total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Batch get file remarks
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileRemarkBatch true "request"
|
||||||
|
// @Success 200 {object} response.FileRemarksRes
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/remarks [post]
|
||||||
|
func (b *BaseApi) BatchGetFileRemarks(c *gin.Context) {
|
||||||
|
var req request.FileRemarkBatch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
remarks := fileService.BatchGetRemarks(req)
|
||||||
|
helper.SuccessWithData(c, response.FileRemarksRes{Remarks: remarks})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Set file remark
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileRemarkUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/remark [post]
|
||||||
|
func (b *BaseApi) SetFileRemark(c *gin.Context) {
|
||||||
|
var req request.FileRemarkUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fileService.SetRemark(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary List file shares
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.PageInfo true "request"
|
||||||
|
// @Success 200 {object} dto.PageResult
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/share/search [post]
|
||||||
|
func (b *BaseApi) SearchFileShare(c *gin.Context) {
|
||||||
|
var req dto.PageInfo
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, list, err := fileShareService.Page(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, dto.PageResult{
|
||||||
|
Total: total,
|
||||||
|
Items: list,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Get file share detail by path
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FilePath true "request"
|
||||||
|
// @Success 200 {object} response.FileShareInfo
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/share/detail [post]
|
||||||
|
func (b *BaseApi) GetFileShareDetail(c *gin.Context) {
|
||||||
|
var req dto.FilePath
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info, err := fileShareService.GetByPath(req.Path)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Get file share detail by code (no login)
|
||||||
|
// @Param code query string true "share code"
|
||||||
|
// @Success 200 {object} response.FileSharePublicInfo
|
||||||
|
// @Router /files/share/info [get]
|
||||||
|
func (b *BaseApi) GetPublicFileShareInfo(c *gin.Context) {
|
||||||
|
code := strings.TrimSpace(c.Query("code"))
|
||||||
|
if code == "" {
|
||||||
|
helper.BadRequest(c, errors.New("code is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info, err := fileShareService.GetPublicByCode(code)
|
||||||
|
if err != nil {
|
||||||
|
if be, ok := err.(buserr.BusinessError); ok {
|
||||||
|
helper.ErrorWithDetail(c, http.StatusBadRequest, be.Msg, be)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSharePublicURL(c *gin.Context, code, operateNode string) string {
|
||||||
|
scheme := strings.TrimSpace(c.GetHeader("X-Forwarded-Proto"))
|
||||||
|
if scheme == "" {
|
||||||
|
if c.Request.TLS != nil {
|
||||||
|
scheme = "https"
|
||||||
|
} else {
|
||||||
|
scheme = "http"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
host := strings.TrimSpace(c.GetHeader("X-Forwarded-Host"))
|
||||||
|
if host == "" {
|
||||||
|
host = c.Request.Host
|
||||||
|
}
|
||||||
|
shareURL := url.URL{
|
||||||
|
Scheme: scheme,
|
||||||
|
Host: host,
|
||||||
|
Path: "/s/" + url.PathEscape(code),
|
||||||
|
}
|
||||||
|
query := shareURL.Query()
|
||||||
|
if strings.TrimSpace(operateNode) != "" {
|
||||||
|
query.Set("operateNode", operateNode)
|
||||||
|
}
|
||||||
|
shareURL.RawQuery = query.Encode()
|
||||||
|
return shareURL.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Get file share QR code image
|
||||||
|
// @Produce png
|
||||||
|
// @Param code query string true "share code"
|
||||||
|
// @Param operateNode query string false "operate node"
|
||||||
|
// @Success 200 {file} file
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/share/qrcode [get]
|
||||||
|
func (b *BaseApi) GetFileShareQRCode(c *gin.Context) {
|
||||||
|
code := strings.TrimSpace(c.Query("code"))
|
||||||
|
if code == "" {
|
||||||
|
helper.BadRequest(c, errors.New("code is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err := fileShareService.GetByCode(code); err != nil {
|
||||||
|
if be, ok := err.(buserr.BusinessError); ok {
|
||||||
|
helper.ErrorWithDetail(c, http.StatusBadRequest, be.Msg, be)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
png, err := qrcode.Encode(buildSharePublicURL(c, code, c.Query("operateNode")), qrcode.Medium, 256)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Header("Cache-Control", "private, max-age=300")
|
||||||
|
c.Data(http.StatusOK, "image/png", png)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Create temporary file share link
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FileShareCreate true "request"
|
||||||
|
// @Success 200 {object} response.FileShareInfo
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/share/create [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["path","expireMinutes"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"创建文件分享 [path]","formatEN":"Create file share [path]"}
|
||||||
|
func (b *BaseApi) CreateFileShare(c *gin.Context) {
|
||||||
|
var req request.FileShareCreate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := fileShareService.Create(req)
|
||||||
|
if err != nil {
|
||||||
|
if be, ok := err.(buserr.BusinessError); ok {
|
||||||
|
helper.ErrorWithDetail(c, http.StatusInternalServerError, be.Msg, be.Err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Delete file share by path
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FilePath true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /files/share/del [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"关闭文件分享 [path]","formatEN":"Close file share [path]"}
|
||||||
|
func (b *BaseApi) DeleteFileShare(c *gin.Context) {
|
||||||
|
var req dto.FilePath
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fileShareService.DeleteByPath(req.Path); err != nil {
|
||||||
|
if be, ok := err.(buserr.BusinessError); ok {
|
||||||
|
helper.ErrorWithDetail(c, http.StatusInternalServerError, be.Msg, be.Err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Check file share code (no login)
|
||||||
|
// @Param code query string true "share code"
|
||||||
|
// @Param password query string false "optional password"
|
||||||
|
// @Success 200 {object} dto.Response
|
||||||
|
// @Router /files/share/check [get]
|
||||||
|
func (b *BaseApi) CheckFileShare(c *gin.Context) {
|
||||||
|
code := strings.TrimSpace(c.Query("code"))
|
||||||
|
password := c.Query("password")
|
||||||
|
if code == "" {
|
||||||
|
helper.BadRequest(c, errors.New("code is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := fileShareService.Check(code, password); err != nil {
|
||||||
|
if be, ok := err.(buserr.BusinessError); ok {
|
||||||
|
helper.ErrorWithDetail(c, http.StatusBadRequest, be.Msg, be)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Download file by share code (no login)
|
||||||
|
// @Produce octet-stream
|
||||||
|
// @Param code query string true "share code"
|
||||||
|
// @Param password query string false "optional password"
|
||||||
|
// @Success 200 {file} file
|
||||||
|
// @Router /files/share/download [get]
|
||||||
|
func (b *BaseApi) DownloadFileShare(c *gin.Context) {
|
||||||
|
code := strings.TrimSpace(c.Query("code"))
|
||||||
|
password := c.Query("password")
|
||||||
|
if code == "" {
|
||||||
|
helper.BadRequest(c, errors.New("code is required"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
filePath, displayName, err := fileShareService.PrepareDownload(code, password)
|
||||||
|
if err != nil {
|
||||||
|
if be, ok := err.(buserr.BusinessError); ok {
|
||||||
|
helper.ErrorWithDetail(c, http.StatusBadRequest, be.Msg, be)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if files.ShouldDenySensitiveFileRead(filePath) {
|
||||||
|
helper.InternalServer(c, buserr.New("ErrSensitiveFileRead"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
file, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
info, err := file.Stat()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Header("Content-Length", strconv.FormatInt(info.Size(), 10))
|
||||||
|
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(displayName))
|
||||||
|
http.ServeContent(c.Writer, c.Request, displayName, info.ModTime(), file)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -236,7 +236,7 @@ func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
|
|||||||
// @Success 200 {object} dto.PageResult
|
// @Success 200 {object} dto.PageResult
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/firewall/filter/search [post]
|
// @Router /hosts/firewall/filter/rule/search [post]
|
||||||
func (b *BaseApi) SearchFilterRules(c *gin.Context) {
|
func (b *BaseApi) SearchFilterRules(c *gin.Context) {
|
||||||
var req dto.SearchPageWithType
|
var req dto.SearchPageWithType
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
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/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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @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
|
||||||
|
// @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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,243 @@
|
|||||||
|
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/utils/encrypt"
|
||||||
|
"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) {
|
||||||
|
var req dto.HostOperate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
host, err := hostService.Create(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
var req dto.HostConnTest
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
var req dto.OperateByID
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
var req dto.SearchForTree
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := hostService.SearchForTree(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
var req dto.SearchPageWithGroup
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
total, list, err := hostService.SearchWithPage(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
var req dto.OperateByIDs
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := hostService.Delete(req.IDs); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
var req dto.HostOperate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if len(req.Password) != 0 && req.AuthMode == "password" {
|
||||||
|
req.Password, err = hostService.EncryptHost(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.PrivateKey = ""
|
||||||
|
req.PassPhrase = ""
|
||||||
|
}
|
||||||
|
if len(req.PrivateKey) != 0 && req.AuthMode == "key" {
|
||||||
|
req.PrivateKey, err = hostService.EncryptHost(req.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(req.PassPhrase) != 0 {
|
||||||
|
req.PassPhrase, err = encrypt.StringEncrypt(req.PassPhrase)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.Password = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
upMap := map[string]interface{}{
|
||||||
|
"name": req.Name,
|
||||||
|
"group_id": req.GroupID,
|
||||||
|
"addr": req.Addr,
|
||||||
|
"port": req.Port,
|
||||||
|
"user": req.User,
|
||||||
|
"auth_mode": req.AuthMode,
|
||||||
|
"remember_password": req.RememberPassword,
|
||||||
|
"description": req.Description,
|
||||||
|
}
|
||||||
|
if req.AuthMode == "password" {
|
||||||
|
upMap["password"] = req.Password
|
||||||
|
upMap["private_key"] = ""
|
||||||
|
upMap["pass_phrase"] = ""
|
||||||
|
} else {
|
||||||
|
upMap["password"] = ""
|
||||||
|
upMap["private_key"] = req.PrivateKey
|
||||||
|
upMap["pass_phrase"] = req.PassPhrase
|
||||||
|
}
|
||||||
|
hostItem, err := hostService.Update(req.ID, upMap)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
var req dto.ChangeGroup
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := hostService.Update(req.ID, map[string]interface{}{"group_id": req.GroupID}); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
var req dto.OperateByID
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info, err := hostService.GetHostByID(req.ID)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, info)
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
+13
-26
@@ -31,27 +31,6 @@ func (b *BaseApi) LoadMonitor(c *gin.Context) {
|
|||||||
helper.SuccessWithDataGzipped(c, data)
|
helper.SuccessWithDataGzipped(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Monitor
|
|
||||||
// @Summary Load monitor data
|
|
||||||
// @Param request body dto.MonitorGPUSearch 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
|
// @Tags Monitor
|
||||||
// @Summary Clean monitor data
|
// @Summary Clean monitor data
|
||||||
// @Success 200
|
// @Success 200
|
||||||
@@ -91,7 +70,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,6 +84,12 @@ 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)
|
netStat, _ := net.IOCounters(true)
|
||||||
var options []string
|
var options []string
|
||||||
@@ -116,6 +101,12 @@ func (b *BaseApi) GetNetworkOptions(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, 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()
|
diskStat, _ := disk.IOCounters()
|
||||||
var options []string
|
var options []string
|
||||||
@@ -126,7 +117,3 @@ func (b *BaseApi) GetIOOptions(c *gin.Context) {
|
|||||||
sort.Strings(options)
|
sort.Strings(options)
|
||||||
helper.SuccessWithData(c, options)
|
helper.SuccessWithData(c, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BaseApi) GetCPUOptions(c *gin.Context) {
|
|
||||||
helper.SuccessWithData(c, monitorService.LoadGPUOptions())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -57,3 +68,18 @@ func (b *BaseApi) GetProcessInfoByPID(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithData(c, data)
|
helper.SuccessWithData(c, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Process
|
||||||
|
// @Summary Get Listening Process
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /process/listening [post]
|
||||||
|
func (b *BaseApi) GetListeningProcess(c *gin.Context) {
|
||||||
|
procs, err := processService.GetListeningProcess(c)
|
||||||
|
if err != nil {
|
||||||
|
helper.BadRequest(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, procs)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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":[],"formatZH":"操作运行环境 [id]","formatEN":"Operate runtime [id]"}
|
||||||
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
|
||||||
|
|||||||
+134
-31
@@ -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,21 @@ 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) {
|
||||||
|
setting, err := settingService.GetTerminalAIInfo()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, setting)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags System Setting
|
// @Tags System Setting
|
||||||
// @Summary Load system available status
|
// @Summary Load system available status
|
||||||
// @Success 200
|
// @Success 200
|
||||||
@@ -40,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
|
||||||
}
|
}
|
||||||
@@ -59,6 +71,109 @@ 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) {
|
||||||
|
var req dto.TerminalAIInfo
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := settingService.UpdateTerminalAI(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
setting, err := settingService.GetFileManageAIInfo()
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
var req dto.FileManageAIInfo
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := settingService.UpdateFileManageAI(req); err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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
|
||||||
@@ -79,8 +194,17 @@ 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) {
|
||||||
_, err := loadLocalConn()
|
client, err := loadLocalConn()
|
||||||
|
if err == nil && client != nil {
|
||||||
|
client.Close()
|
||||||
|
}
|
||||||
helper.SuccessWithData(c, err == nil)
|
helper.SuccessWithData(c, err == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,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
|
||||||
@@ -141,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{
|
||||||
@@ -161,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
|
||||||
|
|||||||
@@ -249,14 +249,14 @@ func (b *BaseApi) LoadSSHFile(c *gin.Context) {
|
|||||||
// @Tags SSH
|
// @Tags SSH
|
||||||
// @Summary Update host SSH setting by file
|
// @Summary Update host SSH setting by file
|
||||||
// @Accept json
|
// @Accept json
|
||||||
// @Param request body dto.SSHConf true "request"
|
// @Param request body dto.SSHConfUpdate true "request"
|
||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /hosts/ssh/file/update [post]
|
// @Router /hosts/ssh/file/update [post]
|
||||||
// @x-panel-log {"bodyKeys":["key"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置文件 [key]","formatEN":"update SSH conf [key]"}
|
// @x-panel-log {"bodyKeys":["key"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"修改 SSH 配置文件 [key]","formatEN":"update SSH conf [key]"}
|
||||||
func (b *BaseApi) UpdateSSHByFile(c *gin.Context) {
|
func (b *BaseApi) UpdateSSHByFile(c *gin.Context) {
|
||||||
var req dto.SettingUpdate
|
var req dto.SSHConfUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,9 +32,34 @@ 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 {object} int64
|
// @Success 200 {integer} int64
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /logs/tasks/executing/count [get]
|
// @Router /logs/tasks/executing/count [get]
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
+157
-82
@@ -8,102 +8,65 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"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/global"
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/ssh"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/terminal"
|
"github.com/1Panel-dev/1Panel/agent/utils/terminal"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
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)
|
// @Success 200
|
||||||
return
|
// @Security ApiKeyAuth
|
||||||
}
|
// @Security Timestamp
|
||||||
defer wsConn.Close()
|
// @Router /hosts/terminal/local [get]
|
||||||
|
func (b *BaseApi) WsLocalTerminal(c *gin.Context) {
|
||||||
if global.CONF.Base.IsDemo {
|
b.runSSHSession(c, loadLocalConn, c.DefaultQuery("command", ""))
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := loadLocalConn()
|
|
||||||
if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer client.Close()
|
|
||||||
command := c.DefaultQuery("command", "")
|
|
||||||
sws, err := terminal.NewLogicSshWsSession(cols, rows, client.Client, wsConn, command)
|
|
||||||
if wshandleError(wsConn, err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer sws.Close()
|
|
||||||
|
|
||||||
quitChan := make(chan bool, 3)
|
|
||||||
sws.Start(quitChan)
|
|
||||||
go sws.Wait(quitChan)
|
|
||||||
|
|
||||||
<-quitChan
|
|
||||||
|
|
||||||
dt := time.Now().Add(time.Second)
|
|
||||||
_ = wsConn.WriteControl(websocket.CloseMessage, nil, dt)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
|
// @Tags Terminal
|
||||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
// @Summary Ws host SSH
|
||||||
if err != nil {
|
// @Param id query integer false "id"
|
||||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
// @Param command query string false "command"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /hosts/terminal/ssh [get]
|
||||||
|
func (b *BaseApi) WsHostSSH(c *gin.Context) {
|
||||||
|
b.runSSHSession(c, 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()
|
||||||
|
|
||||||
if global.CONF.Base.IsDemo {
|
slave, err := loadContainerTerminalCommand(c)
|
||||||
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")
|
|
||||||
var initCmd []string
|
|
||||||
switch source {
|
|
||||||
case "redis", "redis-cluster":
|
|
||||||
initCmd, err = loadRedisInitCmd(c, source)
|
|
||||||
case "ollama":
|
|
||||||
initCmd, err = loadOllamaInitCmd(c)
|
|
||||||
case "container":
|
|
||||||
initCmd, err = loadContainerInitCmd(c)
|
|
||||||
case "database":
|
|
||||||
initCmd, err = loadDatabaseInitCmd(c)
|
|
||||||
default:
|
|
||||||
if wshandleError(wsConn, fmt.Errorf("not support such source %s", source)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if wshandleError(wsConn, err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
slave, err := terminal.NewCommand("docker", initCmd...)
|
|
||||||
if wshandleError(wsConn, err) {
|
if wshandleError(wsConn, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -121,10 +84,112 @@ func (b *BaseApi) ContainerWsSSH(c *gin.Context) {
|
|||||||
<-quitChan
|
<-quitChan
|
||||||
|
|
||||||
global.LOG.Info("websocket finished")
|
global.LOG.Info("websocket finished")
|
||||||
|
closeTerminalConn(wsConn)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 wshandleError(wsConn, errors.New(" demo server, prohibit this operation!")) {
|
||||||
|
return nil, 0, 0, false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||||
|
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
|
||||||
|
return nil, 0, 0, false
|
||||||
|
}
|
||||||
|
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||||
|
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, connect func() (*ssh.SSHClient, error), command string) {
|
||||||
|
wsConn, cols, rows, ok := prepareTerminalSession(c)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer wsConn.Close()
|
||||||
|
|
||||||
|
client, clientErr := connect()
|
||||||
|
if wshandleError(wsConn, errors.WithMessage(clientErr, "failed to set up the connection. Please check the host information")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
sws, err := terminal.NewLogicSshWsSession(cols, rows, client.Client, wsConn, command)
|
||||||
|
if wshandleError(wsConn, err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer sws.Close()
|
||||||
|
|
||||||
|
quitChan := make(chan bool, 3)
|
||||||
|
sws.Start(quitChan)
|
||||||
|
go sws.Wait(quitChan)
|
||||||
|
|
||||||
|
<-quitChan
|
||||||
|
|
||||||
|
closeTerminalConn(wsConn)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 newHostSSHClient(host *model.Host, err error) (*ssh.SSHClient, error) {
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.WithMessage(err, "load host info by id failed")
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadContainerTerminalCommand(c *gin.Context) (*terminal.LocalCommand, error) {
|
||||||
|
source := c.Query("source")
|
||||||
|
var (
|
||||||
|
initCmd []string
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
switch source {
|
||||||
|
case "redis", "redis-cluster":
|
||||||
|
initCmd, err = loadRedisInitCmd(c, source)
|
||||||
|
case "ollama":
|
||||||
|
initCmd, err = loadOllamaInitCmd(c)
|
||||||
|
case "container":
|
||||||
|
initCmd, err = loadContainerInitCmd(c)
|
||||||
|
case "database":
|
||||||
|
initCmd, err = loadDatabaseInitCmd(c)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("not support such source %s", source)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return terminal.NewCommand("docker", initCmd...)
|
||||||
|
}
|
||||||
|
|
||||||
func loadRedisInitCmd(c *gin.Context, redisType string) ([]string, error) {
|
func loadRedisInitCmd(c *gin.Context, redisType string) ([]string, error) {
|
||||||
name := c.Query("name")
|
name := c.Query("name")
|
||||||
from := c.Query("from")
|
from := c.Query("from")
|
||||||
@@ -187,19 +252,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}
|
||||||
}
|
}
|
||||||
|
|||||||
+88
-11
@@ -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
|
||||||
@@ -506,7 +528,7 @@ func (b *BaseApi) GetProxyConfig(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /websites/proxies/update [post]
|
// @Router /websites/proxies/update [post]
|
||||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改网站 [domain] 反向代理配置 ","formatEN":"Update domain [domain] proxy config"}
|
// @x-panel-log {"bodyKeys":["id","name","operate"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改 [operate] 网站 [domain] 反向代理配置 [name] ","formatEN":"Update [operate] domain [domain] proxy config [name]"}
|
||||||
func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
||||||
var req request.WebsiteProxyConfig
|
var req request.WebsiteProxyConfig
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -520,6 +542,50 @@ func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
|||||||
helper.Success(c)
|
helper.Success(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Delete proxy config
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteProxyDel true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/proxies/delete [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","name"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除网站 [domain] 反向代理配置 [name] ","formatEN":"Delete domain [domain] proxy config [name]"}
|
||||||
|
func (b *BaseApi) DeleteProxyConfig(c *gin.Context) {
|
||||||
|
var req request.WebsiteProxyDel
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := websiteService.DeleteProxy(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website
|
||||||
|
// @Summary Update proxy config status
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteProxyStatusUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/proxies/status [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id","name","status"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改网站 [domain] 反向代理配置 [name] 状态 [status] ","formatEN":"Update domain [domain] proxy config [name] status [status]"}
|
||||||
|
func (b *BaseApi) UpdateProxyConfigStatus(c *gin.Context) {
|
||||||
|
var req request.WebsiteProxyStatusUpdate
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := websiteService.UpdateProxyStatus(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.Success(c)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Website
|
// @Tags Website
|
||||||
// @Summary Update proxy file
|
// @Summary Update proxy file
|
||||||
// @Accept json
|
// @Accept json
|
||||||
@@ -528,7 +594,7 @@ func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
|||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Security Timestamp
|
// @Security Timestamp
|
||||||
// @Router /websites/proxies/file [post]
|
// @Router /websites/proxies/file [post]
|
||||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新反向代理文件 [domain]","formatEN":"Nginx conf proxy file update [domain]"}
|
// @x-panel-log {"bodyKeys":["websiteID","name"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改网站 [domain] 反向代理配置文件 [name] ","formatEN":"Update domain [domain] proxy config file [name]"}
|
||||||
func (b *BaseApi) UpdateProxyConfigFile(c *gin.Context) {
|
func (b *BaseApi) UpdateProxyConfigFile(c *gin.Context) {
|
||||||
var req request.NginxProxyUpdate
|
var req request.NginxProxyUpdate
|
||||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
@@ -755,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")
|
||||||
@@ -794,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 {
|
||||||
@@ -893,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 {
|
||||||
@@ -925,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"
|
||||||
@@ -1251,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 {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
@@ -26,27 +25,39 @@ import (
|
|||||||
// @Router /websites/ssl/search [post]
|
// @Router /websites/ssl/search [post]
|
||||||
func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
|
func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
|
||||||
var req request.WebsiteSSLSearch
|
var req request.WebsiteSSLSearch
|
||||||
|
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
total, accounts, err := websiteSSLService.Page(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.InternalServer(c, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithDataGzipped(c, dto.PageResult{
|
||||||
|
Total: total,
|
||||||
|
Items: accounts,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Tags Website SSL
|
||||||
|
// @Summary List website ssl
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteSSLListReq true "request"
|
||||||
|
// @Success 200 {array} response.WebsiteSSLDTO
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Security Timestamp
|
||||||
|
// @Router /websites/ssl/list [post]
|
||||||
|
func (b *BaseApi) ListWebsiteSSL(c *gin.Context) {
|
||||||
|
var req request.WebsiteSSLListReq
|
||||||
if err := helper.CheckBind(&req, c); err != nil {
|
if err := helper.CheckBind(&req, c); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(req.PageInfo, dto.PageInfo{}) {
|
list, err := websiteSSLService.Search(req)
|
||||||
total, accounts, err := websiteSSLService.Page(req)
|
if err != nil {
|
||||||
if err != nil {
|
helper.InternalServer(c, err)
|
||||||
helper.InternalServer(c, err)
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithDataGzipped(c, dto.PageResult{
|
|
||||||
Total: total,
|
|
||||||
Items: accounts,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
list, err := websiteSSLService.Search(req)
|
|
||||||
if err != nil {
|
|
||||||
helper.InternalServer(c, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithDataGzipped(c, list)
|
|
||||||
}
|
}
|
||||||
|
helper.SuccessWithDataGzipped(c, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Website SSL
|
// @Tags Website SSL
|
||||||
@@ -322,6 +333,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,735 @@
|
|||||||
|
package dto
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type AgentCreateReq struct {
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
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"`
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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"`
|
||||||
|
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 {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
AgentType string `json:"agentType"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
ProviderName string `json:"providerName"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
APIType string `json:"apiType"`
|
||||||
|
MaxTokens int `json:"maxTokens"`
|
||||||
|
ContextWindow int `json:"contextWindow"`
|
||||||
|
BaseURL string `json:"baseUrl"`
|
||||||
|
APIKey string `json:"apiKey"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
AppInstallID uint `json:"appInstallId"`
|
||||||
|
WebsiteID uint `json:"websiteId"`
|
||||||
|
WebsitePrimaryDomain string `json:"websitePrimaryDomain"`
|
||||||
|
WebsiteType string `json:"websiteType"`
|
||||||
|
WebsiteProtocol string `json:"websiteProtocol"`
|
||||||
|
AccountID uint `json:"accountId"`
|
||||||
|
AppVersion string `json:"appVersion"`
|
||||||
|
Container string `json:"containerName"`
|
||||||
|
WebUIPort int `json:"webUIPort"`
|
||||||
|
BridgePort int `json:"bridgePort"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
ConfigPath string `json:"configPath"`
|
||||||
|
Upgradable bool `json:"upgradable"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentDeleteReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
|
ForceDelete bool `json:"forceDelete"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentTokenResetReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRemarkUpdateReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentWebsiteBindReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentModelConfigUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
AccountID uint `json:"accountId" validate:"required"`
|
||||||
|
Model string `json:"model" validate:"required"`
|
||||||
|
Fallbacks []string `json:"fallbacks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentModelConfig struct {
|
||||||
|
AccountID uint `json:"accountId"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
Fallbacks []string `json:"fallbacks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentIDReq struct {
|
||||||
|
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 {
|
||||||
|
Snapshot AgentOverviewSnapshot `json:"snapshot"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleBinding struct {
|
||||||
|
Channel string `json:"channel" validate:"required"`
|
||||||
|
AccountID string `json:"accountId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleCreateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
Bindings []AgentRoleBinding `json:"bindings"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleCreateResp struct {
|
||||||
|
Output string `json:"output"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleDeleteReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
ID string `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleBindReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
ID string `json:"id" validate:"required"`
|
||||||
|
Channel string `json:"channel" validate:"required"`
|
||||||
|
AccountID string `json:"accountId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentConfiguredAgentsReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleChannelsReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleChannelItem struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Bound bool `json:"bound"`
|
||||||
|
AccountIDs []string `json:"accountIds"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleMarkdownFilesReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Workspace string `json:"workspace" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentConfiguredAgentItem struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Workspace string `json:"workspace"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
AgentDir string `json:"agentDir"`
|
||||||
|
Bindings []AgentRoleBinding `json:"bindings"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleMarkdownFileItem struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleMarkdownFileUpdateItem struct {
|
||||||
|
Name string `json:"name" validate:"required,oneof=AGENTS.md SOUL.md USER.md IDENTITY.md TOOLS.md HEARTBEAT.md BOOT.md BOOTSTRAP.md"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentRoleMarkdownFilesUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Workspace string `json:"workspace" validate:"required"`
|
||||||
|
Restart bool `json:"restart"`
|
||||||
|
Files []AgentRoleMarkdownFileUpdateItem `json:"files" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentOverviewSnapshot struct {
|
||||||
|
ContainerStatus string `json:"containerStatus"`
|
||||||
|
AppVersion string `json:"appVersion"`
|
||||||
|
DefaultModel string `json:"defaultModel"`
|
||||||
|
ChannelCount int `json:"channelCount"`
|
||||||
|
SkillCount int `json:"skillCount"`
|
||||||
|
JobCount int `json:"jobCount"`
|
||||||
|
SessionCount int `json:"sessionCount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountModel struct {
|
||||||
|
RecordID uint `json:"recordId"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ContextWindow int `json:"contextWindow"`
|
||||||
|
MaxTokens int `json:"maxTokens"`
|
||||||
|
Reasoning bool `json:"reasoning"`
|
||||||
|
Input []string `json:"input"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountModelReq struct {
|
||||||
|
AccountID uint `json:"accountId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountModelCreateReq struct {
|
||||||
|
AccountID uint `json:"accountId" validate:"required"`
|
||||||
|
Model AgentAccountModel `json:"model" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountModelUpdateReq struct {
|
||||||
|
AccountID uint `json:"accountId" validate:"required"`
|
||||||
|
Model AgentAccountModel `json:"model" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountModelDeleteReq struct {
|
||||||
|
AccountID uint `json:"accountId" validate:"required"`
|
||||||
|
RecordID uint `json:"recordId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountCreateReq struct {
|
||||||
|
Provider string `json:"provider" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
APIKey string `json:"apiKey" validate:"required"`
|
||||||
|
RememberAPIKey bool `json:"rememberApiKey"`
|
||||||
|
BaseURL string `json:"baseURL"`
|
||||||
|
Models []AgentAccountModel `json:"models"`
|
||||||
|
APIType string `json:"apiType" validate:"required"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountUpdateReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
APIKey string `json:"apiKey" validate:"required"`
|
||||||
|
RememberAPIKey bool `json:"rememberApiKey"`
|
||||||
|
BaseURL string `json:"baseURL"`
|
||||||
|
APIType string `json:"apiType" validate:"required"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
SyncAgents bool `json:"syncAgents"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountVerifyReq struct {
|
||||||
|
Provider string `json:"provider" validate:"required"`
|
||||||
|
APIKey string `json:"apiKey" validate:"required"`
|
||||||
|
BaseURL string `json:"baseURL"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountDeleteReq struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountSearch struct {
|
||||||
|
PageInfo
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountProviderCountReq struct {
|
||||||
|
Providers []string `json:"providers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentAccountInfo struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
MasterAccountID uint `json:"masterAccountId"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
ProviderName string `json:"providerName"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
APIKey string `json:"apiKey"`
|
||||||
|
RememberAPIKey bool `json:"rememberApiKey"`
|
||||||
|
BaseURL string `json:"baseUrl"`
|
||||||
|
Models []AgentAccountModel `json:"models"`
|
||||||
|
APIType string `json:"apiType"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProviderModelInfo struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ContextWindow int `json:"contextWindow"`
|
||||||
|
MaxTokens int `json:"maxTokens"`
|
||||||
|
Reasoning bool `json:"reasoning"`
|
||||||
|
Input []string `json:"input"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProviderInfo struct {
|
||||||
|
Sort uint `json:"-"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
BaseURL string `json:"baseUrl"`
|
||||||
|
Models []ProviderModelInfo `json:"models"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentFeishuConfigReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentFeishuConfigUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
ThreadSession bool `json:"threadSession"`
|
||||||
|
ReplyMode string `json:"replyMode" validate:"required"`
|
||||||
|
Streaming bool `json:"streaming"`
|
||||||
|
RequireMention string `json:"requireMention" validate:"required,oneof=true false open"`
|
||||||
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
ConnectionMode string `json:"connectionMode"`
|
||||||
|
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 {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
ThreadSession bool `json:"threadSession"`
|
||||||
|
ReplyMode string `json:"replyMode"`
|
||||||
|
Streaming bool `json:"streaming"`
|
||||||
|
RequireMention string `json:"requireMention"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Domain string `json:"domain"`
|
||||||
|
ConnectionMode string `json:"connectionMode"`
|
||||||
|
Bots []AgentFeishuBot `json:"bots"`
|
||||||
|
Installed bool `json:"installed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentTelegramConfigReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentTelegramConfigUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy" validate:"required,oneof=pairing open allowlist disabled"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
RequireMention bool `json:"requireMention"`
|
||||||
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Proxy string `json:"proxy"`
|
||||||
|
Streaming string `json:"streaming" validate:"required,oneof=off partial block progress"`
|
||||||
|
DefaultAccount string `json:"defaultAccount" validate:"required"`
|
||||||
|
Bots []AgentTelegramBot `json:"bots" validate:"required,min=1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentTelegramConfig struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
RequireMention bool `json:"requireMention"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Proxy string `json:"proxy"`
|
||||||
|
Streaming string `json:"streaming"`
|
||||||
|
DefaultAccount string `json:"defaultAccount"`
|
||||||
|
Bots []AgentTelegramBot `json:"bots"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentChannelPairingApproveReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=feishu telegram discord wecom qqbot dingtalk"`
|
||||||
|
PairingCode string `json:"pairingCode" validate:"required"`
|
||||||
|
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 {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy" validate:"required,oneof=pairing open allowlist disabled"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
BotID string `json:"botId" validate:"required"`
|
||||||
|
Secret string `json:"secret" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentWecomConfig struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
BotID string `json:"botId"`
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
Installed bool `json:"installed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentDingTalkConfigUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy" validate:"required,oneof=pairing allowlist open disabled"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
SeparateSessionByConversation bool `json:"separateSessionByConversation"`
|
||||||
|
GroupSessionScope string `json:"groupSessionScope" validate:"required,oneof=group group_sender"`
|
||||||
|
SharedMemoryAcrossConversations bool `json:"sharedMemoryAcrossConversations"`
|
||||||
|
AsyncMode bool `json:"asyncMode"`
|
||||||
|
AckText string `json:"ackText"`
|
||||||
|
Bots []AgentDingTalkBot `json:"bots" validate:"required,min=1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentDingTalkConfig struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
SeparateSessionByConversation bool `json:"separateSessionByConversation"`
|
||||||
|
GroupSessionScope string `json:"groupSessionScope"`
|
||||||
|
SharedMemoryAcrossConversations bool `json:"sharedMemoryAcrossConversations"`
|
||||||
|
AsyncMode bool `json:"asyncMode"`
|
||||||
|
AckText string `json:"ackText"`
|
||||||
|
Bots []AgentDingTalkBot `json:"bots"`
|
||||||
|
Installed bool `json:"installed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentWeixinLoginReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentWeixinConfig struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentQQBotConfigUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
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 {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
GroupAllowFrom []string `json:"groupAllowFrom"`
|
||||||
|
Bots []AgentQQBotBot `json:"bots"`
|
||||||
|
Installed bool `json:"installed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginInstallReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=feishu qqbot wecom dingtalk weixin"`
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginUpgradeReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=feishu qqbot wecom dingtalk weixin"`
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginUninstallReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=feishu qqbot wecom dingtalk weixin"`
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginCheckReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Type string `json:"type" validate:"required,oneof=feishu qqbot wecom dingtalk weixin"`
|
||||||
|
CheckLatest bool `json:"checkLatest"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentPluginStatus struct {
|
||||||
|
Installed bool `json:"installed"`
|
||||||
|
CurrentVersion string `json:"currentVersion"`
|
||||||
|
LatestVersion string `json:"latestVersion"`
|
||||||
|
Upgradable bool `json:"upgradable"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentDiscordConfigUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy" validate:"required"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
RequireMention bool `json:"requireMention"`
|
||||||
|
GroupPolicy string `json:"groupPolicy" validate:"required,oneof=open allowlist disabled"`
|
||||||
|
Proxy string `json:"proxy"`
|
||||||
|
DefaultAccount string `json:"defaultAccount" validate:"required"`
|
||||||
|
Bots []AgentDiscordBot `json:"bots" validate:"required,min=1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentDiscordConfig struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
RequireMention bool `json:"requireMention"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
Proxy string `json:"proxy"`
|
||||||
|
DefaultAccount string `json:"defaultAccount"`
|
||||||
|
Bots []AgentDiscordBot `json:"bots"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentChannelBotBase struct {
|
||||||
|
AccountID string `json:"accountId"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
IsDefault bool `json:"isDefault"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b AgentChannelBotBase) IsEnabled() bool {
|
||||||
|
return b.Enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentFeishuBot struct {
|
||||||
|
AgentChannelBotBase
|
||||||
|
AppID string `json:"appId"`
|
||||||
|
AppSecret string `json:"appSecret"`
|
||||||
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentTelegramBot struct {
|
||||||
|
AgentChannelBotBase
|
||||||
|
BotToken string `json:"botToken"`
|
||||||
|
DmPolicy string `json:"dmPolicy"`
|
||||||
|
GroupPolicy string `json:"groupPolicy"`
|
||||||
|
Streaming string `json:"streaming"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentDiscordBot struct {
|
||||||
|
AgentChannelBotBase
|
||||||
|
Token string `json:"token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentQQBotBot struct {
|
||||||
|
AgentChannelBotBase
|
||||||
|
AppID string `json:"appId"`
|
||||||
|
ClientSecret string `json:"clientSecret"`
|
||||||
|
AllowFrom []string `json:"allowFrom"`
|
||||||
|
SystemPrompt string `json:"systemPrompt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentDingTalkBot struct {
|
||||||
|
AgentChannelBotBase
|
||||||
|
ClientID string `json:"clientId"`
|
||||||
|
ClientSecret string `json:"clientSecret"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentSecurityConfigUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
AllowedOrigins []string `json:"allowedOrigins"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentSecurityConfig struct {
|
||||||
|
AllowedOrigins []string `json:"allowedOrigins"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentOtherConfigUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
UserTimezone string `json:"userTimezone" validate:"required"`
|
||||||
|
BrowserEnabled bool `json:"browserEnabled"`
|
||||||
|
NPMRegistry string `json:"npmRegistry" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentOtherConfig struct {
|
||||||
|
UserTimezone string `json:"userTimezone"`
|
||||||
|
BrowserEnabled bool `json:"browserEnabled"`
|
||||||
|
NPMRegistry string `json:"npmRegistry"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentConfigFileReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentConfigFileUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Content string `json:"content" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentConfigFile struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentSkillSearchReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Source string `json:"source" validate:"required,oneof=clawhub-global clawhub-cn skillhub official skills-sh local-hub"`
|
||||||
|
Keyword string `json:"keyword" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentSkillItem struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Category string `json:"category"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
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 {
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
Identifier string `json:"identifier"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
Source string `json:"source"`
|
||||||
|
Trust string `json:"trust"`
|
||||||
|
Score string `json:"score"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentSkillUpdateReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentSkillInstallReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Source string `json:"source" validate:"required,oneof=clawhub-global clawhub-cn skillhub official skills-sh local-hub"`
|
||||||
|
Slug string `json:"slug" validate:"required"`
|
||||||
|
TaskID string `json:"taskID" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AgentSkillUninstallReq struct {
|
||||||
|
AgentID uint `json:"agentId" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
}
|
||||||
+29
-6
@@ -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 {
|
||||||
@@ -35,6 +36,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"`
|
||||||
@@ -46,6 +56,8 @@ type AlertDTO struct {
|
|||||||
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"`
|
||||||
}
|
}
|
||||||
@@ -281,11 +293,12 @@ 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"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertConfigTest struct {
|
type AlertConfigTest struct {
|
||||||
@@ -330,3 +343,13 @@ type AlertEmailConfig struct {
|
|||||||
Encryption string `json:"encryption"` // "ssl" / "tls" / "none"
|
Encryption string `json:"encryption"` // "ssl" / "tls" / "none"
|
||||||
Recipient string `json:"recipient"`
|
Recipient string `json:"recipient"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentInfo struct {
|
||||||
|
NodeName string `json:"nodeName"`
|
||||||
|
NodeAddr string `json:"nodeAddr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AlertWebhookConfig struct {
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
}
|
||||||
|
|||||||
+20
-19
@@ -84,25 +84,26 @@ type ExtraProperties struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AppProperty struct {
|
type AppProperty struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh"`
|
ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh"`
|
||||||
ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn"`
|
ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn"`
|
||||||
Description Locale `json:"description"`
|
Description Locale `json:"description"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Required []string `json:"Required"`
|
Required []string `json:"Required"`
|
||||||
CrossVersionUpdate bool `json:"crossVersionUpdate" yaml:"crossVersionUpdate"`
|
CrossVersionUpdate bool `json:"crossVersionUpdate" yaml:"crossVersionUpdate"`
|
||||||
Limit int `json:"limit" yaml:"limit"`
|
Limit int `json:"limit" yaml:"limit"`
|
||||||
Recommend int `json:"recommend" yaml:"recommend"`
|
Recommend int `json:"recommend" yaml:"recommend"`
|
||||||
Website string `json:"website"`
|
Website string `json:"website"`
|
||||||
Github string `json:"github"`
|
Github string `json:"github"`
|
||||||
Document string `json:"document"`
|
Document string `json:"document"`
|
||||||
Architectures []string `json:"architectures"`
|
Architectures []string `json:"architectures"`
|
||||||
MemoryRequired int `json:"memoryRequired" yaml:"memoryRequired"`
|
MemoryRequired int `json:"memoryRequired" yaml:"memoryRequired"`
|
||||||
GpuSupport bool `json:"gpuSupport" yaml:"gpuSupport"`
|
GpuSupport bool `json:"gpuSupport" yaml:"gpuSupport"`
|
||||||
Version float64 `json:"version"`
|
Version float64 `json:"version"`
|
||||||
Deprecated float64 `json:"deprecated"`
|
Deprecated float64 `json:"deprecated"`
|
||||||
|
BatchInstallSupport bool `json:"batchInstallSupport"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppConfigVersion struct {
|
type AppConfigVersion struct {
|
||||||
|
|||||||
+18
-15
@@ -65,25 +65,28 @@ 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"`
|
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"`
|
||||||
TaskID string `json:"taskID"`
|
StopBefore bool `json:"stopBefore"`
|
||||||
FileName string `json:"fileName"`
|
TaskID string `json:"taskID"`
|
||||||
|
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"`
|
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 {
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ type SearchPageWithType struct {
|
|||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SearchPageWithGroup struct {
|
||||||
|
PageInfo
|
||||||
|
GroupID uint `json:"groupID"`
|
||||||
|
Info string `json:"info"`
|
||||||
|
}
|
||||||
|
|
||||||
type PageInfo struct {
|
type PageInfo struct {
|
||||||
Page int `json:"page" validate:"required,number"`
|
Page int `json:"page" validate:"required,number"`
|
||||||
PageSize int `json:"pageSize" validate:"required,number"`
|
PageSize int `json:"pageSize" validate:"required,number"`
|
||||||
|
|||||||
+57
-17
@@ -48,6 +48,34 @@ type ContainerOptions struct {
|
|||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ContainerFileReq struct {
|
||||||
|
ContainerID string `json:"containerID" validate:"required"`
|
||||||
|
Path string `json:"path" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContainerFileBatchDeleteReq struct {
|
||||||
|
ContainerID string `json:"containerID" validate:"required"`
|
||||||
|
Paths []string `json:"paths" validate:"required,min=1,dive,required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContainerFileInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
IsDir bool `json:"isDir"`
|
||||||
|
IsLink bool `json:"isLink"`
|
||||||
|
LinkTo string `json:"linkTo"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
ModTime string `json:"modTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContainerFileContent struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
Truncated bool `json:"truncated"`
|
||||||
|
IsBinary bool `json:"isBinary"`
|
||||||
|
}
|
||||||
|
|
||||||
type ContainerStatus struct {
|
type ContainerStatus struct {
|
||||||
Created int `json:"created"`
|
Created int `json:"created"`
|
||||||
Running int `json:"running"`
|
Running int `json:"running"`
|
||||||
@@ -95,10 +123,16 @@ type ContainerOperate struct {
|
|||||||
Privileged bool `json:"privileged"`
|
Privileged bool `json:"privileged"`
|
||||||
AutoRemove bool `json:"autoRemove"`
|
AutoRemove bool `json:"autoRemove"`
|
||||||
Volumes []VolumeHelper `json:"volumes"`
|
Volumes []VolumeHelper `json:"volumes"`
|
||||||
|
ExtraHosts []ExtraHost `json:"extraHosts"`
|
||||||
Labels []string `json:"labels"`
|
Labels []string `json:"labels"`
|
||||||
Env []string `json:"env"`
|
Env []string `json:"env"`
|
||||||
RestartPolicy string `json:"restartPolicy"`
|
RestartPolicy string `json:"restartPolicy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ExtraHost struct {
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
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"`
|
||||||
@@ -253,16 +287,17 @@ type BatchDelete struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ComposeInfo struct {
|
type ComposeInfo struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
CreatedAt string `json:"createdAt"`
|
CreatedAt string `json:"createdAt"`
|
||||||
CreatedBy string `json:"createdBy"`
|
CreatedBy string `json:"createdBy"`
|
||||||
ContainerCount int `json:"containerCount"`
|
ContainerCount int `json:"containerCount"`
|
||||||
RunningCount int `json:"runningCount"`
|
RunningCount int `json:"runningCount"`
|
||||||
ConfigFile string `json:"configFile"`
|
ConfigFile string `json:"configFile"`
|
||||||
Workdir string `json:"workdir"`
|
Workdir string `json:"workdir"`
|
||||||
Path string `json:"path"`
|
ComposeFileExists bool `json:"composeFileExists"`
|
||||||
Containers []ComposeContainer `json:"containers"`
|
Path string `json:"path"`
|
||||||
Env string `json:"env"`
|
Containers []ComposeContainer `json:"containers"`
|
||||||
|
Env string `json:"env"`
|
||||||
}
|
}
|
||||||
type ComposeContainer struct {
|
type ComposeContainer struct {
|
||||||
ContainerID string `json:"containerID"`
|
ContainerID string `json:"containerID"`
|
||||||
@@ -272,13 +307,14 @@ type ComposeContainer struct {
|
|||||||
Ports []string `json:"ports"`
|
Ports []string `json:"ports"`
|
||||||
}
|
}
|
||||||
type ComposeCreate struct {
|
type ComposeCreate struct {
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
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"`
|
||||||
Template uint `json:"template"`
|
Template uint `json:"template"`
|
||||||
Env string `json:"env"`
|
Env string `json:"env"`
|
||||||
|
ForcePull bool `json:"forcePull"`
|
||||||
}
|
}
|
||||||
type ComposeOperation struct {
|
type ComposeOperation struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
@@ -288,11 +324,13 @@ type ComposeOperation struct {
|
|||||||
Force bool `json:"force"`
|
Force bool `json:"force"`
|
||||||
}
|
}
|
||||||
type ComposeUpdate struct {
|
type ComposeUpdate struct {
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
DetailPath string `json:"detailPath"`
|
DetailPath string `json:"detailPath"`
|
||||||
Content string `json:"content" validate:"required"`
|
Content string `json:"content" validate:"required"`
|
||||||
Env string `json:"env"`
|
Env string `json:"env"`
|
||||||
|
ForcePull bool `json:"forcePull"`
|
||||||
}
|
}
|
||||||
type ComposeLogClean struct {
|
type ComposeLogClean struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
@@ -304,6 +342,7 @@ type ContainerLog struct {
|
|||||||
Container string `json:"container" validate:"required"`
|
Container string `json:"container" validate:"required"`
|
||||||
Since string `json:"since"`
|
Since string `json:"since"`
|
||||||
Tail uint `json:"tail"`
|
Tail uint `json:"tail"`
|
||||||
|
Timestamp bool `json:"timestamp"`
|
||||||
ContainerType string `json:"containerType"`
|
ContainerType string `json:"containerType"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,5 +352,6 @@ type StreamLog struct {
|
|||||||
Since string
|
Since string
|
||||||
Follow bool
|
Follow bool
|
||||||
Tail string
|
Tail string
|
||||||
|
Timestamp bool
|
||||||
Type string
|
Type string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ type CronjobOperate struct {
|
|||||||
Timeout uint `json:"timeout" validate:"number,min=1"`
|
Timeout uint `json:"timeout" validate:"number,min=1"`
|
||||||
IgnoreErr bool `json:"ignoreErr"`
|
IgnoreErr bool `json:"ignoreErr"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
|
Args string `json:"args"`
|
||||||
|
|
||||||
AlertCount uint `json:"alertCount"`
|
AlertCount uint `json:"alertCount"`
|
||||||
AlertTitle string `json:"alertTitle"`
|
AlertTitle string `json:"alertTitle"`
|
||||||
@@ -123,6 +124,7 @@ type CronjobInfo struct {
|
|||||||
LastRecordTime string `json:"lastRecordTime"`
|
LastRecordTime string `json:"lastRecordTime"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
|
Args string `json:"args"`
|
||||||
|
|
||||||
AlertCount uint `json:"alertCount"`
|
AlertCount uint `json:"alertCount"`
|
||||||
}
|
}
|
||||||
@@ -162,6 +164,7 @@ type CronjobTrans struct {
|
|||||||
IgnoreErr bool `json:"ignoreErr"`
|
IgnoreErr bool `json:"ignoreErr"`
|
||||||
SnapshotRule SnapshotTransHelper `json:"snapshotRule"`
|
SnapshotRule SnapshotTransHelper `json:"snapshotRule"`
|
||||||
Secret string `json:"secret"`
|
Secret string `json:"secret"`
|
||||||
|
Args string `json:"args"`
|
||||||
|
|
||||||
SourceAccounts []string `json:"sourceAccounts"`
|
SourceAccounts []string `json:"sourceAccounts"`
|
||||||
DownloadAccount string `json:"downloadAccount"`
|
DownloadAccount string `json:"downloadAccount"`
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import "time"
|
|||||||
|
|
||||||
type DashboardBase struct {
|
type DashboardBase struct {
|
||||||
WebsiteNumber int `json:"websiteNumber"`
|
WebsiteNumber int `json:"websiteNumber"`
|
||||||
|
AgentNumber int `json:"agentNumber"`
|
||||||
DatabaseNumber int `json:"databaseNumber"`
|
DatabaseNumber int `json:"databaseNumber"`
|
||||||
CronjobNumber int `json:"cronjobNumber"`
|
CronjobNumber int `json:"cronjobNumber"`
|
||||||
AppInstalledNumber int `json:"appInstalledNumber"`
|
AppInstalledNumber int `json:"appInstalledNumber"`
|
||||||
|
|||||||
@@ -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"`
|
||||||
}
|
}
|
||||||
@@ -137,6 +137,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"`
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ type RuleSearch struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type FirewallOperation struct {
|
type FirewallOperation struct {
|
||||||
Operation string `json:"operation" validate:"required,oneof=start stop restart disablePing enablePing"`
|
Operation string `json:"operation" validate:"required,oneof=start stop restart disableBanPing enableBanPing"`
|
||||||
WithDockerRestart bool `json:"withDockerRestart"`
|
WithDockerRestart bool `json:"withDockerRestart"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package dto
|
package dto
|
||||||
|
|
||||||
import (
|
import "time"
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type HostOperate struct {
|
type HostOperate struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
@@ -34,11 +32,6 @@ type SearchForTree struct {
|
|||||||
Info string `json:"info"`
|
Info string `json:"info"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChangeHostGroup struct {
|
|
||||||
ID uint `json:"id" validate:"required"`
|
|
||||||
GroupID uint `json:"groupID" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type HostInfo struct {
|
type HostInfo struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
@@ -21,8 +21,8 @@ type ImageInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ImageLoad struct {
|
type ImageLoad struct {
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
Path string `json:"path" validate:"required"`
|
Paths []string `json:"paths" validate:"required,dive,required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ImageBuild struct {
|
type ImageBuild struct {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,16 @@ type AppInstallCreate struct {
|
|||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Services map[string]string `json:"services"`
|
Services map[string]string `json:"services"`
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
|
|
||||||
AppContainerConfig
|
AppContainerConfig
|
||||||
|
NodePushConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodePushConfig struct {
|
||||||
|
Nodes []string `json:"nodes"`
|
||||||
|
PushNode bool `json:"pushNode"`
|
||||||
|
AppKey string `json:"appKey"`
|
||||||
|
Version string `json:"version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppContainerConfig struct {
|
type AppContainerConfig struct {
|
||||||
@@ -45,13 +54,14 @@ type AppContainerConfig struct {
|
|||||||
|
|
||||||
type AppInstalledSearch struct {
|
type AppInstalledSearch struct {
|
||||||
dto.PageInfo
|
dto.PageInfo
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
Update bool `json:"update"`
|
Update bool `json:"update"`
|
||||||
Unused bool `json:"unused"`
|
Unused bool `json:"unused"`
|
||||||
All bool `json:"all"`
|
All bool `json:"all"`
|
||||||
Sync bool `json:"sync"`
|
Sync bool `json:"sync"`
|
||||||
|
CheckUpdate bool `json:"checkUpdate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppInstalledInfo struct {
|
type AppInstalledInfo struct {
|
||||||
@@ -128,3 +138,12 @@ type AppUpdateVersion struct {
|
|||||||
AppInstallID uint `json:"appInstallID" validate:"required"`
|
AppInstallID uint `json:"appInstallID" validate:"required"`
|
||||||
UpdateVersion string `json:"updateVersion"`
|
UpdateVersion string `json:"updateVersion"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppInstallSortItem struct {
|
||||||
|
InstallID uint `json:"installID"`
|
||||||
|
SortOrder int `json:"sortOrder"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AppInstallSort struct {
|
||||||
|
Items []AppInstallSortItem `json:"items" validate:"required"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ type DiskMountRequest struct {
|
|||||||
MountPoint string `json:"mountPoint" validate:"required"`
|
MountPoint string `json:"mountPoint" validate:"required"`
|
||||||
Filesystem string `json:"filesystem" validate:"required,oneof=ext4 xfs"`
|
Filesystem string `json:"filesystem" validate:"required,oneof=ext4 xfs"`
|
||||||
AutoMount bool `json:"autoMount"`
|
AutoMount bool `json:"autoMount"`
|
||||||
|
NoFail bool `json:"noFail"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiskUnmountRequest struct {
|
type DiskUnmountRequest struct {
|
||||||
|
|||||||
@@ -9,6 +9,29 @@ type FileOption struct {
|
|||||||
files.FileOption
|
files.FileOption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FileAISearch struct {
|
||||||
|
Path string `json:"path" validate:"required"`
|
||||||
|
Query string `json:"query" validate:"required"`
|
||||||
|
ResponseLanguage string `json:"responseLanguage,omitempty"`
|
||||||
|
ContainSub *bool `json:"containSub,omitempty"`
|
||||||
|
MaxItems int `json:"maxItems" validate:"omitempty,min=1,max=2000"`
|
||||||
|
MatchCase bool `json:"matchCase"`
|
||||||
|
WholeWord bool `json:"wholeWord"`
|
||||||
|
UseRegex bool `json:"useRegex"`
|
||||||
|
Extensions []string `json:"extensions,omitempty"`
|
||||||
|
MinSize int64 `json:"minSize"`
|
||||||
|
MaxSize int64 `json:"maxSize"`
|
||||||
|
ModifiedAfter string `json:"modifiedAfter,omitempty"`
|
||||||
|
ModifiedBefore string `json:"modifiedBefore,omitempty"`
|
||||||
|
|
||||||
|
MaxScanFiles int `json:"maxScanFiles"`
|
||||||
|
MaxFileBytes int64 `json:"maxFileBytes"`
|
||||||
|
MaxHitsPerFile int `json:"maxHitsPerFile"`
|
||||||
|
MaxTotalHits int `json:"maxTotalHits"`
|
||||||
|
ContentHitsPromptMaxBytes int `json:"contentHitsPromptMaxBytes"`
|
||||||
|
LlmMaxOutputTokens int `json:"llmMaxOutputTokens"`
|
||||||
|
}
|
||||||
|
|
||||||
type FileContentReq struct {
|
type FileContentReq struct {
|
||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
IsDetail bool `json:"isDetail"`
|
IsDetail bool `json:"isDetail"`
|
||||||
@@ -55,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 {
|
||||||
@@ -62,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 {
|
||||||
@@ -88,6 +121,7 @@ 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"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileMove struct {
|
type FileMove struct {
|
||||||
@@ -129,13 +163,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"`
|
||||||
@@ -163,3 +204,18 @@ type FileConvertRequest struct {
|
|||||||
DeleteSource bool `json:"deleteSource"`
|
DeleteSource bool `json:"deleteSource"`
|
||||||
TaskID string `json:"taskID"`
|
TaskID string `json:"taskID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FileRemarkBatch struct {
|
||||||
|
Paths []string `json:"paths" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileRemarkUpdate struct {
|
||||||
|
Path string `json:"path" validate:"required"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileShareCreate struct {
|
||||||
|
Path string `json:"path" validate:"required"`
|
||||||
|
ExpireMinutes int `json:"expireMinutes" validate:"min=0,max=10080"`
|
||||||
|
Password *string `json:"password"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
package request
|
|
||||||
@@ -45,6 +45,7 @@ type StreamConfig struct {
|
|||||||
StreamPorts string `json:"streamPorts"`
|
StreamPorts string `json:"streamPorts"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Algorithm string `json:"algorithm"`
|
Algorithm string `json:"algorithm"`
|
||||||
|
UDP bool `json:"udp"`
|
||||||
|
|
||||||
Servers []dto.NginxUpstreamServer `json:"servers"`
|
Servers []dto.NginxUpstreamServer `json:"servers"`
|
||||||
}
|
}
|
||||||
@@ -222,9 +223,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"`
|
||||||
}
|
}
|
||||||
@@ -268,9 +274,21 @@ type WebsiteProxyConfig struct {
|
|||||||
Replaces map[string]string `json:"replaces"`
|
Replaces map[string]string `json:"replaces"`
|
||||||
SNI bool `json:"sni"`
|
SNI bool `json:"sni"`
|
||||||
ProxySSLName string `json:"proxySSLName"`
|
ProxySSLName string `json:"proxySSLName"`
|
||||||
|
SSLVerify bool `json:"sslVerify"`
|
||||||
CorsConfig
|
CorsConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebsiteProxyDelete struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteProxyStatusUpdate struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
Status string `json:"status" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type CorsConfig struct {
|
type CorsConfig struct {
|
||||||
Cors bool `json:"cors"`
|
Cors bool `json:"cors"`
|
||||||
AllowOrigins string `json:"allowOrigins"`
|
AllowOrigins string `json:"allowOrigins"`
|
||||||
@@ -310,6 +328,7 @@ type WebsiteHtmlReq struct {
|
|||||||
type WebsiteHtmlUpdate struct {
|
type WebsiteHtmlUpdate struct {
|
||||||
Type string `json:"type" validate:"required"`
|
Type string `json:"type" validate:"required"`
|
||||||
Content string `json:"content" validate:"required"`
|
Content string `json:"content" validate:"required"`
|
||||||
|
Sync bool `json:"sync"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteLBCreate struct {
|
type WebsiteLBCreate struct {
|
||||||
|
|||||||
@@ -6,8 +6,12 @@ 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:"required,oneof=expire_date"`
|
OrderBy string `json:"orderBy" validate:"omitempty,oneof=created_at updated_at expire_date"`
|
||||||
Order string `json:"order" validate:"required,oneof=null ascending descending"`
|
Order string `json:"order" validate:"omitempty,oneof=null ascending descending"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebsiteSSLListReq struct {
|
||||||
|
AcmeAccountID string `json:"acmeAccountID"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteSSLCreate struct {
|
type WebsiteSSLCreate struct {
|
||||||
@@ -47,7 +51,6 @@ type WebsiteSSLApply struct {
|
|||||||
ID uint `json:"ID" validate:"required"`
|
ID uint `json:"ID" validate:"required"`
|
||||||
SkipDNSCheck bool `json:"skipDNSCheck"`
|
SkipDNSCheck bool `json:"skipDNSCheck"`
|
||||||
Nameservers []string `json:"nameservers"`
|
Nameservers []string `json:"nameservers"`
|
||||||
DisableLog bool `json:"disableLog"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteSSLObtain struct {
|
type WebsiteSSLObtain struct {
|
||||||
@@ -58,11 +61,12 @@ 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"`
|
||||||
CaDirURL string `json:"caDirURL"`
|
CaDirURL string `json:"caDirURL"`
|
||||||
|
UseEAB bool `json:"useEAB"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteAcmeAccountUpdate struct {
|
type WebsiteAcmeAccountUpdate struct {
|
||||||
@@ -134,7 +138,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"`
|
||||||
}
|
}
|
||||||
@@ -142,7 +146,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"`
|
||||||
|
|||||||
@@ -29,17 +29,18 @@ type AppDTO struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AppItem struct {
|
type AppItem struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Installed bool `json:"installed"`
|
Installed bool `json:"installed"`
|
||||||
Limit int `json:"limit"`
|
Limit int `json:"limit"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
GpuSupport bool `json:"gpuSupport"`
|
GpuSupport bool `json:"gpuSupport"`
|
||||||
Recommend int `json:"recommend"`
|
Recommend int `json:"recommend"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
BatchInstallSupport bool `json:"batchInstallSupport"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TagDTO struct {
|
type TagDTO struct {
|
||||||
@@ -75,6 +76,10 @@ type AppDetailDTO struct {
|
|||||||
GpuSupport bool `json:"gpuSupport"`
|
GpuSupport bool `json:"gpuSupport"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AppDetailSimpleDTO struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
type IgnoredApp struct {
|
type IgnoredApp struct {
|
||||||
Icon string `json:"icon"`
|
Icon string `json:"icon"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
@@ -121,6 +126,7 @@ type AppInstallDTO struct {
|
|||||||
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"`
|
||||||
App AppDetail `json:"app"`
|
App AppDetail `json:"app"`
|
||||||
Container string `json:"container"`
|
Container string `json:"container"`
|
||||||
IsEdit bool `json:"isEdit"`
|
IsEdit bool `json:"isEdit"`
|
||||||
|
|||||||
@@ -81,3 +81,45 @@ type FileConvertLog struct {
|
|||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FileRemarksRes struct {
|
||||||
|
Remarks map[string]string `json:"remarks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileShareInfo struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
FileName string `json:"fileName"`
|
||||||
|
ExpiresAt int64 `json:"expiresAt"`
|
||||||
|
Permanent bool `json:"permanent"`
|
||||||
|
HasPassword bool `json:"hasPassword"`
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileSharePublicInfo struct {
|
||||||
|
FileName string `json:"fileName"`
|
||||||
|
ExpiresAt int64 `json:"expiresAt"`
|
||||||
|
Permanent bool `json:"permanent"`
|
||||||
|
HasPassword bool `json:"hasPassword"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileAIContentHit struct {
|
||||||
|
Path string `json:"path"`
|
||||||
|
Line int `json:"line"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileAISearchResult struct {
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
Hits []FileAIContentHit `json:"hits"`
|
||||||
|
ContentScannedFiles int `json:"contentScannedFiles"`
|
||||||
|
ContentHitsTruncated bool `json:"contentHitsTruncated"`
|
||||||
|
Truncated bool `json:"truncated"`
|
||||||
|
PreFiltered bool `json:"preFiltered"`
|
||||||
|
ItemCount int `json:"itemCount"`
|
||||||
|
PromptTokens int `json:"promptTokens"`
|
||||||
|
CompletionTokens int `json:"completionTokens"`
|
||||||
|
TotalTokens int `json:"totalTokens"`
|
||||||
|
Duration string `json:"duration"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -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"`
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ type WebsiteDTO struct {
|
|||||||
SiteDir string `json:"siteDir"`
|
SiteDir string `json:"siteDir"`
|
||||||
OpenBaseDir bool `json:"openBaseDir"`
|
OpenBaseDir bool `json:"openBaseDir"`
|
||||||
Algorithm string `json:"algorithm"`
|
Algorithm string `json:"algorithm"`
|
||||||
|
UDP bool `json:"udp"`
|
||||||
|
|
||||||
Servers []dto.NginxUpstreamServer `json:"servers"`
|
Servers []dto.NginxUpstreamServer `json:"servers"`
|
||||||
}
|
}
|
||||||
@@ -39,6 +40,7 @@ type WebsiteRes struct {
|
|||||||
SSLStatus string `json:"sslStatus"`
|
SSLStatus string `json:"sslStatus"`
|
||||||
AppInstallID uint `json:"appInstallId"`
|
AppInstallID uint `json:"appInstallId"`
|
||||||
ChildSites []string `json:"childSites"`
|
ChildSites []string `json:"childSites"`
|
||||||
|
ParentSite string `json:"parentSite"`
|
||||||
RuntimeType string `json:"runtimeType"`
|
RuntimeType string `json:"runtimeType"`
|
||||||
Favorite bool `json:"favorite"`
|
Favorite bool `json:"favorite"`
|
||||||
IPV6 bool `json:"IPV6"`
|
IPV6 bool `json:"IPV6"`
|
||||||
|
|||||||
@@ -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,12 +34,18 @@ type SettingUpdate struct {
|
|||||||
Value string `json:"value"`
|
Value string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AgentSettingUpdate struct {
|
||||||
|
Key string `json:"key" validate:"required,oneof=SystemIP DockerSockPath FileRecycleBin FirewallPortWhiteList"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
type SyncTime struct {
|
type SyncTime struct {
|
||||||
NtpSite string `json:"ntpSite" validate:"required"`
|
NtpSite string `json:"ntpSite" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CleanData struct {
|
type CleanData struct {
|
||||||
SystemClean []CleanTree `json:"systemClean"`
|
SystemClean []CleanTree `json:"systemClean"`
|
||||||
|
BackupClean []CleanTree `json:"backupClean"`
|
||||||
UploadClean []CleanTree `json:"uploadClean"`
|
UploadClean []CleanTree `json:"uploadClean"`
|
||||||
DownloadClean []CleanTree `json:"downloadClean"`
|
DownloadClean []CleanTree `json:"downloadClean"`
|
||||||
SystemLogClean []CleanTree `json:"systemLogClean"`
|
SystemLogClean []CleanTree `json:"systemLogClean"`
|
||||||
@@ -54,6 +63,7 @@ type CleanTree struct {
|
|||||||
Size uint64 `json:"size"`
|
Size uint64 `json:"size"`
|
||||||
IsCheck bool `json:"isCheck"`
|
IsCheck bool `json:"isCheck"`
|
||||||
IsRecommend bool `json:"isRecommend"`
|
IsRecommend bool `json:"isRecommend"`
|
||||||
|
CanDelete bool `json:"canDelete"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Clean struct {
|
type Clean struct {
|
||||||
@@ -86,6 +96,19 @@ type SystemProxy struct {
|
|||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TerminalAIInfo struct {
|
||||||
|
AIStatus string `json:"aiStatus"`
|
||||||
|
AIAccountID string `json:"aiAccountId"`
|
||||||
|
AIPrefix string `json:"aiPrefix" validate:"required,oneof=@ai #ai /ai"`
|
||||||
|
AIRiskCommands string `json:"aiRiskCommands"`
|
||||||
|
AIRiskCommandsDefault string `json:"aiRiskCommandsDefault"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileManageAIInfo struct {
|
||||||
|
AIStatus string `json:"aiStatus"`
|
||||||
|
AIAccountID string `json:"aiAccountId"`
|
||||||
|
}
|
||||||
|
|
||||||
type CommonDescription struct {
|
type CommonDescription struct {
|
||||||
ID string `json:"id" validate:"required"`
|
ID string `json:"id" validate:"required"`
|
||||||
Type string `json:"type" validate:"required"`
|
Type string `json:"type" validate:"required"`
|
||||||
|
|||||||
+10
-3
@@ -4,7 +4,6 @@ import "time"
|
|||||||
|
|
||||||
type SSHUpdate struct {
|
type SSHUpdate struct {
|
||||||
Key string `json:"key" validate:"required"`
|
Key string `json:"key" validate:"required"`
|
||||||
OldValue string `json:"oldValue"`
|
|
||||||
NewValue string `json:"newValue"`
|
NewValue string `json:"newValue"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,10 +49,18 @@ type GenerateLoad struct {
|
|||||||
type SSHConf struct {
|
type SSHConf struct {
|
||||||
File string `json:"file"`
|
File string `json:"file"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SSHConfUpdate struct {
|
||||||
|
Key string `json:"key" validate:"required"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
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,22 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Agent struct {
|
||||||
|
BaseModel
|
||||||
|
Name string `json:"name" gorm:"not null;unique"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
AgentType string `json:"agentType" gorm:"default:openclaw"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
APIType string `json:"apiType"`
|
||||||
|
MaxTokens int `json:"maxTokens"`
|
||||||
|
ContextWindow int `json:"contextWindow"`
|
||||||
|
BaseURL string `json:"baseUrl"`
|
||||||
|
APIKey string `json:"apiKey"`
|
||||||
|
Token string `json:"token"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
AppInstallID uint `json:"appInstallId"`
|
||||||
|
WebsiteID uint `json:"websiteId"`
|
||||||
|
AccountID uint `json:"accountId"`
|
||||||
|
ConfigPath string `json:"configPath"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type AgentAccount struct {
|
||||||
|
BaseModel
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
APIKey string `json:"apiKey"`
|
||||||
|
BaseURL string `json:"baseUrl"`
|
||||||
|
APIType string `json:"apiType"`
|
||||||
|
RememberAPIKey bool `json:"rememberApiKey"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
Remark string `json:"remark"`
|
||||||
|
MasterAccountID uint `json:"masterAccountId" gorm:"index"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (AgentAccount) TableName() string {
|
||||||
|
return "agent_provider_accounts"
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type AgentAccountModel struct {
|
||||||
|
BaseModel
|
||||||
|
AccountID uint `json:"accountId" gorm:"index"`
|
||||||
|
Model string `json:"model" gorm:"index"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ContextWindow int `json:"contextWindow"`
|
||||||
|
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 {
|
||||||
|
return "agent_account_models"
|
||||||
|
}
|
||||||
@@ -9,9 +9,11 @@ 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:"advancedParam"`
|
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 {
|
||||||
@@ -19,7 +21,7 @@ type AlertTask struct {
|
|||||||
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"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AlertLog struct {
|
type AlertLog struct {
|
||||||
@@ -34,15 +36,17 @@ 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"`
|
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||||
Title string `gorm:"type:varchar(64);not null" json:"title"`
|
Title string `gorm:"type:varchar(64);not null" json:"title"`
|
||||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||||
Config string `gorm:"type:varchar(256);not null" json:"config"`
|
Config string `gorm:"type:varchar(256);not null" json:"config"`
|
||||||
|
CreateUser string `gorm:"type:varchar(256)" json:"createUser"`
|
||||||
|
UpdateUser string `gorm:"type:varchar(256)" json:"updateUser"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoginLog struct {
|
type LoginLog struct {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ type App struct {
|
|||||||
MemoryRequired int `json:"memoryRequired"`
|
MemoryRequired int `json:"memoryRequired"`
|
||||||
GpuSupport bool `json:"gpuSupport"`
|
GpuSupport bool `json:"gpuSupport"`
|
||||||
RequiredPanelVersion float64 `json:"requiredPanelVersion"`
|
RequiredPanelVersion float64 `json:"requiredPanelVersion"`
|
||||||
|
BatchInstallSupport bool `json:"batchInstallSupport" yaml:"batchInstallSupport"`
|
||||||
|
|
||||||
Details []AppDetail `json:"-" gorm:"-:migration"`
|
Details []AppDetail `json:"-" gorm:"-:migration"`
|
||||||
TagsKey []string `json:"tags" yaml:"tags" gorm:"-"`
|
TagsKey []string `json:"tags" yaml:"tags" gorm:"-"`
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ type AppInstall struct {
|
|||||||
HttpsPort int `json:"httpsPort"`
|
HttpsPort int `json:"httpsPort"`
|
||||||
WebUI string `json:"webUI"`
|
WebUI string `json:"webUI"`
|
||||||
Favorite bool `json:"favorite"`
|
Favorite bool `json:"favorite"`
|
||||||
|
SortOrder int `json:"sortOrder" gorm:"default:0"`
|
||||||
|
|
||||||
App App `json:"app" gorm:"-:migration"`
|
App App `json:"app" gorm:"-:migration"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ type Cronjob struct {
|
|||||||
Timeout uint `json:"timeout"`
|
Timeout uint `json:"timeout"`
|
||||||
IgnoreErr bool `json:"ignoreErr"`
|
IgnoreErr bool `json:"ignoreErr"`
|
||||||
RetainCopies uint64 `json:"retainCopies"`
|
RetainCopies uint64 `json:"retainCopies"`
|
||||||
|
Args string `json:"args"`
|
||||||
|
|
||||||
IsExecuting bool `json:"isExecuting"`
|
IsExecuting bool `json:"isExecuting"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
|
|||||||
@@ -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,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"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type FileShare struct {
|
||||||
|
BaseModel
|
||||||
|
Path string `gorm:"not null;uniqueIndex" json:"path"`
|
||||||
|
Token string `gorm:"not null;uniqueIndex" json:"token"`
|
||||||
|
FileName string `gorm:"not null" json:"fileName"`
|
||||||
|
ExpiresUnix int64 `json:"expiresUnix"`
|
||||||
|
PasswordEnc string `json:"-"`
|
||||||
|
PasswordSalt string `json:"passwordSalt"`
|
||||||
|
PasswordHash string `json:"passwordHash"`
|
||||||
|
MaxDownloads int `json:"maxDownloads"`
|
||||||
|
DownloadCount int `json:"downloadCount"`
|
||||||
|
}
|
||||||
@@ -8,9 +8,10 @@ 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"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteAcmeAccount) TableName() string {
|
func (w WebsiteAcmeAccount) TableName() string {
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ type WebsiteCA struct {
|
|||||||
CSR string `gorm:"not null;" json:"csr"`
|
CSR string `gorm:"not null;" json:"csr"`
|
||||||
Name string `gorm:"not null;" json:"name"`
|
Name string `gorm:"not null;" json:"name"`
|
||||||
PrivateKey string `gorm:"not null" json:"privateKey"`
|
PrivateKey string `gorm:"not null" json:"privateKey"`
|
||||||
KeyType string `gorm:"not null;default:2048" json:"keyType"`
|
KeyType string `gorm:"not null;default:RSA2048" json:"keyType"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,438 @@
|
|||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Model struct {
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
ContextWindow int
|
||||||
|
MaxTokens int
|
||||||
|
Reasoning bool
|
||||||
|
Input []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RuntimeDefault struct {
|
||||||
|
APIType string
|
||||||
|
ContextWindow int
|
||||||
|
MaxTokens int
|
||||||
|
Input []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Meta struct {
|
||||||
|
Key string
|
||||||
|
DisplayName string
|
||||||
|
Sort uint
|
||||||
|
DefaultBaseURL string
|
||||||
|
EnvKey string
|
||||||
|
Default RuntimeDefault
|
||||||
|
Models []Model
|
||||||
|
}
|
||||||
|
|
||||||
|
var catalog = map[string]Meta{
|
||||||
|
"custom": {
|
||||||
|
Key: "custom",
|
||||||
|
DisplayName: "Custom",
|
||||||
|
Sort: 10,
|
||||||
|
DefaultBaseURL: "",
|
||||||
|
EnvKey: "CUSTOM_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 128000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{},
|
||||||
|
},
|
||||||
|
"ollama": {
|
||||||
|
Key: "ollama",
|
||||||
|
DisplayName: "Ollama",
|
||||||
|
Sort: 15,
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-responses",
|
||||||
|
ContextWindow: 160000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"vllm": {
|
||||||
|
Key: "vllm",
|
||||||
|
DisplayName: "vLLM",
|
||||||
|
Sort: 20,
|
||||||
|
DefaultBaseURL: "",
|
||||||
|
EnvKey: "VLLM_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 128000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{},
|
||||||
|
},
|
||||||
|
"deepseek": {
|
||||||
|
Key: "deepseek",
|
||||||
|
DisplayName: "DeepSeek",
|
||||||
|
Sort: 25,
|
||||||
|
DefaultBaseURL: "https://api.deepseek.com/v1",
|
||||||
|
EnvKey: "DEEPSEEK_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 131072,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "deepseek/deepseek-v4-flash", Name: "deepseek-v4-flash"},
|
||||||
|
{ID: "deepseek/deepseek-v4-pro", Name: "deepseek-v4-pro"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"bailian-coding-plan": {
|
||||||
|
Key: "bailian-coding-plan",
|
||||||
|
DisplayName: "阿里云百炼 Coding Plan",
|
||||||
|
Sort: 30,
|
||||||
|
DefaultBaseURL: "https://coding.dashscope.aliyuncs.com/v1",
|
||||||
|
EnvKey: "QWEN_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 256000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "bailian-coding-plan/qwen3.5-plus", Name: "Qwen3.5-Plus", Reasoning: true},
|
||||||
|
{ID: "bailian-coding-plan/qwen3-max", Name: "Qwen3-Max", Reasoning: true},
|
||||||
|
{ID: "bailian-coding-plan/qwen3-coder-next", Name: "Qwen3-Coder-Next", Reasoning: true},
|
||||||
|
{ID: "bailian-coding-plan/qwen3-coder-plus", Name: "Qwen3-Coder-Plus", Reasoning: true},
|
||||||
|
{ID: "bailian-coding-plan/minimax-m2.5", Name: "MiniMax M2.5", Reasoning: true},
|
||||||
|
{ID: "bailian-coding-plan/glm-5", Name: "GLM-5", Reasoning: true},
|
||||||
|
{ID: "bailian-coding-plan/kimi-k2.5", Name: "Kimi-k2.5", Reasoning: true},
|
||||||
|
{ID: "bailian-coding-plan/glm-4.7", Name: "GLM-4.7", Reasoning: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ark-coding-plan": {
|
||||||
|
Key: "ark-coding-plan",
|
||||||
|
DisplayName: "方舟 Coding Plan",
|
||||||
|
Sort: 35,
|
||||||
|
DefaultBaseURL: "https://ark.cn-beijing.volces.com/api/coding/v3",
|
||||||
|
EnvKey: "ARK_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 256000,
|
||||||
|
MaxTokens: 4096,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "ark-coding-plan/ark-code-latest", Name: "Ark Coding Plan", ContextWindow: 256000, MaxTokens: 4096},
|
||||||
|
{ID: "ark-coding-plan/doubao-seed-code", Name: "Doubao Seed Code", ContextWindow: 256000, MaxTokens: 4096},
|
||||||
|
{ID: "ark-coding-plan/glm-4.7", Name: "GLM 4.7 Coding", ContextWindow: 200000, MaxTokens: 4096},
|
||||||
|
{ID: "ark-coding-plan/kimi-k2-thinking", Name: "Kimi K2 Thinking", ContextWindow: 256000, MaxTokens: 4096},
|
||||||
|
{ID: "ark-coding-plan/kimi-k2.5", Name: "Kimi K2.5 Coding", ContextWindow: 256000, MaxTokens: 4096},
|
||||||
|
{ID: "ark-coding-plan/doubao-seed-code-preview-251028", Name: "Doubao Seed Code Preview", ContextWindow: 256000, MaxTokens: 4096},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"zai": {
|
||||||
|
Key: "zai",
|
||||||
|
DisplayName: "Z.ai",
|
||||||
|
Sort: 40,
|
||||||
|
DefaultBaseURL: "https://open.bigmodel.cn/api/paas/v4",
|
||||||
|
EnvKey: "ZAI_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 204800,
|
||||||
|
MaxTokens: 131072,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "zai/glm-5", Name: "GLM-5", Reasoning: true},
|
||||||
|
{ID: "zai/glm-4.7", Name: "GLM-4.7", Reasoning: true},
|
||||||
|
{ID: "zai/glm-4.7-flash", Name: "GLM-4.7-Flash", Reasoning: true},
|
||||||
|
{ID: "zai/glm-4.7-flashx", Name: "GLM-4.7-FlashX", Reasoning: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"minimax": {
|
||||||
|
Key: "minimax",
|
||||||
|
DisplayName: "MiniMax (CN)",
|
||||||
|
Sort: 45,
|
||||||
|
DefaultBaseURL: "https://api.minimaxi.com/anthropic",
|
||||||
|
EnvKey: "MINIMAX_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "anthropic-messages",
|
||||||
|
ContextWindow: 200000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "minimax/MiniMax-M2.7", Name: "MiniMax M2.7"},
|
||||||
|
{ID: "minimax/MiniMax-M2.7-highspeed", Name: "MiniMax M2.7 highspeed"},
|
||||||
|
{ID: "minimax/MiniMax-M2.5", Name: "MiniMax M2.5", Reasoning: true},
|
||||||
|
{ID: "minimax/MiniMax-M2.5-highspeed", Name: "MiniMax M2.5 highspeed"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"xiaomi": {
|
||||||
|
Key: "xiaomi",
|
||||||
|
DisplayName: "Xiaomi",
|
||||||
|
Sort: 46,
|
||||||
|
DefaultBaseURL: "https://api.xiaomimimo.com/v1",
|
||||||
|
EnvKey: "XIAOMI_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 262144,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "xiaomi/mimo-v2-flash", Name: "Xiaomi MiMo V2 Flash", ContextWindow: 262144, MaxTokens: 8192, Input: []string{"text"}},
|
||||||
|
{ID: "xiaomi/mimo-v2-pro", Name: "Xiaomi MiMo V2 Pro", ContextWindow: 1048576, MaxTokens: 32000, Reasoning: true, Input: []string{"text"}},
|
||||||
|
{ID: "xiaomi/mimo-v2-omni", Name: "Xiaomi MiMo V2 Omni", ContextWindow: 262144, MaxTokens: 32000, Reasoning: true, Input: []string{"text", "image"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"kimi": {
|
||||||
|
Key: "kimi",
|
||||||
|
DisplayName: "Kimi (CN)",
|
||||||
|
Sort: 50,
|
||||||
|
DefaultBaseURL: "https://api.moonshot.cn/v1",
|
||||||
|
EnvKey: "KIMI_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 256000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text", "image"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "kimi/kimi-k2.5", Name: "Kimi K2.5", Reasoning: true},
|
||||||
|
{ID: "kimi/kimi-k2-0905-preview", Name: "Kimi K2 0905 Preview"},
|
||||||
|
{ID: "kimi/kimi-k2-thinking", Name: "Kimi K2 Thinking", Reasoning: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"kimi-coding": {
|
||||||
|
Key: "kimi-coding",
|
||||||
|
DisplayName: "Kimi Coding",
|
||||||
|
Sort: 51,
|
||||||
|
DefaultBaseURL: "https://api.kimi.com/coding/",
|
||||||
|
EnvKey: "KIMI_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "anthropic-messages",
|
||||||
|
ContextWindow: 262144,
|
||||||
|
MaxTokens: 32768,
|
||||||
|
Input: []string{"text", "image"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "kimi-coding/kimi-code", Name: "Kimi Code", ContextWindow: 262144, MaxTokens: 32768, Reasoning: true, Input: []string{"text", "image"}},
|
||||||
|
{ID: "kimi-coding/k2p5", Name: "Kimi K2.5", ContextWindow: 262144, MaxTokens: 32768, Reasoning: true, Input: []string{"text", "image"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"openai": {
|
||||||
|
Key: "openai",
|
||||||
|
DisplayName: "OpenAI",
|
||||||
|
Sort: 55,
|
||||||
|
DefaultBaseURL: "https://api.openai.com/v1",
|
||||||
|
EnvKey: "OPENAI_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-responses",
|
||||||
|
ContextWindow: 272000,
|
||||||
|
MaxTokens: 128000,
|
||||||
|
Input: []string{"text", "image"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "openai/gpt-5.4", Name: "gpt-5.4", ContextWindow: 272000, MaxTokens: 128000, Reasoning: true, Input: []string{"text", "image"}},
|
||||||
|
{ID: "openai/gpt-5.4-pro", Name: "gpt-5.4-pro", ContextWindow: 1050000, MaxTokens: 128000, Reasoning: true, Input: []string{"text", "image"}},
|
||||||
|
{ID: "openai/gpt-5.4-mini", Name: "gpt-5.4-mini", ContextWindow: 400000, MaxTokens: 128000, Reasoning: true, Input: []string{"text", "image"}},
|
||||||
|
{ID: "openai/gpt-5.4-nano", Name: "gpt-5.4-nano", ContextWindow: 400000, MaxTokens: 128000, Reasoning: true, Input: []string{"text", "image"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"openrouter": {
|
||||||
|
Key: "openrouter",
|
||||||
|
DisplayName: "OpenRouter",
|
||||||
|
Sort: 56,
|
||||||
|
DefaultBaseURL: "https://openrouter.ai/api/v1",
|
||||||
|
EnvKey: "OPENROUTER_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 128000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "openrouter/free", Name: "openrouter/free"},
|
||||||
|
{ID: "openrouter/auto", Name: "openrouter/auto"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"anthropic": {
|
||||||
|
Key: "anthropic",
|
||||||
|
DisplayName: "Anthropic",
|
||||||
|
Sort: 60,
|
||||||
|
DefaultBaseURL: "https://api.anthropic.com",
|
||||||
|
EnvKey: "ANTHROPIC_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "anthropic-messages",
|
||||||
|
ContextWindow: 256000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text", "image"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "anthropic/claude-sonnet-4-6", Name: "Claude Sonnet 4.6", Reasoning: true},
|
||||||
|
{ID: "anthropic/claude-opus-4-6", Name: "Claude Opus 4.6", Reasoning: true},
|
||||||
|
{ID: "anthropic/claude-opus-4-5", Name: "Claude Opus 4.5"},
|
||||||
|
{ID: "anthropic/claude-sonnet-4-5", Name: "Claude Sonnet 4.5"},
|
||||||
|
{ID: "anthropic/claude-haiku-4-5", Name: "Claude Haiku 4.5"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"gemini": {
|
||||||
|
Key: "gemini",
|
||||||
|
DisplayName: "Gemini",
|
||||||
|
Sort: 65,
|
||||||
|
DefaultBaseURL: "https://generativelanguage.googleapis.com",
|
||||||
|
EnvKey: "GEMINI_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 256000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text", "image"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "google/gemini-3-flash-preview", Name: "Gemini 3 Flash Preview", Reasoning: true},
|
||||||
|
{ID: "google/gemini-flash-latest", Name: "Gemini Flash Latest"},
|
||||||
|
{ID: "google/gemini-3-pro-preview", Name: "Gemini 3 Pro Preview", Reasoning: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"moonshot": {
|
||||||
|
Key: "moonshot",
|
||||||
|
DisplayName: "Moonshot (Global)",
|
||||||
|
Sort: 70,
|
||||||
|
DefaultBaseURL: "https://api.moonshot.ai/v1",
|
||||||
|
EnvKey: "MOONSHOT_API_KEY",
|
||||||
|
Default: RuntimeDefault{
|
||||||
|
APIType: "openai-completions",
|
||||||
|
ContextWindow: 256000,
|
||||||
|
MaxTokens: 8192,
|
||||||
|
Input: []string{"text"},
|
||||||
|
},
|
||||||
|
Models: []Model{
|
||||||
|
{ID: "moonshot/kimi-k2.5", Name: "Kimi K2.5", Reasoning: true},
|
||||||
|
{ID: "moonshot/kimi-k2-0905-preview", Name: "Kimi K2 0905 Preview"},
|
||||||
|
{ID: "moonshot/kimi-k2-thinking", Name: "Kimi K2 Thinking", Reasoning: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func Get(key string) (Meta, bool) {
|
||||||
|
meta, ok := catalog[key]
|
||||||
|
if !ok {
|
||||||
|
return Meta{}, false
|
||||||
|
}
|
||||||
|
return cloneMeta(meta), true
|
||||||
|
}
|
||||||
|
|
||||||
|
func All() map[string]Meta {
|
||||||
|
result := make(map[string]Meta, len(catalog))
|
||||||
|
for key, meta := range catalog {
|
||||||
|
result[key] = cloneMeta(meta)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultBaseURL(key string) (string, bool) {
|
||||||
|
meta, ok := catalog[key]
|
||||||
|
if !ok || strings.TrimSpace(meta.DefaultBaseURL) == "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return meta.DefaultBaseURL, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func EnvKey(key string) string {
|
||||||
|
meta, ok := catalog[key]
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return meta.EnvKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisplayName(key string) string {
|
||||||
|
meta, ok := catalog[key]
|
||||||
|
if !ok {
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
if strings.TrimSpace(meta.DisplayName) == "" {
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
return meta.DisplayName
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindModel(key, modelID string) (Model, bool) {
|
||||||
|
meta, ok := Get(key)
|
||||||
|
if !ok {
|
||||||
|
return Model{}, false
|
||||||
|
}
|
||||||
|
for _, item := range meta.Models {
|
||||||
|
if item.ID == modelID {
|
||||||
|
return item, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Model{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func cloneMeta(meta Meta) Meta {
|
||||||
|
clone := meta
|
||||||
|
if len(meta.Default.Input) > 0 {
|
||||||
|
clone.Default.Input = make([]string, len(meta.Default.Input))
|
||||||
|
copy(clone.Default.Input, meta.Default.Input)
|
||||||
|
}
|
||||||
|
if len(meta.Models) > 0 {
|
||||||
|
clone.Models = make([]Model, len(meta.Models))
|
||||||
|
for i, item := range meta.Models {
|
||||||
|
clone.Models[i] = normalizeModel(meta, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeModel(meta Meta, model Model) Model {
|
||||||
|
clone := model
|
||||||
|
clone.ID = strings.TrimSpace(clone.ID)
|
||||||
|
clone.Name = strings.TrimSpace(clone.Name)
|
||||||
|
if clone.Name == "" {
|
||||||
|
clone.Name = clone.ID
|
||||||
|
}
|
||||||
|
if clone.MaxTokens <= 0 {
|
||||||
|
clone.MaxTokens = meta.Default.MaxTokens
|
||||||
|
}
|
||||||
|
if clone.ContextWindow <= 0 {
|
||||||
|
clone.ContextWindow = meta.Default.ContextWindow
|
||||||
|
}
|
||||||
|
if len(clone.Input) == 0 && len(meta.Default.Input) > 0 {
|
||||||
|
clone.Input = make([]string, len(meta.Default.Input))
|
||||||
|
copy(clone.Input, meta.Default.Input)
|
||||||
|
}
|
||||||
|
return clone
|
||||||
|
}
|
||||||
|
|
||||||
|
func ResolveRuntimeParams(provider, apiType string, maxTokens, contextWindow int) (string, int, int) {
|
||||||
|
defaultAPIType := "openai-completions"
|
||||||
|
defaultMaxTokens := 8192
|
||||||
|
defaultContextWindow := 256000
|
||||||
|
if meta, ok := Get(provider); ok {
|
||||||
|
if meta.Default.APIType != "" {
|
||||||
|
defaultAPIType = meta.Default.APIType
|
||||||
|
}
|
||||||
|
if meta.Default.MaxTokens > 0 {
|
||||||
|
defaultMaxTokens = meta.Default.MaxTokens
|
||||||
|
}
|
||||||
|
if meta.Default.ContextWindow > 0 {
|
||||||
|
defaultContextWindow = meta.Default.ContextWindow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolvedAPI := apiType
|
||||||
|
if strings.TrimSpace(apiType) == "" {
|
||||||
|
resolvedAPI = defaultAPIType
|
||||||
|
}
|
||||||
|
resolvedMaxTokens := defaultMaxTokens
|
||||||
|
resolvedContextWindow := defaultContextWindow
|
||||||
|
if maxTokens > 0 {
|
||||||
|
resolvedMaxTokens = maxTokens
|
||||||
|
}
|
||||||
|
if contextWindow > 0 {
|
||||||
|
resolvedContextWindow = contextWindow
|
||||||
|
}
|
||||||
|
return resolvedAPI, resolvedMaxTokens, resolvedContextWindow
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OpenClawProviderPatch struct {
|
||||||
|
PrimaryModel string
|
||||||
|
ProviderKey string
|
||||||
|
ModelID string
|
||||||
|
APIKey string
|
||||||
|
BaseURL string
|
||||||
|
APIType string
|
||||||
|
AuthHeader bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildOpenClawProviderPatch(provider, modelName, apiType, baseURL, apiKey string) (*OpenClawProviderPatch, error) {
|
||||||
|
if modelName == "" {
|
||||||
|
return nil, fmt.Errorf("model is required")
|
||||||
|
}
|
||||||
|
resolvedAPIType, _, _ := ResolveRuntimeParams(provider, apiType, 0, 0)
|
||||||
|
modelID := resolveOpenClawModelID(provider, modelName)
|
||||||
|
switch provider {
|
||||||
|
case "deepseek":
|
||||||
|
return newOpenClawProviderPatch(modelName, "deepseek", modelID, apiKey, baseURL, "openai-completions", false), nil
|
||||||
|
case "gemini":
|
||||||
|
return newOpenClawProviderPatch("google/"+modelID, "google", modelID, apiKey, baseURL, resolvedAPIType, false), nil
|
||||||
|
case "moonshot", "kimi":
|
||||||
|
return buildMoonshotProviderPatch(provider, modelName, modelID, baseURL, apiKey), nil
|
||||||
|
case "bailian-coding-plan":
|
||||||
|
return newOpenClawProviderPatch("bailian-coding-plan/"+modelID, "bailian-coding-plan", modelID, apiKey, baseURL, "openai-completions", false), nil
|
||||||
|
case "ark-coding-plan":
|
||||||
|
return newOpenClawProviderPatch("ark-coding-plan/"+modelID, "ark-coding-plan", modelID, apiKey, baseURL, "openai-completions", false), nil
|
||||||
|
case "minimax":
|
||||||
|
return newOpenClawProviderPatch("minimax/"+modelID, "minimax", modelID, apiKey, baseURL, "anthropic-messages", true), nil
|
||||||
|
case "xiaomi":
|
||||||
|
return newOpenClawProviderPatch("xiaomi/"+modelID, "xiaomi", modelID, apiKey, baseURL, "openai-completions", false), nil
|
||||||
|
case "custom", "vllm":
|
||||||
|
return newOpenClawProviderPatch(provider+"/"+modelID, provider, modelID, apiKey, baseURL, resolvedAPIType, false), nil
|
||||||
|
case "ollama":
|
||||||
|
return newOpenClawProviderPatch(modelName, "ollama", modelID, "ollama", baseURL, resolvedAPIType, false), nil
|
||||||
|
case "kimi-coding":
|
||||||
|
return newOpenClawProviderPatch(modelName, "kimi-coding", modelID, apiKey, baseURL, "anthropic-messages", false), nil
|
||||||
|
case "zai":
|
||||||
|
return newOpenClawProviderPatch("zai/"+modelID, "zai", modelID, apiKey, baseURL, "openai-completions", false), nil
|
||||||
|
default:
|
||||||
|
return newOpenClawProviderPatch(modelName, provider, modelID, apiKey, baseURL, resolvedAPIType, false), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildMoonshotProviderPatch(provider, modelName, modelID, baseURL, apiKey string) *OpenClawProviderPatch {
|
||||||
|
providerKey := provider
|
||||||
|
primaryModel := modelName
|
||||||
|
if provider == "kimi" {
|
||||||
|
providerKey = "moonshot"
|
||||||
|
primaryModel = "moonshot/" + modelID
|
||||||
|
}
|
||||||
|
return newOpenClawProviderPatch(primaryModel, providerKey, modelID, apiKey, baseURL, "openai-completions", false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOpenClawProviderPatch(primaryModel, providerKey, modelID, apiKey, baseURL, apiType string, authHeader bool) *OpenClawProviderPatch {
|
||||||
|
return &OpenClawProviderPatch{
|
||||||
|
PrimaryModel: primaryModel,
|
||||||
|
ProviderKey: providerKey,
|
||||||
|
ModelID: modelID,
|
||||||
|
APIKey: apiKey,
|
||||||
|
BaseURL: baseURL,
|
||||||
|
APIType: apiType,
|
||||||
|
AuthHeader: authHeader,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveOpenClawModelID(provider, modelName string) string {
|
||||||
|
if provider == "custom" || provider == "vllm" {
|
||||||
|
target := strings.TrimLeft(modelName, "/")
|
||||||
|
if parts := strings.SplitN(target, "/", 2); len(parts) == 2 && parts[0] == "custom" {
|
||||||
|
return strings.TrimLeft(parts[1], "/")
|
||||||
|
}
|
||||||
|
return target
|
||||||
|
}
|
||||||
|
if parts := strings.SplitN(modelName, "/", 2); len(parts) == 2 {
|
||||||
|
return parts[1]
|
||||||
|
}
|
||||||
|
return modelName
|
||||||
|
}
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VerifyRequest struct {
|
||||||
|
Method string
|
||||||
|
URL string
|
||||||
|
Headers map[string]string
|
||||||
|
Body []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultVerifyTimeout = 30 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
func SkipVerification(key string) bool {
|
||||||
|
switch key {
|
||||||
|
case "custom", "vllm", "ollama", "kimi-coding":
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func VerifyAccount(provider, baseURL, apiKey string) error {
|
||||||
|
req := BuildVerifyRequest(provider, baseURL, apiKey)
|
||||||
|
var body *bytes.Buffer
|
||||||
|
if len(req.Body) > 0 {
|
||||||
|
body = bytes.NewBuffer(req.Body)
|
||||||
|
} else {
|
||||||
|
body = bytes.NewBuffer(nil)
|
||||||
|
}
|
||||||
|
httpReq, err := http.NewRequest(req.Method, req.URL, body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for key, value := range req.Headers {
|
||||||
|
httpReq.Header.Set(key, value)
|
||||||
|
}
|
||||||
|
resp, err := (&http.Client{Timeout: verifyTimeout()}).Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
return buserr.WithErr("ErrAgentAccountUnavailable", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
return buserr.WithErr("ErrAgentAccountUnavailable", fmt.Errorf("verify failed: %s", resp.Status))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyTimeout() time.Duration {
|
||||||
|
return defaultVerifyTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildVerifyRequest(provider, baseURL, apiKey string) VerifyRequest {
|
||||||
|
base := strings.TrimRight(strings.TrimSpace(baseURL), "/")
|
||||||
|
headers := map[string]string{}
|
||||||
|
request := VerifyRequest{Method: http.MethodGet, Headers: headers}
|
||||||
|
|
||||||
|
switch provider {
|
||||||
|
case "anthropic", "kimi-coding":
|
||||||
|
headers["x-api-key"] = apiKey
|
||||||
|
headers["anthropic-version"] = "2023-06-01"
|
||||||
|
if strings.Contains(base, "/v1") {
|
||||||
|
request.URL = base + "/models"
|
||||||
|
} else {
|
||||||
|
request.URL = base + "/v1/models"
|
||||||
|
}
|
||||||
|
case "gemini":
|
||||||
|
request.Method = http.MethodPost
|
||||||
|
if strings.Contains(base, "/v1beta") {
|
||||||
|
request.URL = base + "/models/gemini-3-flash-preview:generateContent"
|
||||||
|
} else {
|
||||||
|
request.URL = base + "/v1beta/models/gemini-3-flash-preview:generateContent"
|
||||||
|
}
|
||||||
|
headers["x-goog-api-key"] = apiKey
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
request.Body = mustJSON(map[string]interface{}{
|
||||||
|
"contents": []map[string]interface{}{{
|
||||||
|
"parts": []map[string]string{{
|
||||||
|
"text": "Explain how AI works in a few words",
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
case "zai":
|
||||||
|
headers["Authorization"] = fmt.Sprintf("Bearer %s", apiKey)
|
||||||
|
request.URL = base + "/models"
|
||||||
|
case "bailian-coding-plan":
|
||||||
|
request.Method = http.MethodPost
|
||||||
|
if !strings.Contains(base, "/v1") {
|
||||||
|
base = base + "/v1"
|
||||||
|
}
|
||||||
|
request.URL = base + "/chat/completions"
|
||||||
|
headers["Authorization"] = fmt.Sprintf("Bearer %s", apiKey)
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
request.Body = mustJSON(map[string]interface{}{
|
||||||
|
"model": "qwen3.5-plus",
|
||||||
|
"messages": []map[string]string{{"role": "user", "content": "test"}},
|
||||||
|
"max_tokens": 1,
|
||||||
|
})
|
||||||
|
case "ark-coding-plan":
|
||||||
|
request.Method = http.MethodPost
|
||||||
|
if !strings.Contains(base, "/api/coding/v3") {
|
||||||
|
base = "https://ark.cn-beijing.volces.com/api/coding/v3"
|
||||||
|
}
|
||||||
|
request.URL = base + "/chat/completions"
|
||||||
|
headers["Authorization"] = fmt.Sprintf("Bearer %s", apiKey)
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
request.Body = mustJSON(map[string]interface{}{
|
||||||
|
"model": "ark-code-latest",
|
||||||
|
"messages": []map[string]string{{"role": "user", "content": "test"}},
|
||||||
|
"max_tokens": 1,
|
||||||
|
})
|
||||||
|
case "minimax":
|
||||||
|
request.Method = http.MethodPost
|
||||||
|
headers["x-api-key"] = apiKey
|
||||||
|
headers["anthropic-version"] = "2023-06-01"
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
if strings.Contains(base, "/v1") {
|
||||||
|
request.URL = base + "/messages"
|
||||||
|
} else {
|
||||||
|
request.URL = base + "/v1/messages"
|
||||||
|
}
|
||||||
|
request.Body = mustJSON(map[string]interface{}{
|
||||||
|
"model": "MiniMax-M2.5",
|
||||||
|
"max_tokens": 1,
|
||||||
|
"messages": []map[string]interface{}{{
|
||||||
|
"role": "user",
|
||||||
|
"content": []map[string]string{{
|
||||||
|
"type": "text",
|
||||||
|
"text": "test",
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
case "xiaomi":
|
||||||
|
request.Method = http.MethodPost
|
||||||
|
headers["Authorization"] = fmt.Sprintf("Bearer %s", apiKey)
|
||||||
|
headers["Content-Type"] = "application/json"
|
||||||
|
if !strings.Contains(base, "/v1") {
|
||||||
|
base = base + "/v1"
|
||||||
|
}
|
||||||
|
request.URL = base + "/chat/completions"
|
||||||
|
request.Body = mustJSON(map[string]interface{}{
|
||||||
|
"model": "mimo-v2-flash",
|
||||||
|
"max_tokens": 1,
|
||||||
|
"messages": []map[string]string{{"role": "user", "content": "test"}},
|
||||||
|
})
|
||||||
|
case "openrouter":
|
||||||
|
headers["Authorization"] = fmt.Sprintf("Bearer %s", apiKey)
|
||||||
|
if strings.Contains(base, "/v1") {
|
||||||
|
request.URL = base + "/key"
|
||||||
|
} else {
|
||||||
|
request.URL = base + "/v1/key"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
headers["Authorization"] = fmt.Sprintf("Bearer %s", apiKey)
|
||||||
|
if strings.Contains(base, "/v1") {
|
||||||
|
request.URL = base + "/models"
|
||||||
|
} else {
|
||||||
|
request.URL = base + "/v1/models"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return request
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustJSON(value interface{}) []byte {
|
||||||
|
payload, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return []byte("{}")
|
||||||
|
}
|
||||||
|
return payload
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AgentRepo struct{}
|
||||||
|
|
||||||
|
type IAgentRepo interface {
|
||||||
|
Page(page, size int, opts ...DBOption) (int64, []model.Agent, error)
|
||||||
|
GetFirst(opts ...DBOption) (*model.Agent, error)
|
||||||
|
Create(agent *model.Agent) error
|
||||||
|
Save(agent *model.Agent) error
|
||||||
|
DeleteByID(id uint) error
|
||||||
|
DeleteByAppInstallID(appInstallID uint) error
|
||||||
|
DeleteByAppInstallIDWithCtx(ctx context.Context, appInstallID uint) error
|
||||||
|
ClearWebsiteIDByWebsiteIDWithCtx(ctx context.Context, websiteID uint) error
|
||||||
|
List(opts ...DBOption) ([]model.Agent, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIAgentRepo() IAgentRepo {
|
||||||
|
return &AgentRepo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) Page(page, size int, opts ...DBOption) (int64, []model.Agent, error) {
|
||||||
|
var agents []model.Agent
|
||||||
|
db := getDb(opts...).Model(&model.Agent{})
|
||||||
|
count := int64(0)
|
||||||
|
db = db.Count(&count)
|
||||||
|
err := db.Limit(size).Offset(size * (page - 1)).Find(&agents).Error
|
||||||
|
return count, agents, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) GetFirst(opts ...DBOption) (*model.Agent, error) {
|
||||||
|
var agent model.Agent
|
||||||
|
if err := getDb(opts...).First(&agent).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &agent, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) Create(agent *model.Agent) error {
|
||||||
|
return getDb().Create(agent).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) Save(agent *model.Agent) error {
|
||||||
|
return getDb().Save(agent).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) DeleteByID(id uint) error {
|
||||||
|
return getDb().Delete(&model.Agent{}, id).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) DeleteByAppInstallID(appInstallID uint) error {
|
||||||
|
if appInstallID == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return getDb().Where("app_install_id = ?", appInstallID).Delete(&model.Agent{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) DeleteByAppInstallIDWithCtx(ctx context.Context, appInstallID uint) error {
|
||||||
|
if appInstallID == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return getTx(ctx).Where("app_install_id = ?", appInstallID).Delete(&model.Agent{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) ClearWebsiteIDByWebsiteIDWithCtx(ctx context.Context, websiteID uint) error {
|
||||||
|
if websiteID == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return getTx(ctx).Model(&model.Agent{}).Where("website_id = ?", websiteID).Update("website_id", 0).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentRepo) List(opts ...DBOption) ([]model.Agent, error) {
|
||||||
|
var agents []model.Agent
|
||||||
|
if err := getDb(opts...).Find(&agents).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return agents, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AgentAccountRepo struct{}
|
||||||
|
|
||||||
|
type IAgentAccountRepo interface {
|
||||||
|
Page(page, size int, opts ...DBOption) (int64, []model.AgentAccount, error)
|
||||||
|
GetFirst(opts ...DBOption) (*model.AgentAccount, error)
|
||||||
|
WithByMasterAccountID(masterID uint) DBOption
|
||||||
|
Create(account *model.AgentAccount) error
|
||||||
|
Save(account *model.AgentAccount) error
|
||||||
|
DeleteByID(id uint) error
|
||||||
|
List(opts ...DBOption) ([]model.AgentAccount, error)
|
||||||
|
CountByProviders(providers []string) (map[string]int64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIAgentAccountRepo() IAgentAccountRepo {
|
||||||
|
return &AgentAccountRepo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountRepo) Page(page, size int, opts ...DBOption) (int64, []model.AgentAccount, error) {
|
||||||
|
var accounts []model.AgentAccount
|
||||||
|
db := getDb(opts...).Model(&model.AgentAccount{})
|
||||||
|
count := int64(0)
|
||||||
|
db = db.Count(&count)
|
||||||
|
err := db.Limit(size).Offset(size * (page - 1)).Find(&accounts).Error
|
||||||
|
return count, accounts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountRepo) GetFirst(opts ...DBOption) (*model.AgentAccount, error) {
|
||||||
|
var account model.AgentAccount
|
||||||
|
if err := getDb(opts...).First(&account).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &account, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountRepo) WithByMasterAccountID(masterID uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("master_account_id = ?", masterID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountRepo) Create(account *model.AgentAccount) error {
|
||||||
|
return getDb().Create(account).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountRepo) Save(account *model.AgentAccount) error {
|
||||||
|
return getDb().Save(account).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountRepo) DeleteByID(id uint) error {
|
||||||
|
return getDb().Delete(&model.AgentAccount{}, id).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountRepo) List(opts ...DBOption) ([]model.AgentAccount, error) {
|
||||||
|
var accounts []model.AgentAccount
|
||||||
|
if err := getDb(opts...).Find(&accounts).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return accounts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountRepo) CountByProviders(providers []string) (map[string]int64, error) {
|
||||||
|
normalizedProviders := normalizeProviders(providers)
|
||||||
|
counts := make(map[string]int64, len(normalizedProviders))
|
||||||
|
for _, provider := range normalizedProviders {
|
||||||
|
counts[provider] = 0
|
||||||
|
}
|
||||||
|
if len(normalizedProviders) == 0 {
|
||||||
|
return counts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type providerCount struct {
|
||||||
|
Provider string
|
||||||
|
Count int64
|
||||||
|
}
|
||||||
|
var rows []providerCount
|
||||||
|
if err := getDb().
|
||||||
|
Model(&model.AgentAccount{}).
|
||||||
|
Select("provider, COUNT(*) as count").
|
||||||
|
Where("provider IN ?", normalizedProviders).
|
||||||
|
Group("provider").
|
||||||
|
Scan(&rows).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, row := range rows {
|
||||||
|
counts[row.Provider] = row.Count
|
||||||
|
}
|
||||||
|
return counts, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeProviders(providers []string) []string {
|
||||||
|
seen := make(map[string]struct{}, len(providers))
|
||||||
|
result := make([]string, 0, len(providers))
|
||||||
|
for _, provider := range providers {
|
||||||
|
provider = strings.TrimSpace(provider)
|
||||||
|
if provider == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := seen[provider]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[provider] = struct{}{}
|
||||||
|
result = append(result, provider)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import "github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
|
||||||
|
type AgentAccountModelRepo struct{}
|
||||||
|
|
||||||
|
type IAgentAccountModelRepo interface {
|
||||||
|
List(opts ...DBOption) ([]model.AgentAccountModel, error)
|
||||||
|
GetFirst(opts ...DBOption) (*model.AgentAccountModel, error)
|
||||||
|
Create(item *model.AgentAccountModel) error
|
||||||
|
Save(item *model.AgentAccountModel) error
|
||||||
|
DeleteByID(id uint) error
|
||||||
|
Delete(opts ...DBOption) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIAgentAccountModelRepo() IAgentAccountModelRepo {
|
||||||
|
return &AgentAccountModelRepo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountModelRepo) List(opts ...DBOption) ([]model.AgentAccountModel, error) {
|
||||||
|
var list []model.AgentAccountModel
|
||||||
|
if err := getDb(opts...).Find(&list).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountModelRepo) GetFirst(opts ...DBOption) (*model.AgentAccountModel, error) {
|
||||||
|
var item model.AgentAccountModel
|
||||||
|
if err := getDb(opts...).First(&item).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &item, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountModelRepo) Create(item *model.AgentAccountModel) error {
|
||||||
|
return getDb().Create(item).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountModelRepo) Save(item *model.AgentAccountModel) error {
|
||||||
|
return getDb().Save(item).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountModelRepo) DeleteByID(id uint) error {
|
||||||
|
return getDb().Delete(&model.AgentAccountModel{}, id).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a AgentAccountModelRepo) Delete(opts ...DBOption) error {
|
||||||
|
return getDb(opts...).Delete(&model.AgentAccountModel{}).Error
|
||||||
|
}
|
||||||
+235
-14
@@ -1,11 +1,15 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||||
"github.com/1Panel-dev/1Panel/agent/global"
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
"google.golang.org/genproto/googleapis/type/date"
|
"google.golang.org/genproto/googleapis/type/date"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,7 +24,8 @@ type IAlertRepo interface {
|
|||||||
WithByCreateAt(date *date.Date) DBOption
|
WithByCreateAt(date *date.Date) DBOption
|
||||||
WithByLicenseId(licenseId string) DBOption
|
WithByLicenseId(licenseId string) DBOption
|
||||||
WithByRecordId(recordId uint) DBOption
|
WithByRecordId(recordId uint) DBOption
|
||||||
WithByMethod(method string) DBOption
|
WithByAlertMethodContainsConfigID(id uint) DBOption
|
||||||
|
WithByMethodConfigIDs(ids []uint) DBOption
|
||||||
|
|
||||||
Create(alert *model.Alert) error
|
Create(alert *model.Alert) error
|
||||||
Get(opts ...DBOption) (model.Alert, error)
|
Get(opts ...DBOption) (model.Alert, error)
|
||||||
@@ -47,11 +52,15 @@ type IAlertRepo interface {
|
|||||||
GetLicensePushCount(method string) (uint, error)
|
GetLicensePushCount(method string) (uint, error)
|
||||||
|
|
||||||
GetConfig(opts ...DBOption) (model.AlertConfig, error)
|
GetConfig(opts ...DBOption) (model.AlertConfig, error)
|
||||||
|
GetConfigById(id uint) (model.AlertConfig, error)
|
||||||
AlertConfigList(opts ...DBOption) ([]model.AlertConfig, error)
|
AlertConfigList(opts ...DBOption) ([]model.AlertConfig, error)
|
||||||
UpdateAlertConfig(maps map[string]interface{}, opts ...DBOption) error
|
UpdateAlertConfig(maps map[string]interface{}, opts ...DBOption) error
|
||||||
CreateAlertConfig(config *model.AlertConfig) error
|
CreateAlertConfig(config *model.AlertConfig) error
|
||||||
DeleteAlertConfig(opts ...DBOption) error
|
DeleteAlertConfig(opts ...DBOption) error
|
||||||
|
|
||||||
|
WithByTypeNotIn(types []string) DBOption
|
||||||
|
PageAlertConfig(page, size int, opts ...DBOption) (int64, []model.AlertConfig, error)
|
||||||
|
|
||||||
SyncAll(data []model.AlertConfig) error
|
SyncAll(data []model.AlertConfig) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,9 +110,20 @@ func (a *AlertRepo) WithByRecordId(recordId uint) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AlertRepo) WithByMethod(method string) DBOption {
|
func (a *AlertRepo) WithByAlertMethodContainsConfigID(id uint) DBOption {
|
||||||
|
method := strconv.Itoa(int(id))
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("method = ?", method)
|
return g.Where("(method = ? OR method LIKE ? OR method LIKE ? OR method LIKE ?)", method, method+",%", "%,"+method, "%,"+method+",%")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AlertRepo) WithByMethodConfigIDs(ids []uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
methods := make([]string, 0, len(ids))
|
||||||
|
for _, id := range ids {
|
||||||
|
methods = append(methods, strconv.Itoa(int(id)))
|
||||||
|
}
|
||||||
|
return g.Where("method IN ?", methods)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,32 +326,233 @@ func (a *AlertRepo) GetConfig(opts ...DBOption) (model.AlertConfig, error) {
|
|||||||
return alertConfig, err
|
return alertConfig, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *AlertRepo) GetConfigById(id uint) (model.AlertConfig, error) {
|
||||||
|
var config model.AlertConfig
|
||||||
|
err := global.AlertDB.First(&config, id).Error
|
||||||
|
return config, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AlertRepo) WithByTypeNotIn(types []string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("`type` NOT IN (?)", types)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AlertRepo) PageAlertConfig(page, size int, opts ...DBOption) (int64, []model.AlertConfig, error) {
|
||||||
|
var configs []model.AlertConfig
|
||||||
|
db := global.AlertDB.Model(&model.AlertConfig{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
count := int64(0)
|
||||||
|
db = db.Count(&count)
|
||||||
|
err := db.Limit(size).Offset(size * (page - 1)).Find(&configs).Error
|
||||||
|
return count, configs, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var singletonTypes = map[string]bool{
|
||||||
|
constant.CommonConfig: true,
|
||||||
|
}
|
||||||
|
|
||||||
func (a *AlertRepo) SyncAll(data []model.AlertConfig) error {
|
func (a *AlertRepo) SyncAll(data []model.AlertConfig) error {
|
||||||
tx := global.AlertDB.Begin()
|
tx := global.AlertDB.Begin()
|
||||||
|
if tx.Error != nil {
|
||||||
|
return tx.Error
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
var oldConfigs []model.AlertConfig
|
var oldConfigs []model.AlertConfig
|
||||||
_ = tx.Find(&oldConfigs).Error
|
if err := tx.Find(&oldConfigs).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
usedConfigIDs, err := loadUsedAlertConfigIDs(tx)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
oldConfigMap := make(map[string]uint)
|
oldConfigMap := make(map[string]uint)
|
||||||
|
oldConfigByType := make(map[string][]model.AlertConfig)
|
||||||
|
oldConfigByKey := make(map[string][]model.AlertConfig)
|
||||||
|
consumedConfigIDs := make(map[uint]struct{})
|
||||||
for _, item := range oldConfigs {
|
for _, item := range oldConfigs {
|
||||||
oldConfigMap[item.Type] = item.ID
|
if singletonTypes[item.Type] {
|
||||||
|
oldConfigMap[item.Type] = item.ID
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
oldConfigByType[item.Type] = append(oldConfigByType[item.Type], item)
|
||||||
|
oldConfigByKey[alertConfigSyncKey(item)] = append(oldConfigByKey[alertConfigSyncKey(item)], item)
|
||||||
}
|
}
|
||||||
for _, item := range data {
|
for _, item := range data {
|
||||||
if val, ok := oldConfigMap[item.Type]; ok {
|
if singletonTypes[item.Type] {
|
||||||
item.ID = val
|
if val, ok := oldConfigMap[item.Type]; ok {
|
||||||
delete(oldConfigMap, item.Type)
|
item.ID = val
|
||||||
} else {
|
delete(oldConfigMap, item.Type)
|
||||||
item.ID = 0
|
consumedConfigIDs[item.ID] = struct{}{}
|
||||||
|
} else {
|
||||||
|
item.ID = 0
|
||||||
|
}
|
||||||
|
if item.ID == 0 {
|
||||||
|
if err := tx.Create(&item).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err := tx.Save(&item).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
if err := tx.Model(model.AlertConfig{}).Where("id = ?", item.ID).Save(&item).Error; err != nil {
|
|
||||||
|
key := alertConfigSyncKey(item)
|
||||||
|
if matched, ok := popAlertConfigByKey(oldConfigByKey, key); ok {
|
||||||
|
item.ID = matched.ID
|
||||||
|
consumedConfigIDs[item.ID] = struct{}{}
|
||||||
|
if err := tx.Save(&item).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
deleteAlertConfigByID(oldConfigByType, matched.ID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if matched, ok := popUnusedAlertConfigByType(oldConfigByType, usedConfigIDs, item.Type); ok {
|
||||||
|
item.ID = matched.ID
|
||||||
|
consumedConfigIDs[item.ID] = struct{}{}
|
||||||
|
if err := tx.Save(&item).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
item.ID = 0
|
||||||
|
if err := tx.Create(&item).Error; err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, val := range oldConfigMap {
|
for _, item := range oldConfigs {
|
||||||
if err := tx.Where("id = ?", val).Delete(&model.AlertConfig{}).Error; err != nil {
|
if _, used := usedConfigIDs[item.ID]; used {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, kept := consumedConfigIDs[item.ID]; kept {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := tx.Where("id = ?", item.ID).Delete(&model.AlertConfig{}).Error; err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tx.Commit()
|
if err := tx.Commit().Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadUsedAlertConfigIDs(tx *gorm.DB) (map[uint]struct{}, error) {
|
||||||
|
var alerts []model.Alert
|
||||||
|
if err := tx.Select("method").Find(&alerts).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
usedIDs := make(map[uint]struct{})
|
||||||
|
for _, alert := range alerts {
|
||||||
|
for _, item := range strings.Split(alert.Method, ",") {
|
||||||
|
item = strings.TrimSpace(item)
|
||||||
|
if item == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
id, err := strconv.ParseUint(item, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
usedIDs[uint(id)] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return usedIDs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func alertConfigSyncKey(item model.AlertConfig) string {
|
||||||
|
return item.Type + "::" + normalizeAlertConfigJSON(item.Config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeAlertConfigJSON(config string) string {
|
||||||
|
trimmed := strings.TrimSpace(config)
|
||||||
|
if trimmed == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var data any
|
||||||
|
if err := json.Unmarshal([]byte(trimmed), &data); err != nil {
|
||||||
|
return trimmed
|
||||||
|
}
|
||||||
|
buf, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
return trimmed
|
||||||
|
}
|
||||||
|
return string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popAlertConfigByKey(configMap map[string][]model.AlertConfig, key string) (model.AlertConfig, bool) {
|
||||||
|
items := configMap[key]
|
||||||
|
if len(items) == 0 {
|
||||||
|
return model.AlertConfig{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
item := items[0]
|
||||||
|
if len(items) == 1 {
|
||||||
|
delete(configMap, key)
|
||||||
|
} else {
|
||||||
|
configMap[key] = items[1:]
|
||||||
|
}
|
||||||
|
return item, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func popUnusedAlertConfigByType(configMap map[string][]model.AlertConfig, usedConfigIDs map[uint]struct{}, configType string) (model.AlertConfig, bool) {
|
||||||
|
items := configMap[configType]
|
||||||
|
if len(items) == 0 {
|
||||||
|
return model.AlertConfig{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx, item := range items {
|
||||||
|
if _, used := usedConfigIDs[item.ID]; used {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if idx == 0 {
|
||||||
|
if len(items) == 1 {
|
||||||
|
delete(configMap, configType)
|
||||||
|
} else {
|
||||||
|
configMap[configType] = items[1:]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
configMap[configType] = append(items[:idx], items[idx+1:]...)
|
||||||
|
}
|
||||||
|
return item, true
|
||||||
|
}
|
||||||
|
return model.AlertConfig{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteAlertConfigByID(configMap map[string][]model.AlertConfig, id uint) {
|
||||||
|
for key, items := range configMap {
|
||||||
|
for idx, item := range items {
|
||||||
|
if item.ID != id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(items) == 1 {
|
||||||
|
delete(configMap, key)
|
||||||
|
} else {
|
||||||
|
configMap[key] = append(items[:idx], items[idx+1:]...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ type IAppRepo interface {
|
|||||||
WithResource(resource string) DBOption
|
WithResource(resource string) DBOption
|
||||||
WithNotLocal() DBOption
|
WithNotLocal() DBOption
|
||||||
WithByLikeName(name string) DBOption
|
WithByLikeName(name string) DBOption
|
||||||
|
WithKeyIn(keys []string) DBOption
|
||||||
WithArch(arch string) DBOption
|
WithArch(arch string) DBOption
|
||||||
WithPanelVersion(panelVersion string) DBOption
|
WithPanelVersion(panelVersion string) DBOption
|
||||||
|
|
||||||
@@ -55,6 +56,12 @@ func (a AppRepo) WithKey(key string) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a AppRepo) WithKeyIn(keys []string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("`key` in (?)", keys)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (a AppRepo) WithType(typeStr string) DBOption {
|
func (a AppRepo) WithType(typeStr string) DBOption {
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("type = ?", typeStr)
|
return g.Where("type = ?", typeStr)
|
||||||
|
|||||||
@@ -80,9 +80,10 @@ func (u *LauncherRepo) ListQuickJump(withAll bool) []model.QuickJump {
|
|||||||
}
|
}
|
||||||
if !withAll && len(quicks) == 0 {
|
if !withAll && len(quicks) == 0 {
|
||||||
return []model.QuickJump{
|
return []model.QuickJump{
|
||||||
|
{Name: "Agent", Title: "aiTools.agents.agent", Recommend: 1, IsShow: true, Router: "/ai/agents/agent"},
|
||||||
{Name: "Website", Title: "menu.website", Recommend: 10, IsShow: true, Router: "/websites"},
|
{Name: "Website", Title: "menu.website", Recommend: 10, IsShow: true, Router: "/websites"},
|
||||||
{Name: "Database", Title: "menu.database", Recommend: 30, IsShow: true, Router: "/databases"},
|
{Name: "Database", Title: "menu.database", Recommend: 30, IsShow: true, Router: "/databases"},
|
||||||
{Name: "Cronjob", Title: "menu.cronjob", Recommend: 50, IsShow: true, Router: "/cronjobs"},
|
{Name: "Cronjob", Title: "menu.cronjob", Recommend: 50, IsShow: false, Router: "/cronjobs"},
|
||||||
{Name: "AppInstalled", Title: "home.appInstalled", Recommend: 70, IsShow: true, Router: "/apps/installed"},
|
{Name: "AppInstalled", Title: "home.appInstalled", Recommend: 70, IsShow: true, Router: "/apps/installed"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||||
"github.com/1Panel-dev/1Panel/agent/global"
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/re"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,6 +19,12 @@ func WithByID(id uint) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithByGroupID(id uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("group_id = ?", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func WithByNOTID(id uint) DBOption {
|
func WithByNOTID(id uint) DBOption {
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("id != ?", id)
|
return g.Where("id != ?", id)
|
||||||
@@ -42,6 +49,12 @@ func WithByName(name string) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithByAddr(addr string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("addr = ?", addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func WithByKey(key string) DBOption {
|
func WithByKey(key string) DBOption {
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("key = ?", key)
|
return g.Where("key = ?", key)
|
||||||
@@ -72,6 +85,51 @@ func WithByDetailName(detailName string) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithByProvider(provider string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
if len(provider) == 0 {
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
return g.Where("provider = ?", provider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithByModel(model string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
if len(model) == 0 {
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
return g.Where("model = ?", model)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithByAccountID(accountID uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
if accountID == 0 {
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
return g.Where("account_id = ?", accountID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithByWebsiteID(websiteID uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
if websiteID == 0 {
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
return g.Where("website_id = ?", websiteID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithByAppInstallID(appInstallID uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
if appInstallID == 0 {
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
return g.Where("app_install_id = ?", appInstallID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func WithByType(tp string) DBOption {
|
func WithByType(tp string) DBOption {
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
return g.Where("`type` = ?", tp)
|
return g.Where("`type` = ?", tp)
|
||||||
@@ -124,23 +182,30 @@ func WithByCreatedAt(startTime, endTime time.Time) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithOrderBy(orderStr string) DBOption {
|
func WithOrderDesc(orderBy string) DBOption {
|
||||||
if orderStr == "createdAt" {
|
return WithOrderRuleBy(orderBy, constant.Desc)
|
||||||
orderStr = "created_at"
|
|
||||||
}
|
|
||||||
return func(g *gorm.DB) *gorm.DB {
|
|
||||||
return g.Order(orderStr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithOrderAsc(orderBy string) DBOption {
|
||||||
|
return WithOrderRuleBy(orderBy, constant.Asc)
|
||||||
|
}
|
||||||
|
|
||||||
func WithOrderRuleBy(orderBy, order string) DBOption {
|
func WithOrderRuleBy(orderBy, order string) DBOption {
|
||||||
if orderBy == "createdAt" {
|
if orderBy == "createdAt" {
|
||||||
orderBy = "created_at"
|
orderBy = "created_at"
|
||||||
}
|
}
|
||||||
|
if !re.GetRegex(re.OrderByValidationPattern).MatchString(orderBy) {
|
||||||
|
orderBy = "created_at"
|
||||||
|
}
|
||||||
switch order {
|
switch order {
|
||||||
case constant.OrderDesc:
|
case constant.OrderDesc:
|
||||||
order = "desc"
|
order = "desc"
|
||||||
case constant.OrderAsc:
|
case constant.OrderAsc:
|
||||||
order = "asc"
|
order = "asc"
|
||||||
|
case constant.Desc:
|
||||||
|
order = "desc"
|
||||||
|
case constant.Asc:
|
||||||
|
order = "asc"
|
||||||
default:
|
default:
|
||||||
orderBy = "created_at"
|
orderBy = "created_at"
|
||||||
order = "desc"
|
order = "desc"
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MongodbRepo struct{}
|
||||||
|
|
||||||
|
type IMongodbRepo interface {
|
||||||
|
Get(opts ...DBOption) (model.DatabaseMongodb, error)
|
||||||
|
WithByMongodbName(mongodbName string) DBOption
|
||||||
|
List(opts ...DBOption) ([]model.DatabaseMongodb, error)
|
||||||
|
Page(limit, offset int, opts ...DBOption) (int64, []model.DatabaseMongodb, error)
|
||||||
|
Create(ctx context.Context, mongodb *model.DatabaseMongodb) error
|
||||||
|
Delete(ctx context.Context, opts ...DBOption) error
|
||||||
|
Update(id uint, vars map[string]interface{}) error
|
||||||
|
DeleteLocal(ctx context.Context) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIMongodbRepo() IMongodbRepo {
|
||||||
|
return &MongodbRepo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MongodbRepo) Get(opts ...DBOption) (model.DatabaseMongodb, error) {
|
||||||
|
var mongodb model.DatabaseMongodb
|
||||||
|
db := global.DB
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
if err := db.First(&mongodb).Error; err != nil {
|
||||||
|
return mongodb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pass, err := encrypt.StringDecrypt(mongodb.Password)
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("decrypt mongodb db %s password failed, err: %v", mongodb.Name, err)
|
||||||
|
}
|
||||||
|
mongodb.Password = pass
|
||||||
|
return mongodb, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MongodbRepo) List(opts ...DBOption) ([]model.DatabaseMongodb, error) {
|
||||||
|
var mongodbs []model.DatabaseMongodb
|
||||||
|
db := global.DB.Model(&model.DatabaseMongodb{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
if err := db.Find(&mongodbs).Error; err != nil {
|
||||||
|
return mongodbs, err
|
||||||
|
}
|
||||||
|
for i := 0; i < len(mongodbs); i++ {
|
||||||
|
pass, err := encrypt.StringDecrypt(mongodbs[i].Password)
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("decrypt mongodb db %s password failed, err: %v", mongodbs[i].Name, err)
|
||||||
|
}
|
||||||
|
mongodbs[i].Password = pass
|
||||||
|
}
|
||||||
|
return mongodbs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MongodbRepo) Page(page, size int, opts ...DBOption) (int64, []model.DatabaseMongodb, error) {
|
||||||
|
var mongodbs []model.DatabaseMongodb
|
||||||
|
db := global.DB.Model(&model.DatabaseMongodb{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
count := int64(0)
|
||||||
|
db = db.Count(&count)
|
||||||
|
if err := db.Limit(size).Offset(size * (page - 1)).Find(&mongodbs).Error; err != nil {
|
||||||
|
return count, mongodbs, err
|
||||||
|
}
|
||||||
|
for i := 0; i < len(mongodbs); i++ {
|
||||||
|
pass, err := encrypt.StringDecrypt(mongodbs[i].Password)
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("decrypt mongodb db %s password failed, err: %v", mongodbs[i].Name, err)
|
||||||
|
}
|
||||||
|
mongodbs[i].Password = pass
|
||||||
|
}
|
||||||
|
return count, mongodbs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MongodbRepo) Create(ctx context.Context, mongodb *model.DatabaseMongodb) error {
|
||||||
|
pass, err := encrypt.StringEncrypt(mongodb.Password)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("encrypt mongodb db %s password failed, err: %v", mongodb.Name, err)
|
||||||
|
}
|
||||||
|
mongodb.Password = pass
|
||||||
|
return getTx(ctx).Create(mongodb).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MongodbRepo) Delete(ctx context.Context, opts ...DBOption) error {
|
||||||
|
return getTx(ctx, opts...).Delete(&model.DatabaseMongodb{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MongodbRepo) DeleteLocal(ctx context.Context) error {
|
||||||
|
return getTx(ctx).Where("`from` = ?", "local").Delete(&model.DatabaseMongodb{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MongodbRepo) Update(id uint, vars map[string]interface{}) error {
|
||||||
|
return global.DB.Model(&model.DatabaseMongodb{}).Where("id = ?", id).Updates(vars).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MongodbRepo) WithByMongodbName(mongodbName string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("mongodb_name = ?", mongodbName)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileHistoryRepo struct{}
|
||||||
|
|
||||||
|
type IFileHistoryRepo interface {
|
||||||
|
Get(opts ...DBOption) (model.FileHistory, error)
|
||||||
|
Page(limit, offset int, opts ...DBOption) (int64, []model.FileHistory, error)
|
||||||
|
Create(history *model.FileHistory) error
|
||||||
|
Delete(opts ...DBOption) error
|
||||||
|
DeleteByIDs(ids []uint) error
|
||||||
|
WithByID(id uint) DBOption
|
||||||
|
WithByFileID(fileID string) DBOption
|
||||||
|
WithByPath(path string) DBOption
|
||||||
|
WithByPathHash(pathHash string) DBOption
|
||||||
|
WithByPathLike(path string) DBOption
|
||||||
|
WithByOperation(operation string) DBOption
|
||||||
|
WithNotOperation(operation string) DBOption
|
||||||
|
WithByRelatedPath(path string) DBOption
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIFileHistoryRepo() IFileHistoryRepo {
|
||||||
|
return &FileHistoryRepo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) Get(opts ...DBOption) (model.FileHistory, error) {
|
||||||
|
var item model.FileHistory
|
||||||
|
db := global.DB.Model(&model.FileHistory{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
return item, db.First(&item).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) Page(limit, offset int, opts ...DBOption) (int64, []model.FileHistory, error) {
|
||||||
|
var total int64
|
||||||
|
var items []model.FileHistory
|
||||||
|
db := global.DB.Model(&model.FileHistory{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
if err := db.Count(&total).Error; err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
if err := db.Order("created_at desc").Limit(limit).Offset(offset).Find(&items).Error; err != nil {
|
||||||
|
return 0, nil, err
|
||||||
|
}
|
||||||
|
return total, items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) Create(history *model.FileHistory) error {
|
||||||
|
return global.DB.Create(history).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) Delete(opts ...DBOption) error {
|
||||||
|
db := global.DB.Model(&model.FileHistory{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
return db.Delete(&model.FileHistory{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) DeleteByIDs(ids []uint) error {
|
||||||
|
if len(ids) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return global.DB.Where("id in ?", ids).Delete(&model.FileHistory{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) WithByID(id uint) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("id = ?", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) WithByFileID(fileID string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("file_id = ?", fileID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) WithByPath(path string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("path = ?", path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) WithByPathHash(pathHash string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("path_hash = ?", pathHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) WithByPathLike(path string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("path like ?", "%"+path+"%")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) WithByOperation(operation string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("operation = ?", operation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) WithNotOperation(operation string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("operation <> ?", operation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileHistoryRepo) WithByRelatedPath(path string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("path = ? OR source_path = ? OR target_path = ?", path, path, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/global"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileShareRepo struct{}
|
||||||
|
|
||||||
|
type IFileShareRepo interface {
|
||||||
|
Page(page, size int, opts ...DBOption) (int64, []model.FileShare, error)
|
||||||
|
Create(fileShare *model.FileShare) error
|
||||||
|
Save(fileShare *model.FileShare) error
|
||||||
|
Delete(opts ...DBOption) error
|
||||||
|
GetFirst(opts ...DBOption) (model.FileShare, error)
|
||||||
|
All() ([]model.FileShare, error)
|
||||||
|
WithByPath(path string) DBOption
|
||||||
|
WithByCode(code string) DBOption
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIFileShareRepo() IFileShareRepo {
|
||||||
|
return &FileShareRepo{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileShareRepo) WithByPath(path string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("path = ?", path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileShareRepo) WithByCode(code string) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
return db.Where("token = ?", code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileShareRepo) Page(page, size int, opts ...DBOption) (int64, []model.FileShare, error) {
|
||||||
|
var (
|
||||||
|
items []model.FileShare
|
||||||
|
count int64
|
||||||
|
)
|
||||||
|
db := getDb(opts...).Model(&model.FileShare{})
|
||||||
|
db = db.Count(&count)
|
||||||
|
err := db.Order("path asc").Limit(size).Offset(size * (page - 1)).Find(&items).Error
|
||||||
|
return count, items, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileShareRepo) Create(fileShare *model.FileShare) error {
|
||||||
|
return global.DB.Create(fileShare).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileShareRepo) Save(fileShare *model.FileShare) error {
|
||||||
|
return global.DB.Save(fileShare).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileShareRepo) GetFirst(opts ...DBOption) (model.FileShare, error) {
|
||||||
|
var item model.FileShare
|
||||||
|
db := getDb(opts...).Model(&model.FileShare{})
|
||||||
|
if err := db.First(&item).Error; err != nil {
|
||||||
|
return item, err
|
||||||
|
}
|
||||||
|
return item, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileShareRepo) Delete(opts ...DBOption) error {
|
||||||
|
db := getDb(opts...).Model(&model.FileShare{})
|
||||||
|
return db.Delete(&model.FileShare{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileShareRepo) All() ([]model.FileShare, error) {
|
||||||
|
var items []model.FileShare
|
||||||
|
if err := getDb().Order("path asc").Find(&items).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
@@ -10,6 +10,18 @@ import (
|
|||||||
type HostRepo struct{}
|
type HostRepo struct{}
|
||||||
|
|
||||||
type IHostRepo interface {
|
type IHostRepo interface {
|
||||||
|
Get(opts ...DBOption) (model.Host, error)
|
||||||
|
GetList(opts ...DBOption) ([]model.Host, error)
|
||||||
|
Page(limit, offset int, opts ...DBOption) (int64, []model.Host, error)
|
||||||
|
Create(host *model.Host) error
|
||||||
|
Update(id uint, vars map[string]interface{}) error
|
||||||
|
UpdateGroup(group, newGroup uint) error
|
||||||
|
Delete(opts ...DBOption) error
|
||||||
|
|
||||||
|
WithByInfo(info string) DBOption
|
||||||
|
WithByPort(port uint) DBOption
|
||||||
|
WithByUser(user string) DBOption
|
||||||
|
|
||||||
GetFirewallRecord(opts ...DBOption) (model.Firewall, error)
|
GetFirewallRecord(opts ...DBOption) (model.Firewall, error)
|
||||||
ListFirewallRecord(opts ...DBOption) ([]model.Firewall, error)
|
ListFirewallRecord(opts ...DBOption) ([]model.Firewall, error)
|
||||||
SaveFirewallRecord(firewall *model.Firewall) error
|
SaveFirewallRecord(firewall *model.Firewall) error
|
||||||
@@ -30,6 +42,80 @@ func NewIHostRepo() IHostRepo {
|
|||||||
return &HostRepo{}
|
return &HostRepo{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) Get(opts ...DBOption) (model.Host, error) {
|
||||||
|
var host model.Host
|
||||||
|
db := global.DB
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
err := db.First(&host).Error
|
||||||
|
return host, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) GetList(opts ...DBOption) ([]model.Host, error) {
|
||||||
|
var hosts []model.Host
|
||||||
|
db := global.DB.Model(&model.Host{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
err := db.Find(&hosts).Error
|
||||||
|
return hosts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) Page(page, size int, opts ...DBOption) (int64, []model.Host, error) {
|
||||||
|
var hosts []model.Host
|
||||||
|
db := global.DB.Model(&model.Host{})
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
count := int64(0)
|
||||||
|
db = db.Count(&count)
|
||||||
|
err := db.Limit(size).Offset(size * (page - 1)).Find(&hosts).Error
|
||||||
|
return count, hosts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) WithByInfo(info string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
if len(info) == 0 {
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
infoStr := "%" + info + "%"
|
||||||
|
return g.Where("name LIKE ? OR addr LIKE ?", infoStr, infoStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) WithByPort(port uint) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("port = ?", port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) WithByUser(user string) DBOption {
|
||||||
|
return func(g *gorm.DB) *gorm.DB {
|
||||||
|
return g.Where("user = ?", user)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) Create(host *model.Host) error {
|
||||||
|
return global.DB.Create(host).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) Update(id uint, vars map[string]interface{}) error {
|
||||||
|
return global.DB.Model(&model.Host{}).Where("id = ?", id).Updates(vars).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) UpdateGroup(group, newGroup uint) error {
|
||||||
|
return global.DB.Model(&model.Host{}).Where("group_id = ?", group).Updates(map[string]interface{}{"group_id": newGroup}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HostRepo) Delete(opts ...DBOption) error {
|
||||||
|
db := global.DB
|
||||||
|
for _, opt := range opts {
|
||||||
|
db = opt(db)
|
||||||
|
}
|
||||||
|
return db.Delete(&model.Host{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
func (h *HostRepo) GetFirewallRecord(opts ...DBOption) (model.Firewall, error) {
|
func (h *HostRepo) GetFirewallRecord(opts ...DBOption) (model.Firewall, error) {
|
||||||
var firewall model.Firewall
|
var firewall model.Firewall
|
||||||
db := global.DB
|
db := global.DB
|
||||||
@@ -79,6 +165,9 @@ func (h *HostRepo) SaveFirewallRecord(firewall *model.Firewall) error {
|
|||||||
firewall.Strategy,
|
firewall.Strategy,
|
||||||
).First(&data).Error
|
).First(&data).Error
|
||||||
}
|
}
|
||||||
|
if data.ID != 0 {
|
||||||
|
firewall.ID = data.ID
|
||||||
|
}
|
||||||
return global.DB.Save(firewall).Error
|
return global.DB.Save(firewall).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,28 +73,13 @@ func (u *MonitorRepo) CreateMonitorBase(model model.MonitorBase) error {
|
|||||||
return global.MonitorDB.Create(&model).Error
|
return global.MonitorDB.Create(&model).Error
|
||||||
}
|
}
|
||||||
func (s *MonitorRepo) BatchCreateMonitorGPU(list []model.MonitorGPU) error {
|
func (s *MonitorRepo) BatchCreateMonitorGPU(list []model.MonitorGPU) error {
|
||||||
for _, item := range list {
|
return global.GPUMonitorDB.CreateInBatches(&list, len(list)).Error
|
||||||
if err := global.GPUMonitorDB.Create(&item).Error; err != nil {
|
|
||||||
global.LOG.Errorf("create Monitor GPU record failed, err: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
func (u *MonitorRepo) BatchCreateMonitorIO(list []model.MonitorIO) error {
|
func (u *MonitorRepo) BatchCreateMonitorIO(ioList []model.MonitorIO) error {
|
||||||
for _, item := range list {
|
return global.MonitorDB.CreateInBatches(ioList, len(ioList)).Error
|
||||||
if err := global.MonitorDB.Create(&item).Error; err != nil {
|
|
||||||
global.LOG.Errorf("create Monitor IO record failed, err: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
func (u *MonitorRepo) BatchCreateMonitorNet(list []model.MonitorNetwork) error {
|
func (u *MonitorRepo) BatchCreateMonitorNet(ioList []model.MonitorNetwork) error {
|
||||||
for _, item := range list {
|
return global.MonitorDB.CreateInBatches(ioList, len(ioList)).Error
|
||||||
if err := global.MonitorDB.Create(&item).Error; err != nil {
|
|
||||||
global.LOG.Errorf("create Monitor Network record failed, err: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
func (u *MonitorRepo) DelMonitorBase(timeForDelete time.Time) error {
|
func (u *MonitorRepo) DelMonitorBase(timeForDelete time.Time) error {
|
||||||
return global.MonitorDB.Where("created_at < ?", timeForDelete).Delete(&model.MonitorBase{}).Error
|
return global.MonitorDB.Where("created_at < ?", timeForDelete).Delete(&model.MonitorBase{}).Error
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
type IWebsiteRepo interface {
|
type IWebsiteRepo interface {
|
||||||
WithAppInstallId(appInstallId uint) DBOption
|
WithAppInstallId(appInstallId uint) DBOption
|
||||||
|
WithAppInstallIds(appInstallIds []uint) DBOption
|
||||||
WithDomain(domain string) DBOption
|
WithDomain(domain string) DBOption
|
||||||
WithAlias(alias string) DBOption
|
WithAlias(alias string) DBOption
|
||||||
WithWebsiteSSLID(sslId uint) DBOption
|
WithWebsiteSSLID(sslId uint) DBOption
|
||||||
@@ -48,6 +49,15 @@ func (w *WebsiteRepo) WithAppInstallId(appInstallID uint) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WebsiteRepo) WithAppInstallIds(appInstallIDs []uint) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
if len(appInstallIDs) == 0 {
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
return db.Where("app_install_id in (?)", appInstallIDs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *WebsiteRepo) WithRuntimeID(runtimeID uint) DBOption {
|
func (w *WebsiteRepo) WithRuntimeID(runtimeID uint) DBOption {
|
||||||
return func(db *gorm.DB) *gorm.DB {
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
return db.Where("runtime_id = ?", runtimeID)
|
return db.Where("runtime_id = ?", runtimeID)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ type WebsiteDomainRepo struct {
|
|||||||
|
|
||||||
type IWebsiteDomainRepo interface {
|
type IWebsiteDomainRepo interface {
|
||||||
WithWebsiteId(websiteId uint) DBOption
|
WithWebsiteId(websiteId uint) DBOption
|
||||||
|
WithWebsiteIds(websiteIds []uint) DBOption
|
||||||
WithPort(port int) DBOption
|
WithPort(port int) DBOption
|
||||||
WithDomain(domain string) DBOption
|
WithDomain(domain string) DBOption
|
||||||
WithDomainLike(domain string) DBOption
|
WithDomainLike(domain string) DBOption
|
||||||
@@ -36,6 +37,15 @@ func (w WebsiteDomainRepo) WithWebsiteId(websiteId uint) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteDomainRepo) WithWebsiteIds(websiteIds []uint) DBOption {
|
||||||
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
|
if len(websiteIds) == 0 {
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
return db.Where("website_id in (?)", websiteIds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w WebsiteDomainRepo) WithPort(port int) DBOption {
|
func (w WebsiteDomainRepo) WithPort(port int) DBOption {
|
||||||
return func(db *gorm.DB) *gorm.DB {
|
return func(db *gorm.DB) *gorm.DB {
|
||||||
return db.Where("port = ?", port)
|
return db.Where("port = ?", port)
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
|
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,6 +23,7 @@ type ISSLRepo interface {
|
|||||||
Page(page, size int, opts ...DBOption) (int64, []model.WebsiteSSL, error)
|
Page(page, size int, opts ...DBOption) (int64, []model.WebsiteSSL, error)
|
||||||
GetFirst(opts ...DBOption) (*model.WebsiteSSL, error)
|
GetFirst(opts ...DBOption) (*model.WebsiteSSL, error)
|
||||||
List(opts ...DBOption) ([]model.WebsiteSSL, error)
|
List(opts ...DBOption) ([]model.WebsiteSSL, error)
|
||||||
|
TryMarkApplying(id uint) (bool, error)
|
||||||
Create(ctx context.Context, ssl *model.WebsiteSSL) error
|
Create(ctx context.Context, ssl *model.WebsiteSSL) error
|
||||||
Save(ssl *model.WebsiteSSL) error
|
Save(ssl *model.WebsiteSSL) error
|
||||||
DeleteBy(opts ...DBOption) error
|
DeleteBy(opts ...DBOption) error
|
||||||
@@ -76,12 +79,12 @@ func (w WebsiteSSLRepo) Page(page, size int, opts ...DBOption) (int64, []model.W
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLRepo) GetFirst(opts ...DBOption) (*model.WebsiteSSL, error) {
|
func (w WebsiteSSLRepo) GetFirst(opts ...DBOption) (*model.WebsiteSSL, error) {
|
||||||
var website *model.WebsiteSSL
|
var website model.WebsiteSSL
|
||||||
db := getDb(opts...).Model(&model.WebsiteSSL{})
|
db := getDb(opts...).Model(&model.WebsiteSSL{})
|
||||||
if err := db.Preload("AcmeAccount").Preload("DnsAccount").First(&website).Error; err != nil {
|
if err := db.Preload("AcmeAccount").Preload("DnsAccount").First(&website).Error; err != nil {
|
||||||
return website, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return website, nil
|
return &website, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLRepo) List(opts ...DBOption) ([]model.WebsiteSSL, error) {
|
func (w WebsiteSSLRepo) List(opts ...DBOption) ([]model.WebsiteSSL, error) {
|
||||||
@@ -93,14 +96,25 @@ func (w WebsiteSSLRepo) List(opts ...DBOption) ([]model.WebsiteSSL, error) {
|
|||||||
return websites, nil
|
return websites, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteSSLRepo) TryMarkApplying(id uint) (bool, error) {
|
||||||
|
db := getDb().Model(&model.WebsiteSSL{}).
|
||||||
|
Where("id = ? AND status <> ?", id, constant.SSLApply).
|
||||||
|
Updates(map[string]interface{}{
|
||||||
|
"status": constant.SSLApply,
|
||||||
|
"updated_at": time.Now(),
|
||||||
|
})
|
||||||
|
if db.Error != nil {
|
||||||
|
return false, db.Error
|
||||||
|
}
|
||||||
|
return db.RowsAffected > 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLRepo) Create(ctx context.Context, ssl *model.WebsiteSSL) error {
|
func (w WebsiteSSLRepo) Create(ctx context.Context, ssl *model.WebsiteSSL) error {
|
||||||
return getTx(ctx).Create(ssl).Error
|
return getTx(ctx).Create(ssl).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLRepo) Save(ssl *model.WebsiteSSL) error {
|
func (w WebsiteSSLRepo) Save(ssl *model.WebsiteSSL) error {
|
||||||
return getDb().Model(&model.WebsiteSSL{BaseModel: model.BaseModel{
|
return getDb().Save(ssl).Error
|
||||||
ID: ssl.ID,
|
|
||||||
}}).Save(&ssl).Error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w WebsiteSSLRepo) SaveByMap(ssl *model.WebsiteSSL, params map[string]interface{}) error {
|
func (w WebsiteSSLRepo) SaveByMap(ssl *model.WebsiteSSL, params map[string]interface{}) error {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user