Compare commits
738 Commits
release-1.
...
dev
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3e6cd1cab1 | ||
![]() |
98df3806f5 | ||
![]() |
18e8af6234 | ||
![]() |
5bbda8f842 | ||
![]() |
85f8c1e634 | ||
![]() |
85c935ee46 | ||
![]() |
b4033471e7 | ||
![]() |
8dca519068 | ||
![]() |
39d8b0d98c | ||
![]() |
278a562320 | ||
![]() |
c0d8578466 | ||
![]() |
b8480e4928 | ||
![]() |
1ff39d7b85 | ||
![]() |
b1f817f09b | ||
![]() |
018fb85bc3 | ||
![]() |
bb7102d543 | ||
![]() |
1cccfeff22 | ||
![]() |
6c3a5b0ec7 | ||
![]() |
3fffb3c8ec | ||
![]() |
a51d2d15de | ||
![]() |
1c0d0d46a7 | ||
![]() |
65b8d47310 | ||
![]() |
ca586bb766 | ||
![]() |
25ccadea9e | ||
![]() |
87e9662af4 | ||
![]() |
fe705a25ea | ||
![]() |
7e5cdbf953 | ||
![]() |
e262f4fa40 | ||
![]() |
f4d5b5437e | ||
![]() |
ce258cf157 | ||
![]() |
381233a8a5 | ||
![]() |
0e8a4eaf2e | ||
![]() |
0c4400d6f7 | ||
![]() |
075ae253a1 | ||
![]() |
fc57256197 | ||
![]() |
e0f15ca783 | ||
![]() |
1931e8800a | ||
![]() |
fb4a5491eb | ||
![]() |
cd77c672bc | ||
![]() |
9b02e88e3c | ||
![]() |
2e73857b42 | ||
![]() |
7721395748 | ||
![]() |
c326606401 | ||
![]() |
c9ea6f6c8d | ||
![]() |
8c2d3e432d | ||
![]() |
20a47afb8c | ||
![]() |
07d5c580a6 | ||
![]() |
480b8acd66 | ||
![]() |
ac7e47bdf1 | ||
![]() |
a516ba9d63 | ||
![]() |
5f357db1e1 | ||
![]() |
5944f67823 | ||
![]() |
aa1e548ddf | ||
![]() |
80e845f320 | ||
![]() |
d4e6232664 | ||
![]() |
43e1ec0244 | ||
![]() |
e30546102e | ||
![]() |
70319aca45 | ||
![]() |
7c6f8ff7c4 | ||
![]() |
7eb96a35df | ||
![]() |
e52e6ddaa2 | ||
![]() |
40d3392520 | ||
![]() |
b83147220a | ||
![]() |
a031d3ba41 | ||
![]() |
df770460d6 | ||
![]() |
0f6e14d2f9 | ||
![]() |
b0320a4ebc | ||
![]() |
e4462c06fe | ||
![]() |
c7e7629d85 | ||
![]() |
d34e7492e1 | ||
![]() |
f6b84d384e | ||
![]() |
202a2ad7ae | ||
![]() |
6f6c836d9a | ||
![]() |
01d5bd047f | ||
![]() |
f000f8b46c | ||
![]() |
ae8b6b8c05 | ||
![]() |
b7d09d0201 | ||
![]() |
67bba4bc1d | ||
![]() |
a0a26f237b | ||
![]() |
a84d8dd828 | ||
![]() |
39abd4341d | ||
![]() |
b31de5e637 | ||
![]() |
09653f9c06 | ||
![]() |
e0ca9507de | ||
![]() |
b59ccc52ae | ||
![]() |
f9c8aa0484 | ||
![]() |
5629dbff8e | ||
![]() |
ed0923fd28 | ||
![]() |
489efb7ac1 | ||
![]() |
6a0b4a1176 | ||
![]() |
7a67377aa9 | ||
![]() |
40aaa1ceb0 | ||
![]() |
e83e592e0a | ||
![]() |
87a7cf3aca | ||
![]() |
2a20ff0b79 | ||
![]() |
1a6c45c526 | ||
![]() |
4d368a4de8 | ||
![]() |
b05e5736a6 | ||
![]() |
3b9f92e03f | ||
![]() |
da4c264908 | ||
![]() |
bbd649188a | ||
![]() |
cd742b0933 | ||
![]() |
7f79f5f031 | ||
![]() |
cb7351a9fb | ||
![]() |
bd5dc56b66 | ||
![]() |
34e8d88a53 | ||
![]() |
c14e192bee | ||
![]() |
d31eacd049 | ||
![]() |
f556038425 | ||
![]() |
03ed4c8071 | ||
![]() |
86ba53d6ec | ||
![]() |
0ca559f1e1 | ||
![]() |
1fd31fffd6 | ||
![]() |
c62c19a49e | ||
![]() |
aa8816f3ec | ||
![]() |
920f1112fa | ||
![]() |
4c2302dc94 | ||
![]() |
efebb26b5e | ||
![]() |
22fe2a6d51 | ||
![]() |
e17b80cff4 | ||
![]() |
1d6f1b0ef3 | ||
![]() |
dac0c81d96 | ||
![]() |
e555dcb903 | ||
![]() |
15c391e763 | ||
![]() |
3b3584714c | ||
![]() |
61a0244cfe | ||
![]() |
73a61933c5 | ||
![]() |
72c7407b0b | ||
![]() |
6538282a7b | ||
![]() |
87326e3292 | ||
![]() |
6eadb116c2 | ||
![]() |
c9ffd2564e | ||
![]() |
cd6e5f7905 | ||
![]() |
b96e988f20 | ||
![]() |
30f7fa6afa | ||
![]() |
4605b19473 | ||
![]() |
87327053dc | ||
![]() |
5e7d5c0235 | ||
![]() |
1ccc56100c | ||
![]() |
ef948bca76 | ||
![]() |
d01a964534 | ||
![]() |
05004cb141 | ||
![]() |
dfcef390d0 | ||
![]() |
ff3b41686c | ||
![]() |
7dd5082bac | ||
![]() |
ec05e81286 | ||
![]() |
e7a7d391e4 | ||
![]() |
e6b1ef30a5 | ||
![]() |
f40b053e5b | ||
![]() |
1a891cb048 | ||
![]() |
66007c07e2 | ||
![]() |
5058a814aa | ||
![]() |
37d8244414 | ||
![]() |
cda5112f5e | ||
![]() |
919f10cc11 | ||
![]() |
66b12800e4 | ||
![]() |
227856b45b | ||
![]() |
44ca529027 | ||
![]() |
885e3b60f0 | ||
![]() |
07bbf057d0 | ||
![]() |
b9227caaf8 | ||
![]() |
55ed67eaed | ||
![]() |
ac55385696 | ||
![]() |
f9b93e8c85 | ||
![]() |
ac7f33a29c | ||
![]() |
4de99f66a8 | ||
![]() |
c0c1d519bf | ||
![]() |
f22980f4ce | ||
![]() |
7b297e824c | ||
![]() |
28bd0e3cc2 | ||
![]() |
f90c009782 | ||
![]() |
a54913f788 | ||
![]() |
ea3dca79aa | ||
![]() |
2b207597b9 | ||
![]() |
044bb79ae9 | ||
![]() |
afcebb46a0 | ||
![]() |
10427ddd65 | ||
![]() |
0ac2b9df7a | ||
![]() |
695aacbe14 | ||
![]() |
71107fa42f | ||
![]() |
d36dfc5490 | ||
![]() |
a463f237b1 | ||
![]() |
ec105ede83 | ||
![]() |
92aff95b3a | ||
![]() |
1fcc345a7a | ||
![]() |
7e9a09c960 | ||
![]() |
8212ff117b | ||
![]() |
b5a1ffe338 | ||
![]() |
759382bcfb | ||
![]() |
12eeb6503c | ||
![]() |
9fa9772c07 | ||
![]() |
35334c1650 | ||
![]() |
006c27fee5 | ||
![]() |
271be81557 | ||
![]() |
b61d8aaabc | ||
![]() |
319afd2d51 | ||
![]() |
bd2facebee | ||
![]() |
3cbaa052c8 | ||
![]() |
a0ceb62372 | ||
![]() |
dddd190911 | ||
![]() |
f70b0049d9 | ||
![]() |
6fea06729e | ||
![]() |
24e6fe89c8 | ||
![]() |
e507611cad | ||
![]() |
72dcdbad1e | ||
![]() |
0a55dec949 | ||
![]() |
555a32c273 | ||
![]() |
fdf2a9d247 | ||
![]() |
30bb64d058 | ||
![]() |
695d4b4a16 | ||
![]() |
01c08a8ef9 | ||
![]() |
dd9f2edf40 | ||
![]() |
105c249d97 | ||
![]() |
b780df96af | ||
![]() |
46495937b1 | ||
![]() |
597c9ea4c0 | ||
![]() |
4662f4703c | ||
![]() |
5f750e6f49 | ||
![]() |
152ba81c34 | ||
![]() |
4bf76aacb1 | ||
![]() |
6c4c73e825 | ||
![]() |
917851dcd7 | ||
![]() |
2e5bf4202c | ||
![]() |
d4319fa55c | ||
![]() |
2ff7726442 | ||
![]() |
38bf54ec3b | ||
![]() |
a1c76600e2 | ||
![]() |
fbcb3da422 | ||
![]() |
3978fb3e46 | ||
![]() |
64f80a95ab | ||
![]() |
847c14ddda | ||
![]() |
38c0d290e7 | ||
![]() |
c403eb55b1 | ||
![]() |
506d78cb00 | ||
![]() |
27918e2dc5 | ||
![]() |
d44231a0ff | ||
![]() |
11a58fde91 | ||
![]() |
3a8c3b5816 | ||
![]() |
50deda27ca | ||
![]() |
4482fa23e6 | ||
![]() |
4c83a3bf36 | ||
![]() |
514538179e | ||
![]() |
4c8245045d | ||
![]() |
efe185e5dc | ||
![]() |
62becf819d | ||
![]() |
f02f32456e | ||
![]() |
57916ed6d7 | ||
![]() |
efa3d06673 | ||
![]() |
14f7435f82 | ||
![]() |
dbeaaa49f3 | ||
![]() |
7546391c17 | ||
![]() |
d8d2ee0f46 | ||
![]() |
3c57fa76bf | ||
![]() |
3fa4a240f7 | ||
![]() |
ae38239b47 | ||
![]() |
6a63b2e5c4 | ||
![]() |
3ead633343 | ||
![]() |
e71f765f2a | ||
![]() |
2b7f68f3fe | ||
![]() |
c82e20efd7 | ||
![]() |
aa37e3885c | ||
![]() |
7918023322 | ||
![]() |
80304937e1 | ||
![]() |
352978b54d | ||
![]() |
b7cda1d2f1 | ||
![]() |
20dbd6c181 | ||
![]() |
8808e1b0c3 | ||
![]() |
47dda4ac9f | ||
![]() |
b1d40960c4 | ||
![]() |
5222caecf9 | ||
![]() |
bc8d4cbb0f | ||
![]() |
0bb31f6caf | ||
![]() |
03c8e4d3cb | ||
![]() |
68ad653545 | ||
![]() |
fd5b34d644 | ||
![]() |
000096bc26 | ||
![]() |
02023102d3 | ||
![]() |
95bc3d9855 | ||
![]() |
f9fb16198b | ||
![]() |
11ae05163c | ||
![]() |
0275716ff5 | ||
![]() |
e9bdca5279 | ||
![]() |
cd84116a03 | ||
![]() |
457effae85 | ||
![]() |
9361c358f1 | ||
![]() |
39f952e460 | ||
![]() |
7c600a357c | ||
![]() |
8f036a0c3d | ||
![]() |
1184ae2b52 | ||
![]() |
de7ef19034 | ||
![]() |
e91b7caf4f | ||
![]() |
033b3c10c0 | ||
![]() |
97774c88d5 | ||
![]() |
95e1c73ced | ||
![]() |
d2a067db77 | ||
![]() |
586dee9e70 | ||
![]() |
6a717b2517 | ||
![]() |
203af988fa | ||
![]() |
911166152a | ||
![]() |
b3ecddb20f | ||
![]() |
a41d4e55aa | ||
![]() |
c7a3ef7d72 | ||
![]() |
b7495a63e9 | ||
![]() |
6b3093aa09 | ||
![]() |
8f8369c989 | ||
![]() |
f79293be69 | ||
![]() |
4631da2212 | ||
![]() |
e2a7c51de0 | ||
![]() |
633e26b1de | ||
![]() |
08992f83b5 | ||
![]() |
921e886e71 | ||
![]() |
9fc4cad80e | ||
![]() |
4fdb81642a | ||
![]() |
056c771d2e | ||
![]() |
84183bdfeb | ||
![]() |
4e786fee31 | ||
![]() |
9f4e5050dd | ||
![]() |
bb49a610a2 | ||
![]() |
5e3e580f51 | ||
![]() |
75fa498a7c | ||
![]() |
05e5f06cf1 | ||
![]() |
3a17f4f29f | ||
![]() |
5e7524e4f8 | ||
![]() |
b2e17d4c42 | ||
![]() |
b88303d36a | ||
![]() |
5a5b0e3a1b | ||
![]() |
e504e55a34 | ||
![]() |
b6758ff92d | ||
![]() |
957499e4d7 | ||
![]() |
3773d64aa7 | ||
![]() |
d89f823bef | ||
![]() |
a8b7c3d8c5 | ||
![]() |
9a45ce3110 | ||
![]() |
3ad3b180af | ||
![]() |
6919ce7b5c | ||
![]() |
e7a9c3814b | ||
![]() |
488eb319a1 | ||
![]() |
4f650cad9d | ||
![]() |
ce9c2e6d3c | ||
![]() |
90a5e741fd | ||
![]() |
bfedd02d1d | ||
![]() |
0187d2f5c1 | ||
![]() |
7d968348f5 | ||
![]() |
317017a2b4 | ||
![]() |
35ca52620c | ||
![]() |
01ed60fcb7 | ||
![]() |
80599a3576 | ||
![]() |
d40b2734a9 | ||
![]() |
6abd313bd2 | ||
![]() |
88f573e2a6 | ||
![]() |
eb55e16465 | ||
![]() |
bb48964cca | ||
![]() |
cbdf1ad7b7 | ||
![]() |
df77ac4318 | ||
![]() |
b3caa343d2 | ||
![]() |
49f4f316f8 | ||
![]() |
2207711400 | ||
![]() |
763f450f43 | ||
![]() |
0fa11213bb | ||
![]() |
c743775a1e | ||
![]() |
b854aa3bfe | ||
![]() |
8dfba82a70 | ||
![]() |
824051e89e | ||
![]() |
ab45cc27d5 | ||
![]() |
627e467fdf | ||
![]() |
ca3b4b02e0 | ||
![]() |
34ac685e65 | ||
![]() |
7a66e71215 | ||
![]() |
1e96a1ae84 | ||
![]() |
ce0342e235 | ||
![]() |
a48ea497b0 | ||
![]() |
4b3c9419f3 | ||
![]() |
f51b09dc40 | ||
![]() |
800f9e2d38 | ||
![]() |
b5093e4d93 | ||
![]() |
10684f9aac | ||
![]() |
7c0327c1b8 | ||
![]() |
9f5a03419e | ||
![]() |
ec843f2396 | ||
![]() |
2d6925ac4f | ||
![]() |
7cbaa4f63d | ||
![]() |
ebb9e7a2a0 | ||
![]() |
84e44127b3 | ||
![]() |
0b66bb5eff | ||
![]() |
e70ec0e978 | ||
![]() |
d62f566bb3 | ||
![]() |
4e1c3be03a | ||
![]() |
792e96e95f | ||
![]() |
c1acd8f5f0 | ||
![]() |
d64e1713fb | ||
![]() |
3e6fefe1b7 | ||
![]() |
48e3ef3e73 | ||
![]() |
c76c24e102 | ||
![]() |
4b25dafb92 | ||
![]() |
c8237d59be | ||
![]() |
c2629e3945 | ||
![]() |
b5864ca3a3 | ||
![]() |
b84c983727 | ||
![]() |
aa3e8783ae | ||
![]() |
f65f0d86aa | ||
![]() |
93b03c7212 | ||
![]() |
c96b999b2c | ||
![]() |
da155fadf2 | ||
![]() |
c69a1c8ec2 | ||
![]() |
83ac2f1ff7 | ||
![]() |
f77972fa38 | ||
![]() |
d7c08295f8 | ||
![]() |
be6b7157f4 | ||
![]() |
b979c2574c | ||
![]() |
f7c76c012f | ||
![]() |
13abe8cb66 | ||
![]() |
7596099aa1 | ||
![]() |
626782102a | ||
![]() |
3e068a0020 | ||
![]() |
09af1e9cdf | ||
![]() |
5ac9298db0 | ||
![]() |
0d084861e0 | ||
![]() |
c052887d58 | ||
![]() |
f5cd45438b | ||
![]() |
a0a1cc410f | ||
![]() |
74cfc11a37 | ||
![]() |
53600900f2 | ||
![]() |
ce19107c95 | ||
![]() |
7c56ed7b16 | ||
![]() |
152cc76e3f | ||
![]() |
8fd4060562 | ||
![]() |
c2f5908a9d | ||
![]() |
57aa2aba74 | ||
![]() |
d851aeed45 | ||
![]() |
03d338d6c9 | ||
![]() |
a74cdcc061 | ||
![]() |
4fca9aeb48 | ||
![]() |
205e32dde8 | ||
![]() |
d065558865 | ||
![]() |
950c6b9d08 | ||
![]() |
d20d5946f2 | ||
![]() |
72bc99bddc | ||
![]() |
8c4016792b | ||
![]() |
2975cf6d5a | ||
![]() |
73d93d6104 | ||
![]() |
7452cc19e0 | ||
![]() |
efd545882f | ||
![]() |
b19cdd9339 | ||
![]() |
da54794aca | ||
![]() |
a8df6d0668 | ||
![]() |
1f65d2243e | ||
![]() |
36db30471c | ||
![]() |
80e22ffc82 | ||
![]() |
872581fa4b | ||
![]() |
aeabed70db | ||
![]() |
d443103e2c | ||
![]() |
c1332235a0 | ||
![]() |
212c8634ea | ||
![]() |
b966ab3e11 | ||
![]() |
25c2246782 | ||
![]() |
2ae1db4730 | ||
![]() |
43652b2a54 | ||
![]() |
574a504ec3 | ||
![]() |
52a8331c78 | ||
![]() |
afa9eecf35 | ||
![]() |
46e13d754f | ||
![]() |
0157326d61 | ||
![]() |
7d08875f95 | ||
![]() |
bd2a49e299 | ||
![]() |
06f1d03b93 | ||
![]() |
4c39955f2f | ||
![]() |
56f92310f8 | ||
![]() |
cb47806fd6 | ||
![]() |
16ae193e9f | ||
![]() |
8770939328 | ||
![]() |
d5bff6473e | ||
![]() |
a1c0408aae | ||
![]() |
ab523b6879 | ||
![]() |
740b4c52d2 | ||
![]() |
dbb94942df | ||
![]() |
1e4ea2f8c3 | ||
![]() |
8083837333 | ||
![]() |
dd89933613 | ||
![]() |
5101dace59 | ||
![]() |
81c56a740c | ||
![]() |
27cc3bcccd | ||
![]() |
8ddaa26a57 | ||
![]() |
3a848428c3 | ||
![]() |
4c18f3aa1d | ||
![]() |
be6278c0b7 | ||
![]() |
d5e08d5db2 | ||
![]() |
2d321b4a79 | ||
![]() |
fcd764d521 | ||
![]() |
7d4a8782d8 | ||
![]() |
eea28e8481 | ||
![]() |
71d679d426 | ||
![]() |
2b23523bec | ||
![]() |
149c26728c | ||
![]() |
8c5c2440fe | ||
![]() |
f22caed20c | ||
![]() |
ed3e7e7c26 | ||
![]() |
54bc33a1a2 | ||
![]() |
900e141297 | ||
![]() |
ca1eca476c | ||
![]() |
c4d2593a42 | ||
![]() |
932811c167 | ||
![]() |
95ad101a08 | ||
![]() |
a0c329019f | ||
![]() |
8a92913230 | ||
![]() |
5a8deddc63 | ||
![]() |
2a1e60da44 | ||
![]() |
6ca3deeac1 | ||
![]() |
1b2edbb79a | ||
![]() |
49c9929a53 | ||
![]() |
8ce73a38dd | ||
![]() |
28ebf7a0cc | ||
![]() |
4f168656fc | ||
![]() |
7f1f758e60 | ||
![]() |
f8ab71953d | ||
![]() |
eb50ee1c03 | ||
![]() |
a184cb9bc4 | ||
![]() |
0b50a10fb8 | ||
![]() |
9bafdc1b0b | ||
![]() |
63af54353b | ||
![]() |
b67739af13 | ||
![]() |
40633619ca | ||
![]() |
e672d1d896 | ||
![]() |
c69d162f5a | ||
![]() |
2fd97b1753 | ||
![]() |
5f893929da | ||
![]() |
1c06b7b608 | ||
![]() |
3ac64d65b6 | ||
![]() |
f4f83283d3 | ||
![]() |
aed4a55655 | ||
![]() |
5f55a56a9e | ||
![]() |
e95e79b572 | ||
![]() |
15c0d0074b | ||
![]() |
f4716cb62f | ||
![]() |
1f2dfce7d1 | ||
![]() |
c679631440 | ||
![]() |
c62fd4841a | ||
![]() |
a073113817 | ||
![]() |
09d462b829 | ||
![]() |
379b171f0a | ||
![]() |
c424e22924 | ||
![]() |
18e171446e | ||
![]() |
c0a1555c73 | ||
![]() |
3b0c844f33 | ||
![]() |
566a4f3568 | ||
![]() |
2c8b19bff2 | ||
![]() |
292dca6419 | ||
![]() |
ebe0f98209 | ||
![]() |
eba1e5495f | ||
![]() |
0ebd04f012 | ||
![]() |
c5e8a3fa04 | ||
![]() |
42b76fd82d | ||
![]() |
bbf610569d | ||
![]() |
eeb5fa81a1 | ||
![]() |
f65ca6678f | ||
![]() |
680f48dcba | ||
![]() |
8947e00302 | ||
![]() |
b42cf32326 | ||
![]() |
5b68332b9a | ||
![]() |
d7f53862e9 | ||
![]() |
7887bf96de | ||
![]() |
db2aa35b2f | ||
![]() |
936b0e59ab | ||
![]() |
6e3923d0da | ||
![]() |
4377575206 | ||
![]() |
0c09b12680 | ||
![]() |
8a32d8032f | ||
![]() |
9f12a91f4a | ||
![]() |
dd0ca4bcaf | ||
![]() |
14cc97eb44 | ||
![]() |
2d31c5b005 | ||
![]() |
05e7506f61 | ||
![]() |
37806f1113 | ||
![]() |
79622f324b | ||
![]() |
34e84081e3 | ||
![]() |
edf07be281 | ||
![]() |
1208514f37 | ||
![]() |
bfd857ec4b | ||
![]() |
9435290bb6 | ||
![]() |
acf64dcf25 | ||
![]() |
2dd88364f8 | ||
![]() |
d900b52a50 | ||
![]() |
bd8d96be4d | ||
![]() |
17dd07fe32 | ||
![]() |
a06e5f28b3 | ||
![]() |
d5f400670c | ||
![]() |
5222388ba1 | ||
![]() |
549ccbe6a0 | ||
![]() |
7fd6afb17f | ||
![]() |
2ff4da5e46 | ||
![]() |
0f6e98be20 | ||
![]() |
4399ffa9a4 | ||
![]() |
44a1d9d16c | ||
![]() |
565fd1c605 | ||
![]() |
09ac40846f | ||
![]() |
a0b820649e | ||
![]() |
6cee4bfe7c | ||
![]() |
ad0c859b54 | ||
![]() |
d660b7d315 | ||
![]() |
2dbc7f28fd | ||
![]() |
e224bc4b24 | ||
![]() |
9c52977825 | ||
![]() |
cb151dc985 | ||
![]() |
24b9f8f705 | ||
![]() |
5592063e69 | ||
![]() |
7b19aab305 | ||
![]() |
5c50695bdc | ||
![]() |
1086597e3a | ||
![]() |
2944ea508e | ||
![]() |
5e887bd00c | ||
![]() |
76b3cf4d2b | ||
![]() |
4a9895218e | ||
![]() |
222593ea69 | ||
![]() |
05b7fd1f63 | ||
![]() |
256c04f3b8 | ||
![]() |
02577ef746 | ||
![]() |
059c3a0b80 | ||
![]() |
5ce1b1591a | ||
![]() |
6595ad6228 | ||
![]() |
e7608673d7 | ||
![]() |
4c8fc1defa | ||
![]() |
975663f0ff | ||
![]() |
9603389586 | ||
![]() |
cd79cac0af | ||
![]() |
d151e98fab | ||
![]() |
6115ffe0fc | ||
![]() |
b646c5385d | ||
![]() |
04a1cff37e | ||
![]() |
a5be9ca226 | ||
![]() |
0356bdbf54 | ||
![]() |
4c276ff383 | ||
![]() |
f8432ba521 | ||
![]() |
7f75ea06c2 | ||
![]() |
11d3e98155 | ||
![]() |
01185306f2 | ||
![]() |
6ff9c4335f | ||
![]() |
b2e38c320d | ||
![]() |
c63897ded4 | ||
![]() |
d6dcb59ab7 | ||
![]() |
bd1ced0af7 | ||
![]() |
1bbf501783 | ||
![]() |
b16308b7ea | ||
![]() |
42531dae5a | ||
![]() |
aeb9135cde | ||
![]() |
f092927ab8 | ||
![]() |
3ac467fc53 | ||
![]() |
b9e1de8446 | ||
![]() |
245bbf651b | ||
![]() |
a8b83cf4ed | ||
![]() |
38725097a6 | ||
![]() |
e935fa128f | ||
![]() |
ef16934952 | ||
![]() |
550872a564 | ||
![]() |
e746a959af | ||
![]() |
ab0f4380b2 | ||
![]() |
7c236ccc3a | ||
![]() |
52030dbea0 | ||
![]() |
4e20ec1c9b | ||
![]() |
0ddbdfeac9 | ||
![]() |
a5fd55e90e | ||
![]() |
844a6c11b4 | ||
![]() |
a4cab09b62 | ||
![]() |
12d010351a | ||
![]() |
d00e5b0421 | ||
![]() |
4c2fb7095d | ||
![]() |
cca1406f0f | ||
![]() |
1bba2664b6 | ||
![]() |
cc51eaef3f | ||
![]() |
2bd289defa | ||
![]() |
47d090d481 | ||
![]() |
4a4c2b24dd | ||
![]() |
8603d4347b | ||
![]() |
188a3e0ac5 | ||
![]() |
a22efc90f6 | ||
![]() |
d0d76c023f | ||
![]() |
241a4e62ac | ||
![]() |
295f2a5cf2 | ||
![]() |
e3cf522565 | ||
![]() |
0f1107314f | ||
![]() |
18c5c99705 | ||
![]() |
18b4c98daa | ||
![]() |
24246da71c | ||
![]() |
49ab26200d | ||
![]() |
5c524f0d23 | ||
![]() |
15d7d74c1b | ||
![]() |
29979b23c2 | ||
![]() |
3de223144d | ||
![]() |
18029d8369 | ||
![]() |
fb62ac17e5 | ||
![]() |
dbe70ecc28 | ||
![]() |
74b6af64e9 | ||
![]() |
fa83199d7b | ||
![]() |
750a2a445e | ||
![]() |
6fb1e690aa | ||
![]() |
77c0eb99f0 | ||
![]() |
db64cf02bd | ||
![]() |
57a6417812 | ||
![]() |
12beef49b5 | ||
![]() |
155363afa6 | ||
![]() |
3b3fad7278 | ||
![]() |
b6c4c4539f | ||
![]() |
807302f6cd | ||
![]() |
8902111c23 | ||
![]() |
e45ef455ef | ||
![]() |
0eb25d8413 | ||
![]() |
a0e4c266a1 | ||
![]() |
e452dfdb1f | ||
![]() |
e3b542665d | ||
![]() |
a481a8b322 | ||
![]() |
1b5387dc5a | ||
![]() |
281cf48aaa | ||
![]() |
ce2b92ee01 | ||
![]() |
daba12ee42 | ||
![]() |
363a67b0f2 | ||
![]() |
1a1a14719d | ||
![]() |
5706de5ca7 | ||
![]() |
947293f34e | ||
![]() |
04a76fd94d | ||
![]() |
c629fa9575 | ||
![]() |
d4c1caa26a | ||
![]() |
22d9bdacf6 | ||
![]() |
64a954df53 | ||
![]() |
1949be2490 | ||
![]() |
8be00dad7f | ||
![]() |
bf9a37623a | ||
![]() |
3de0ae1b0f | ||
![]() |
57a2c2616b | ||
![]() |
c63967158b | ||
![]() |
8902fdc78a | ||
![]() |
1c5d01b11c | ||
![]() |
c1c324af23 | ||
![]() |
db74d010d7 | ||
![]() |
c9d36d84f7 | ||
![]() |
d5f446d7cf | ||
![]() |
a2fcdabb7b | ||
![]() |
a434bbbc12 | ||
![]() |
2585801f8a | ||
![]() |
c501d9fefe | ||
![]() |
1d99559d4c |
34
.github/workflows/build-test.yml
vendored
Normal file
34
.github/workflows/build-test.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- dev
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
name: Build Test
|
||||
|
||||
jobs:
|
||||
build-linux-binary:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.14'
|
||||
- name: Build Web
|
||||
id: build_frontend
|
||||
run: |
|
||||
cd frontend && npm install && npm run build:pro
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: '1.20.x'
|
||||
- name: Build Server
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
args: release --snapshot --clean
|
66
.github/workflows/release-drafter.yml
vendored
Normal file
66
.github/workflows/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
on:
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
name: Create Release And Upload assets
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.14'
|
||||
- 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@v4
|
||||
with:
|
||||
go-version: '1.20.x'
|
||||
- name: Build Release
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --skip-publish --clean
|
||||
- name: Upload Assets
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
draft: true
|
||||
body: |
|
||||
# 一、安装和升级
|
||||
|
||||
## 1.1 一键安装
|
||||
```sh
|
||||
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
|
||||
```
|
||||
|
||||
## 1.2 在线升级
|
||||
|
||||
登录 1Panel Web 控制台,在页面右下角点击 **【检查更新】** 进行在线升级。
|
||||
|
||||
>更多信息请查阅在线文档:https://1panel.cn/docs/
|
||||
|
||||
# 二、更新日志
|
||||
|
||||
files: |
|
||||
dist/*.tar.gz
|
||||
dist/checksums.txt
|
||||
- name: Setup OSSUTIL
|
||||
uses: yizhoumo/setup-ossutil@v1
|
||||
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.14'
|
||||
- name: Upload Assets to OSS
|
||||
run: ossutil cp -r dist/ oss://resource-fit2cloud-com/1panel/package/stable/${{ github.ref_name }}/release/ --include "*.tar.gz" --include "checksums.txt" --only-current-dir --force
|
12
.gitignore
vendored
12
.gitignore
vendored
@@ -23,3 +23,15 @@ cmd/server/web/assets
|
||||
cmd/server/web/monacoeditorwork
|
||||
cmd/server/web/index.html
|
||||
frontend/auto-imports.d.ts
|
||||
frontend/components.d.ts
|
||||
|
||||
.history/
|
||||
dist/
|
||||
1pctl
|
||||
1panel.service
|
||||
install.sh
|
||||
quick_start.sh
|
||||
cmd/server/web/.DS_Store
|
||||
cmd/server/.DS_Store
|
||||
cmd/server/fileList.txt
|
||||
.fileList.txt
|
||||
|
58
.goreleaser.yaml
Normal file
58
.goreleaser.yaml
Normal file
@@ -0,0 +1,58 @@
|
||||
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||
# Make sure to check the documentation at https://goreleaser.com
|
||||
before:
|
||||
hooks:
|
||||
# - export NODE_OPTIONS="--max-old-space-size=8192"
|
||||
# - make build_web
|
||||
- chmod +x ./script.sh
|
||||
- ./script.sh
|
||||
- sed -i 's@ORIGINAL_VERSION=.*@ORIGINAL_VERSION=v{{ .Version }}@g' 1pctl
|
||||
- go mod tidy
|
||||
|
||||
builds:
|
||||
- main: ./cmd/server/main.go
|
||||
binary: 1panel
|
||||
flags:
|
||||
- -trimpath
|
||||
ldflags:
|
||||
- -w -s
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
goarm:
|
||||
- 7
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
- arm
|
||||
- ppc64le
|
||||
- s390x
|
||||
|
||||
archives:
|
||||
- format: tar.gz
|
||||
name_template: "1panel-v{{ .Version }}-{{ .Os }}-{{ .Arch }}{{- if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
wrap_in_directory: true
|
||||
files:
|
||||
- 1pctl
|
||||
- 1panel.service
|
||||
- install.sh
|
||||
- README.md
|
||||
- LICENSE
|
||||
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
snapshot:
|
||||
name_template: "{{ incpatch .Version }}-next"
|
||||
release:
|
||||
draft: true
|
||||
mode: append
|
||||
extra_files:
|
||||
- glob: dist/*.tar.gz
|
||||
- glob: dist/checksums.txt
|
||||
name_template: "Release {{.Tag}}"
|
||||
|
||||
# The lines beneath this are called `modelines`. See `:help modeline`
|
||||
# Feel free to remove those if you don't want/use them.
|
||||
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"ansible.python.interpreterPath": "/opt/homebrew/bin/python3"
|
||||
}
|
23
Makefile
23
Makefile
@@ -10,16 +10,25 @@ WEB_PATH=$(BASE_PAH)/frontend
|
||||
SERVER_PATH=$(BASE_PAH)/backend
|
||||
MAIN= $(BASE_PAH)/cmd/server/main.go
|
||||
APP_NAME=1panel
|
||||
ASSERT_PATH= $(BASE_PAH)/cmd/server/web/assets
|
||||
|
||||
build_web:
|
||||
cd $(WEB_PATH) && npm install && npm run build:dev
|
||||
clean_assets:
|
||||
rm -rf $(ASSERT_PATH)
|
||||
|
||||
build_bin:
|
||||
upx_bin:
|
||||
upx $(BUILD_PATH)/$(APP_NAME)
|
||||
|
||||
build_frontend:
|
||||
cd $(WEB_PATH) && npm install && npm run build:pro
|
||||
|
||||
build_backend_on_linux:
|
||||
cd $(SERVER_PATH) \
|
||||
&& CGO_ENABLED=1 GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -trimpath -ldflags '-s -w --extldflags "-static -fpic"' -tags 'osusergo,netgo' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
|
||||
&& GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
|
||||
|
||||
build_linux_on_mac:
|
||||
build_backend_on_darwin:
|
||||
cd $(SERVER_PATH) \
|
||||
&& CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CXX=x86_64-linux-musl-g++ $(GOBUILD) -trimpath -ldflags '-s -w --extldflags "-static -fpic"' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
|
||||
&& GOOS=linux GOARCH=amd64 $(GOBUILD) -trimpath -ldflags '-s -w' -o $(BUILD_PATH)/$(APP_NAME) $(MAIN)
|
||||
|
||||
build_all: build_web build_bin
|
||||
build_all: build_frontend build_backend_on_linux
|
||||
|
||||
build_on_local: clean_assets build_frontend build_backend_on_darwin upx_bin
|
||||
|
18
README.md
18
README.md
@@ -6,6 +6,7 @@
|
||||
<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://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
|
||||
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
|
||||
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel?ref=badge_shield"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel.svg?type=shield" alt="FOSSA Status"></a>
|
||||
</p>
|
||||
|
||||
------------------------------
|
||||
@@ -13,9 +14,9 @@
|
||||
1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。1Panel 的功能和优势包括:
|
||||
|
||||
- **快速建站**:深度集成 Wordpress 和 [Halo](https://github.com/halo-dev/halo/),域名绑定、SSL 证书配置等一键搞定;
|
||||
- **高效管理**:通过 Web 端轻松管理 Linux 服务器,包括应用管理、主机监控、文件管理、数据库管理、容器管理等;
|
||||
- **安全可靠**:最小漏洞暴露面,提供防火墙和安全审计等功能;
|
||||
- **一键备份**:支持一键备份和恢复,备份数据云端存储,永不丢失。
|
||||
- **高效管理**:通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理等;
|
||||
- **安全可靠**:基于容器来管理和部署应用,最小漏洞暴露面,提供防火墙和日志审计等功能;
|
||||
- **一键备份**:支持一键备份和恢复,备份数据到各类云端存储,永不丢失。
|
||||
|
||||
## UI 展示
|
||||
|
||||
@@ -41,12 +42,9 @@ curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_
|
||||
|
||||
- [在线文档](https://1panel.cn/docs/)
|
||||
- [教学视频](https://space.bilibili.com/510493147/channel/collectiondetail?sid=1199760)
|
||||
- [社区论坛](https://bbs.fit2cloud.com/c/1p/7)
|
||||
|
||||
## 社区
|
||||
|
||||
如果您在使用过程中有任何疑问或对建议,欢迎提交 GitHub Issue 或加入到我们微信交流群进行交流沟通。
|
||||
|
||||
**微信交流群**
|
||||
**加入微信交流群**
|
||||
|
||||
<img src="https://1panel.cn/img/wechat-group.jpg" width="156" height="156"/>
|
||||
|
||||
@@ -61,6 +59,10 @@ curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_
|
||||
|
||||
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
||||
|
||||
## FOSSA Status
|
||||
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2F1Panel-dev%2F1Panel?ref=badge_large)
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2014-2023 [FIT2CLOUD 飞致云](https://fit2cloud.com/), All rights reserved.
|
||||
|
@@ -3,6 +3,7 @@
|
||||
如果您发现安全问题,请直接联系我们:
|
||||
|
||||
- wanghe@fit2cloud.com
|
||||
- zhengkun@fit2cloud.com
|
||||
- support@fit2cloud.com
|
||||
- 400-052-0755
|
||||
|
||||
@@ -13,6 +14,7 @@
|
||||
All security bugs should be reported to the contact as below:
|
||||
|
||||
- wanghe@fit2cloud.com
|
||||
- zhengkun@fit2cloud.com
|
||||
- support@fit2cloud.com
|
||||
- 400-052-0755
|
||||
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/i18n"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -38,13 +39,24 @@ func (b *BaseApi) SearchApp(c *gin.Context) {
|
||||
// @Router /apps/sync [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"应用商店同步","formatEN":"App store synchronization"}
|
||||
func (b *BaseApi) SyncApp(c *gin.Context) {
|
||||
global.LOG.Infof("sync app list start ...")
|
||||
if err := appService.SyncAppList(); err != nil {
|
||||
global.LOG.Errorf("sync app list error [%s]", err.Error())
|
||||
go appService.SyncAppListFromLocal()
|
||||
res, err := appService.GetAppUpdate()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
global.LOG.Infof("sync app list success!")
|
||||
if !res.CanUpdate {
|
||||
helper.SuccessWithMsg(c, i18n.GetMsgByKey("AppStoreIsUpToDate"))
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
global.LOG.Infof("sync app list start ...")
|
||||
if err := appService.SyncAppListFromRemote(); err != nil {
|
||||
global.LOG.Errorf("sync app list error [%s]", err.Error())
|
||||
} else {
|
||||
global.LOG.Infof("sync app list success!")
|
||||
}
|
||||
}()
|
||||
helper.SuccessWithData(c, "")
|
||||
}
|
||||
|
||||
@@ -71,14 +83,15 @@ func (b *BaseApi) GetApp(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Search app detail by id
|
||||
// @Description 通过 id 获取应用详情
|
||||
// @Summary Search app detail by appid
|
||||
// @Description 通过 appid 获取应用详情
|
||||
// @Accept json
|
||||
// @Param appId path integer true "app id"
|
||||
// @Param version path string true "app 版本"
|
||||
// @Param version path string true "app 类型"
|
||||
// @Success 200 {object} response.AppDetailDTO
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/detail/:appId/:version [get]
|
||||
// @Router /apps/detail/:appId/:version/:type [get]
|
||||
func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
||||
appId, err := helper.GetIntParamByKey(c, "appId")
|
||||
if err != nil {
|
||||
@@ -86,7 +99,8 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
version := c.Param("version")
|
||||
appDetailDTO, err := appService.GetAppDetail(appId, version)
|
||||
appType := c.Param("type")
|
||||
appDetailDTO, err := appService.GetAppDetail(appId, version, appType)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -94,6 +108,44 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
||||
helper.SuccessWithData(c, appDetailDTO)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Get app detail by id
|
||||
// @Description 通过 id 获取应用详情
|
||||
// @Accept json
|
||||
// @Param appId path integer true "id"
|
||||
// @Success 200 {object} response.AppDetailDTO
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/details/:id [get]
|
||||
func (b *BaseApi) GetAppDetailByID(c *gin.Context) {
|
||||
appDetailID, err := helper.GetIntParamByKey(c, "id")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
appDetailDTO, err := appService.GetAppDetailByID(appDetailID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, appDetailDTO)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Get Ignore App
|
||||
// @Description 获取忽略的应用版本
|
||||
// @Accept json
|
||||
// @Success 200 {object} response.IgnoredApp
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/ingored [get]
|
||||
func (b *BaseApi) GetIgnoredApp(c *gin.Context) {
|
||||
res, err := appService.GetIgnoredApp()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary Install app
|
||||
// @Description 安装应用
|
||||
@@ -102,7 +154,7 @@ func (b *BaseApi) GetAppDetail(c *gin.Context) {
|
||||
// @Success 200 {object} model.AppInstall
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/install [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"name","input_value":"name","isList":false,"db":"app_installs","output_colume":"app_id","output_value":"appId"},{"info":"appId","isList":false,"db":"apps","output_colume":"key","output_value":"appKey"}],"formatZH":"安装应用 [appKey]-[name]","formatEN":"Install app [appKey]-[name]"}
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[{"input_column":"name","input_value":"name","isList":false,"db":"app_installs","output_column":"app_id","output_value":"appId"},{"info":"appId","isList":false,"db":"apps","output_column":"key","output_value":"appKey"}],"formatZH":"安装应用 [appKey]-[name]","formatEN":"Install app [appKey]-[name]"}
|
||||
func (b *BaseApi) InstallApp(c *gin.Context) {
|
||||
var req request.AppInstallCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -93,24 +93,24 @@ func (b *BaseApi) LoadPort(c *gin.Context) {
|
||||
|
||||
// @Tags App
|
||||
// @Summary Search app password by key
|
||||
// @Description 获取应用密码
|
||||
// @Description 获取应用连接信息
|
||||
// @Accept json
|
||||
// @Param key path string true "request"
|
||||
// @Success 200 {string} password
|
||||
// @Success 200 {string} response.DatabaseConn
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/loadpassword/:key [get]
|
||||
func (b *BaseApi) LoadPassword(c *gin.Context) {
|
||||
// @Router /apps/installed/conninfo/:key [get]
|
||||
func (b *BaseApi) LoadConnInfo(c *gin.Context) {
|
||||
key, ok := c.Params.Get("key")
|
||||
if !ok {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error key in path"))
|
||||
return
|
||||
}
|
||||
password, err := appInstallService.LoadPassword(key)
|
||||
conn, err := appInstallService.LoadConnInfo(key)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, password)
|
||||
helper.SuccessWithData(c, conn)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
@@ -118,7 +118,7 @@ func (b *BaseApi) LoadPassword(c *gin.Context) {
|
||||
// @Description 删除前检查
|
||||
// @Accept json
|
||||
// @Param appInstallId path integer true "App install id"
|
||||
// @Success 200 {anrry} dto.AppResource
|
||||
// @Success 200 {array} dto.AppResource
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/delete/check/:appInstallId [get]
|
||||
func (b *BaseApi) DeleteCheck(c *gin.Context) {
|
||||
@@ -159,7 +159,7 @@ func (b *BaseApi) SyncInstalled(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/op [post]
|
||||
// @x-panel-log {"bodyKeys":["installId","operate"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"installId","isList":false,"db":"app_installs","output_colume":"app_id","output_value":"appId"},{"input_colume":"id","input_value":"installId","isList":false,"db":"app_installs","output_colume":"name","output_value":"appName"},{"input_colume":"id","input_value":"appId","isList":false,"db":"apps","output_colume":"key","output_value":"appKey"}],"formatZH":"[appKey] 应用 [appName] [operate]","formatEN":"[appKey] App [appName] [operate]"}
|
||||
// @x-panel-log {"bodyKeys":["installId","operate"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"installId","isList":false,"db":"app_installs","output_column":"app_id","output_value":"appId"},{"input_column":"id","input_value":"installId","isList":false,"db":"app_installs","output_column":"name","output_value":"appName"},{"input_column":"id","input_value":"appId","isList":false,"db":"apps","output_column":"key","output_value":"appKey"}],"formatZH":"[operate] 应用 [appKey][appName]","formatEN":"[operate] App [appKey][appName]"}
|
||||
func (b *BaseApi) OperateInstalled(c *gin.Context) {
|
||||
var req request.AppInstalledOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -178,7 +178,7 @@ func (b *BaseApi) OperateInstalled(c *gin.Context) {
|
||||
// @Description 通过 key 获取应用 service
|
||||
// @Accept json
|
||||
// @Param key path string true "request"
|
||||
// @Success 200 {anrry} response.AppService
|
||||
// @Success 200 {array} response.AppService
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/services/:key [get]
|
||||
func (b *BaseApi) GetServices(c *gin.Context) {
|
||||
@@ -196,7 +196,7 @@ func (b *BaseApi) GetServices(c *gin.Context) {
|
||||
// @Description 通过 install id 获取应用更新版本
|
||||
// @Accept json
|
||||
// @Param appInstallId path integer true "request"
|
||||
// @Success 200 {anrry} dto.AppVersion
|
||||
// @Success 200 {array} dto.AppVersion
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/:appInstallId/versions [get]
|
||||
func (b *BaseApi) GetUpdateVersions(c *gin.Context) {
|
||||
@@ -305,3 +305,25 @@ func (b *BaseApi) UpdateInstalled(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags App
|
||||
// @Summary ignore App Update
|
||||
// @Description 忽略应用升级版本
|
||||
// @Accept json
|
||||
// @Param request body request.AppInstalledIgnoreUpgrade true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /apps/installed/ignore [post]
|
||||
// @x-panel-log {"bodyKeys":["installId"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"忽略应用 [installId] 版本升级","formatEN":"Application param update [installId]"}
|
||||
func (b *BaseApi) IgnoreUpgrade(c *gin.Context) {
|
||||
var req request.AppInstalledIgnoreUpgrade
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := appInstallService.IgnoreUpgrade(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
@@ -1,8 +1,6 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
@@ -28,7 +26,7 @@ func (b *BaseApi) Login(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if req.AuthMethod != "jwt" {
|
||||
if req.AuthMethod != "jwt" && !req.IgnoreCaptcha {
|
||||
if err := captcha.VerifyCode(req.CaptchaID, req.Captcha); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -102,71 +100,15 @@ func (b *BaseApi) Captcha(c *gin.Context) {
|
||||
// @Summary Load safety status
|
||||
// @Description 获取系统安全登录状态
|
||||
// @Success 200
|
||||
// @Failure 402
|
||||
// @Router /auth/status [get]
|
||||
func (b *BaseApi) GetSafetyStatus(c *gin.Context) {
|
||||
if err := authService.SafetyStatus(c); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
func (b *BaseApi) SafeEntrance(c *gin.Context) {
|
||||
code, exist := c.Params.Get("code")
|
||||
if !exist {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, errors.New("missing code"))
|
||||
return
|
||||
}
|
||||
ok, err := authService.VerifyCode(code)
|
||||
// @Router /auth/issafety [get]
|
||||
func (b *BaseApi) CheckIsSafety(c *gin.Context) {
|
||||
code := c.DefaultQuery("code", "")
|
||||
status, err := authService.CheckIsSafety(code)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, errors.New("missing code"))
|
||||
return
|
||||
}
|
||||
if !ok {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, errors.New("missing code"))
|
||||
return
|
||||
}
|
||||
if err := authService.SafeEntrance(c, code); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrUnSafety, constant.ErrTypeNotSafety, errors.New("missing code"))
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Auth
|
||||
// @Summary Check is First login
|
||||
// @Description 判断是否为首次登录
|
||||
// @Success 200
|
||||
// @Router /auth/status [get]
|
||||
func (b *BaseApi) CheckIsFirstLogin(c *gin.Context) {
|
||||
helper.SuccessWithData(c, authService.CheckIsFirst())
|
||||
}
|
||||
|
||||
// @Tags Auth
|
||||
// @Summary Init user
|
||||
// @Description 初始化用户
|
||||
// @Accept json
|
||||
// @Param request body dto.InitUser true "request"
|
||||
// @Success 200
|
||||
// @Router /auth/init [post]
|
||||
func (b *BaseApi) InitUserInfo(c *gin.Context) {
|
||||
var req dto.InitUser
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := authService.InitUser(c, req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
helper.SuccessWithData(c, status)
|
||||
}
|
||||
|
||||
// @Tags Auth
|
||||
@@ -178,6 +120,20 @@ func (b *BaseApi) CheckIsDemo(c *gin.Context) {
|
||||
helper.SuccessWithData(c, global.CONF.System.IsDemo)
|
||||
}
|
||||
|
||||
// @Tags Auth
|
||||
// @Summary Load System Language
|
||||
// @Description 获取系统语言设置
|
||||
// @Success 200
|
||||
// @Router /auth/language [get]
|
||||
func (b *BaseApi) GetLanguage(c *gin.Context) {
|
||||
settingInfo, err := settingService.GetSettingInfo()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, settingInfo.Language)
|
||||
}
|
||||
|
||||
func saveLoginLogs(c *gin.Context, err error) {
|
||||
var logs model.LoginLog
|
||||
if err != nil {
|
||||
|
@@ -2,6 +2,8 @@ package v1
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
@@ -58,7 +60,7 @@ func (b *BaseApi) CreateBackup(c *gin.Context) {
|
||||
// @Description 获取 bucket 列表
|
||||
// @Accept json
|
||||
// @Param request body dto.ForBuckets true "request"
|
||||
// @Success 200 {anrry} string
|
||||
// @Success 200 {array} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/search [post]
|
||||
func (b *BaseApi) ListBuckets(c *gin.Context) {
|
||||
@@ -96,6 +98,22 @@ func (b *BaseApi) ListBuckets(c *gin.Context) {
|
||||
helper.SuccessWithData(c, buckets)
|
||||
}
|
||||
|
||||
// @Tags Backup Account
|
||||
// @Summary Load OneDrive info
|
||||
// @Description 获取 OneDrive 信息
|
||||
// @Accept json
|
||||
// @Success 200 string clientID
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/onedrive [get]
|
||||
func (b *BaseApi) LoadOneDriveInfo(c *gin.Context) {
|
||||
clientID, err := backupService.LoadOneDriveInfo()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, clientID)
|
||||
}
|
||||
|
||||
// @Tags Backup Account
|
||||
// @Summary Delete backup account
|
||||
// @Description 删除备份账号
|
||||
@@ -104,9 +122,9 @@ func (b *BaseApi) ListBuckets(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"backup_accounts","output_colume":"type","output_value":"types"}],"formatZH":"删除备份账号 [types]","formatEN":"delete backup account [types]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":true,"db":"backup_accounts","output_column":"type","output_value":"types"}],"formatZH":"删除备份账号 [types]","formatEN":"delete backup account [types]"}
|
||||
func (b *BaseApi) DeleteBackup(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
var req dto.OperateByID
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -116,7 +134,7 @@ func (b *BaseApi) DeleteBackup(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := backupService.BatchDelete(req.Ids); err != nil {
|
||||
if err := backupService.Delete(req.ID); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
@@ -186,7 +204,7 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/record/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"backup_records","output_colume":"file_name","output_value":"files"}],"formatZH":"删除备份记录 [files]","formatEN":"delete backup records [files]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"backup_records","output_column":"file_name","output_value":"files"}],"formatZH":"删除备份记录 [files]","formatEN":"delete backup records [files]"}
|
||||
func (b *BaseApi) DeleteBackupRecord(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -251,7 +269,7 @@ func (b *BaseApi) UpdateBackup(c *gin.Context) {
|
||||
// @Tags Backup Account
|
||||
// @Summary List backup accounts
|
||||
// @Description 获取备份账号列表
|
||||
// @Success 200 {anrry} dto.BackupInfo
|
||||
// @Success 200 {array} dto.BackupInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/search [get]
|
||||
func (b *BaseApi) ListBackup(c *gin.Context) {
|
||||
@@ -269,7 +287,7 @@ func (b *BaseApi) ListBackup(c *gin.Context) {
|
||||
// @Description 获取备份账号内文件列表
|
||||
// @Accept json
|
||||
// @Param request body dto.BackupSearchFile true "request"
|
||||
// @Success 200 {anrry} string
|
||||
// @Success 200 {array} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/backup/search/files [post]
|
||||
func (b *BaseApi) LoadFilesFromBackup(c *gin.Context) {
|
||||
@@ -356,6 +374,14 @@ func (b *BaseApi) Recover(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if req.Source != "LOCAL" {
|
||||
downloadPath, err := backupService.DownloadRecord(dto.DownloadRecord{Source: req.Source, FileDir: path.Dir(req.File), FileName: path.Base(req.File)})
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, fmt.Errorf("download file failed, err: %v", err))
|
||||
return
|
||||
}
|
||||
req.File = downloadPath
|
||||
}
|
||||
switch req.Type {
|
||||
case "mysql":
|
||||
if err := backupService.MysqlRecover(req); err != nil {
|
||||
|
@@ -85,7 +85,7 @@ func (b *BaseApi) ListCommand(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/command/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"commands","output_colume":"name","output_value":"names"}],"formatZH":"删除快捷命令 [names]","formatEN":"delete quick command [names]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"commands","output_column":"name","output_value":"names"}],"formatZH":"删除快捷命令 [names]","formatEN":"delete quick command [names]"}
|
||||
func (b *BaseApi) DeleteCommand(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -66,7 +66,7 @@ func (b *BaseApi) SearchComposeTemplate(c *gin.Context) {
|
||||
// @Summary List compose templates
|
||||
// @Description 获取容器编排模版列表
|
||||
// @Produce json
|
||||
// @Success 200 {anrry} dto.ComposeTemplateInfo
|
||||
// @Success 200 {array} dto.ComposeTemplateInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/template [get]
|
||||
func (b *BaseApi) ListComposeTemplate(c *gin.Context) {
|
||||
@@ -87,7 +87,7 @@ func (b *BaseApi) ListComposeTemplate(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/template/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"compose_templates","output_colume":"name","output_value":"names"}],"formatZH":"删除 compose 模版 [names]","formatEN":"delete compose template [names]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"compose_templates","output_column":"name","output_value":"names"}],"formatZH":"删除 compose 模版 [names]","formatEN":"delete compose template [names]"}
|
||||
func (b *BaseApi) DeleteComposeTemplate(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -114,7 +114,7 @@ func (b *BaseApi) DeleteComposeTemplate(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/template/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"compose_templates","output_colume":"name","output_value":"name"}],"formatZH":"更新 compose 模版 [name]","formatEN":"update compose template information [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"compose_templates","output_column":"name","output_value":"name"}],"formatZH":"更新 compose 模版 [name]","formatEN":"update compose template information [name]"}
|
||||
func (b *BaseApi) UpdateComposeTemplate(c *gin.Context) {
|
||||
var req dto.ComposeTemplateUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -40,6 +40,23 @@ func (b *BaseApi) SearchContainer(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary List containers
|
||||
// @Description 获取容器名称
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/list [post]
|
||||
func (b *BaseApi) ListContainer(c *gin.Context) {
|
||||
list, err := containerService.List()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Container Compose
|
||||
// @Summary Page composes
|
||||
// @Description 获取编排列表分页
|
||||
@@ -153,17 +170,97 @@ func (b *BaseApi) OperatorCompose(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Update container
|
||||
// @Description 更新容器
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerOperate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新容器 [name][image]","formatEN":"update container [name][image]"}
|
||||
func (b *BaseApi) ContainerUpdate(c *gin.Context) {
|
||||
var req dto.ContainerOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := containerService.ContainerUpdate(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Load container info
|
||||
// @Description 获取容器表单信息
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithName true "request"
|
||||
// @Success 200 {object} dto.ContainerOperate
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/info [post]
|
||||
func (b *BaseApi) ContainerInfo(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
data, err := containerService.ContainerInfo(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Summary Load container limis
|
||||
// @Description 获取容器限制
|
||||
// @Success 200 {object} dto.ResourceLimit
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/limit [get]
|
||||
func (b *BaseApi) LoadResouceLimit(c *gin.Context) {
|
||||
data, err := containerService.LoadResouceLimit()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Summary Load container stats
|
||||
// @Description 获取容器列表资源占用
|
||||
// @Success 200 {array} dto.ContainerListStats
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/list/stats [get]
|
||||
func (b *BaseApi) ContainerListStats(c *gin.Context) {
|
||||
datas, err := containerService.ContainerListStats()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, datas)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Create container
|
||||
// @Description 创建容器
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerCreate true "request"
|
||||
// @Param request body dto.ContainerOperate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers [post]
|
||||
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建容器 [name][image]","formatEN":"create container [name][image]"}
|
||||
func (b *BaseApi) ContainerCreate(c *gin.Context) {
|
||||
var req dto.ContainerCreate
|
||||
var req dto.ContainerOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -179,6 +276,103 @@ func (b *BaseApi) ContainerCreate(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Upgrade container
|
||||
// @Description 更新容器镜像
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerUpgrade true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/upgrade [post]
|
||||
// @x-panel-log {"bodyKeys":["name","image"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新容器镜像 [name][image]","formatEN":"upgrade container image [name][image]"}
|
||||
func (b *BaseApi) ContainerUpgrade(c *gin.Context) {
|
||||
var req dto.ContainerUpgrade
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := containerService.ContainerUpgrade(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Clean container
|
||||
// @Description 容器清理
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerPrune true "request"
|
||||
// @Success 200 {object} dto.ContainerPruneReport
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/prune [post]
|
||||
// @x-panel-log {"bodyKeys":["pruneType"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清理容器 [pruneType]","formatEN":"clean container [pruneType]"}
|
||||
func (b *BaseApi) ContainerPrune(c *gin.Context) {
|
||||
var req dto.ContainerPrune
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
report, err := containerService.Prune(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, report)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Clean container log
|
||||
// @Description 清理容器日志
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithName true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/clean/log [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"清理容器 [name] 日志","formatEN":"clean container [name] logs"}
|
||||
func (b *BaseApi) CleanContainerLog(c *gin.Context) {
|
||||
var req dto.OperationWithName
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := containerService.ContainerLogClean(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Load container log
|
||||
// @Description 获取容器操作日志
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/load/log [post]
|
||||
func (b *BaseApi) LoadContainerLog(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
content := containerService.LoadContainerLogs(req)
|
||||
helper.SuccessWithData(c, content)
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary Operate Container
|
||||
// @Description 容器操作
|
||||
@@ -209,7 +403,7 @@ func (b *BaseApi) ContainerOperation(c *gin.Context) {
|
||||
// @Summary Container stats
|
||||
// @Description 容器监控信息
|
||||
// @Param id path integer true "容器id"
|
||||
// @Success 200 {object} dto.ContainterStats
|
||||
// @Success 200 {object} dto.ContainerStats
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/stats/:id [get]
|
||||
func (b *BaseApi) ContainerStats(c *gin.Context) {
|
||||
@@ -257,27 +451,29 @@ func (b *BaseApi) Inspect(c *gin.Context) {
|
||||
// @Tags Container
|
||||
// @Summary Container logs
|
||||
// @Description 容器日志
|
||||
// @Accept json
|
||||
// @Param request body dto.ContainerLog true "request"
|
||||
// @Success 200 {string} logs
|
||||
// @Param container query string false "容器名称"
|
||||
// @Param since query string false "时间筛选"
|
||||
// @Param follow query string false "是否追踪"
|
||||
// @Param tail query string false "显示行号"
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/search/log [post]
|
||||
func (b *BaseApi) ContainerLogs(c *gin.Context) {
|
||||
var req dto.ContainerLog
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
logs, err := containerService.ContainerLogs(req)
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
defer wsConn.Close()
|
||||
|
||||
container := c.Query("container")
|
||||
since := c.Query("since")
|
||||
follow := c.Query("follow") == "true"
|
||||
tail := c.Query("tail")
|
||||
|
||||
if err := containerService.ContainerLogs(wsConn, container, since, tail, follow); err != nil {
|
||||
_ = wsConn.WriteMessage(1, []byte(err.Error()))
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, logs)
|
||||
}
|
||||
|
||||
// @Tags Container Network
|
||||
@@ -311,6 +507,23 @@ func (b *BaseApi) SearchNetwork(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Container Network
|
||||
// @Summary List networks
|
||||
// @Description 获取容器网络列表
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {array} dto.Options
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/network [get]
|
||||
func (b *BaseApi) ListNetwork(c *gin.Context) {
|
||||
list, err := containerService.ListNetwork()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Container Network
|
||||
// @Summary Delete network
|
||||
// @Description 删除容器网络
|
||||
@@ -342,13 +555,13 @@ func (b *BaseApi) DeleteNetwork(c *gin.Context) {
|
||||
// @Summary Create network
|
||||
// @Description 创建容器网络
|
||||
// @Accept json
|
||||
// @Param request body dto.NetworkCreat true "request"
|
||||
// @Param request body dto.NetworkCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/network [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建容器网络 name","formatEN":"create container network [name]"}
|
||||
func (b *BaseApi) CreateNetwork(c *gin.Context) {
|
||||
var req dto.NetworkCreat
|
||||
var req dto.NetworkCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -400,11 +613,10 @@ func (b *BaseApi) SearchVolume(c *gin.Context) {
|
||||
// @Summary List volumes
|
||||
// @Description 获取容器存储卷列表
|
||||
// @Accept json
|
||||
// @Param request body dto.PageInfo true "request"
|
||||
// @Produce json
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Success 200 {array} dto.Options
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/volume/search [get]
|
||||
// @Router /containers/volume [get]
|
||||
func (b *BaseApi) ListVolume(c *gin.Context) {
|
||||
list, err := containerService.ListVolume()
|
||||
if err != nil {
|
||||
@@ -445,13 +657,13 @@ func (b *BaseApi) DeleteVolume(c *gin.Context) {
|
||||
// @Summary Create volume
|
||||
// @Description 创建容器存储卷
|
||||
// @Accept json
|
||||
// @Param request body dto.VolumeCreat true "request"
|
||||
// @Param request body dto.VolumeCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/volume [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建容器存储卷 [name]","formatEN":"create container volume [name]"}
|
||||
func (b *BaseApi) CreateVolume(c *gin.Context) {
|
||||
var req dto.VolumeCreat
|
||||
var req dto.VolumeCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -77,8 +78,9 @@ func (b *BaseApi) SearchJobRecords(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.StartTime = req.StartTime.Add(8 * time.Hour)
|
||||
req.EndTime = req.EndTime.Add(8 * time.Hour)
|
||||
loc, _ := time.LoadLocation(common.LoadTimeZone())
|
||||
req.StartTime = req.StartTime.In(loc)
|
||||
req.EndTime = req.EndTime.In(loc)
|
||||
|
||||
total, list, err := cronjobService.SearchRecords(req)
|
||||
if err != nil {
|
||||
@@ -92,17 +94,63 @@ func (b *BaseApi) SearchJobRecords(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Load Cronjob record log
|
||||
// @Description 获取计划任务记录日志
|
||||
// @Accept json
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjob/record/log [post]
|
||||
func (b *BaseApi) LoadRecordLog(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
content, err := cronjobService.LoadRecordLog(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, content)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Clean job records
|
||||
// @Description 清空计划任务记录
|
||||
// @Accept json
|
||||
// @Param request body dto.CronjobClean true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/records/clean [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"清空计划任务记录 [name]","formatEN":"clean cronjob [name] records"}
|
||||
func (b *BaseApi) CleanRecord(c *gin.Context) {
|
||||
var req dto.CronjobClean
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := cronjobService.CleanRecord(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
// @Summary Delete cronjob
|
||||
// @Description 删除计划任务
|
||||
// @Accept json
|
||||
// @Param request body dto.BatchDeleteReq true "request"
|
||||
// @Param request body dto.CronjobBatchDelete true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"cronjobs","output_colume":"name","output_value":"names"}],"formatZH":"删除计划任务 [names]","formatEN":"delete cronjob [names]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"cronjobs","output_column":"name","output_value":"names"}],"formatZH":"删除计划任务 [names]","formatEN":"delete cronjob [names]"}
|
||||
func (b *BaseApi) DeleteCronjob(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
var req dto.CronjobBatchDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -112,7 +160,7 @@ func (b *BaseApi) DeleteCronjob(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := cronjobService.Delete(req.Ids); err != nil {
|
||||
if err := cronjobService.Delete(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
@@ -127,7 +175,7 @@ func (b *BaseApi) DeleteCronjob(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"cronjobs","output_colume":"name","output_value":"name"}],"formatZH":"更新计划任务 [name]","formatEN":"update cronjob [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"更新计划任务 [name]","formatEN":"update cronjob [name]"}
|
||||
func (b *BaseApi) UpdateCronjob(c *gin.Context) {
|
||||
var req dto.CronjobUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -154,7 +202,7 @@ func (b *BaseApi) UpdateCronjob(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/status [post]
|
||||
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"cronjobs","output_colume":"name","output_value":"name"}],"formatZH":"修改计划任务 [name] 状态为 [status]","formatEN":"change the status of cronjob [name] to [status]."}
|
||||
// @x-panel-log {"bodyKeys":["id","status"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"修改计划任务 [name] 状态为 [status]","formatEN":"change the status of cronjob [name] to [status]."}
|
||||
func (b *BaseApi) UpdateCronjobStatus(c *gin.Context) {
|
||||
var req dto.CronjobUpdateStatus
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -181,7 +229,7 @@ func (b *BaseApi) UpdateCronjobStatus(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/download [post]
|
||||
// @x-panel-log {"bodyKeys":["recordID"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"recordID","isList":false,"db":"job_records","output_colume":"file","output_value":"file"}],"formatZH":"下载计划任务记录 [file]","formatEN":"download the cronjob record [file]"}
|
||||
// @x-panel-log {"bodyKeys":["recordID"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"recordID","isList":false,"db":"job_records","output_column":"file","output_value":"file"}],"formatZH":"下载计划任务记录 [file]","formatEN":"download the cronjob record [file]"}
|
||||
func (b *BaseApi) TargetDownload(c *gin.Context) {
|
||||
var req dto.CronjobDownload
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -198,7 +246,8 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, filePath)
|
||||
|
||||
c.File(filePath)
|
||||
}
|
||||
|
||||
// @Tags Cronjob
|
||||
@@ -209,7 +258,7 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /cronjobs/handle [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"cronjobs","output_colume":"name","output_value":"name"}],"formatZH":"手动执行计划任务 [name]","formatEN":"manually execute the cronjob [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"cronjobs","output_column":"name","output_value":"name"}],"formatZH":"手动执行计划任务 [name]","formatEN":"manually execute the cronjob [name]"}
|
||||
func (b *BaseApi) HandleOnce(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -54,7 +54,7 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/description/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"database_mysqls","output_colume":"name","output_value":"name"}],"formatZH":"mysql 数据库 [name] 描述信息修改 [description]","formatEN":"The description of the mysql database [name] is modified => [description]"}
|
||||
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"mysql 数据库 [name] 描述信息修改 [description]","formatEN":"The description of the mysql database [name] is modified => [description]"}
|
||||
func (b *BaseApi) UpdateMysqlDescription(c *gin.Context) {
|
||||
var req dto.UpdateDescription
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -80,7 +80,7 @@ func (b *BaseApi) UpdateMysqlDescription(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/change/password [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"database_mysqls","output_colume":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 密码","formatEN":"Update database [name] password"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 密码","formatEN":"Update database [name] password"}
|
||||
func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
|
||||
var req dto.ChangeDBInfo
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -115,7 +115,7 @@ func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/change/access [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"database_mysqls","output_colume":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 访问权限","formatEN":"Update database [name] access"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"更新数据库 [name] 访问权限","formatEN":"Update database [name] access"}
|
||||
func (b *BaseApi) ChangeMysqlAccess(c *gin.Context) {
|
||||
var req dto.ChangeDBInfo
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -188,12 +188,12 @@ func (b *BaseApi) UpdateMysqlConfByFile(c *gin.Context) {
|
||||
// @Summary Page mysql databases
|
||||
// @Description 获取 mysql 数据库列表分页
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchWithPage true "request"
|
||||
// @Param request body dto.MysqlDBSearch true "request"
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/search [post]
|
||||
func (b *BaseApi) SearchMysql(c *gin.Context) {
|
||||
var req dto.SearchWithPage
|
||||
var req dto.MysqlDBSearch
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -216,11 +216,11 @@ func (b *BaseApi) SearchMysql(c *gin.Context) {
|
||||
// @Description 获取 mysql 数据库列表
|
||||
// @Accept json
|
||||
// @Param request body dto.PageInfo true "request"
|
||||
// @Success 200 {anrry} string
|
||||
// @Success 200 {array} dto.MysqlOption
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/options [get]
|
||||
func (b *BaseApi) ListDBName(c *gin.Context) {
|
||||
list, err := mysqlService.ListDBName()
|
||||
list, err := mysqlService.ListDBOption()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -229,12 +229,31 @@ func (b *BaseApi) ListDBName(c *gin.Context) {
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Database Mysql
|
||||
// @Summary Load mysql database from remote
|
||||
// @Description 从服务器获取
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/load/:from [get]
|
||||
func (b *BaseApi) LoadDBFromRemote(c *gin.Context) {
|
||||
from, err := helper.GetStrParamByKey(c, "from")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := mysqlService.LoadFromRemote(from); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database Mysql
|
||||
// @Summary Check before delete mysql database
|
||||
// @Description Mysql 数据库删除前检查
|
||||
// @Accept json
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Success 200 {anrry} string
|
||||
// @Success 200 {array} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/del/check [post]
|
||||
func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
|
||||
@@ -264,7 +283,7 @@ func (b *BaseApi) DeleteCheckMysql(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"database_mysqls","output_colume":"name","output_value":"name"}],"formatZH":"删除 mysql 数据库 [name]","formatEN":"delete mysql database [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"database_mysqls","output_column":"name","output_value":"name"}],"formatZH":"删除 mysql 数据库 [name]","formatEN":"delete mysql database [name]"}
|
||||
func (b *BaseApi) DeleteMysql(c *gin.Context) {
|
||||
var req dto.MysqlDBDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -302,6 +321,28 @@ func (b *BaseApi) LoadBaseinfo(c *gin.Context) {
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Load Database file
|
||||
// @Description 获取数据库文件
|
||||
// @Accept json
|
||||
// @Param request body dto.OperationWithNameAndType true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/load/file [post]
|
||||
func (b *BaseApi) LoadDatabaseFile(c *gin.Context) {
|
||||
var req dto.OperationWithNameAndType
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
content, err := mysqlService.LoadDatabaseFile(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, content)
|
||||
}
|
||||
|
||||
// @Tags Database Mysql
|
||||
// @Summary Load mysql remote access
|
||||
// @Description 获取 mysql 远程访问权限
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
@@ -35,7 +34,7 @@ func (b *BaseApi) LoadDaemonJsonFile(c *gin.Context) {
|
||||
helper.SuccessWithData(c, "daemon.json is not find in path")
|
||||
return
|
||||
}
|
||||
content, err := ioutil.ReadFile(constant.DaemonJsonPath)
|
||||
content, err := os.ReadFile(constant.DaemonJsonPath)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -59,13 +58,13 @@ func (b *BaseApi) LoadDaemonJson(c *gin.Context) {
|
||||
// @Summary Update docker daemon.json
|
||||
// @Description 修改 docker 配置信息
|
||||
// @Accept json
|
||||
// @Param request body dto.DaemonJsonConf true "request"
|
||||
// @Param request body dto.SettingUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/daemonjson/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 配置","formatEN":"Updated the docker daemon.json configuration"}
|
||||
// @x-panel-log {"bodyKeys":["key", "value"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 配置 [key]=>[value]","formatEN":"Updated the docker daemon.json configuration [key]=>[value]"}
|
||||
func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
|
||||
var req dto.DaemonJsonConf
|
||||
var req dto.SettingUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
@@ -79,6 +78,30 @@ func (b *BaseApi) UpdateDaemonJson(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container Docker
|
||||
// @Summary Update docker daemon.json log option
|
||||
// @Description 修改 docker 日志配置
|
||||
// @Accept json
|
||||
// @Param request body dto.LogOption true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/daemonjson/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新 docker daemon.json 日志配置","formatEN":"Updated the docker daemon.json log option"}
|
||||
func (b *BaseApi) UpdateLogOption(c *gin.Context) {
|
||||
var req dto.LogOption
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := dockerService.UpdateLogOption(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Container Docker
|
||||
// @Summary Update docker daemon.json by upload file
|
||||
// @Description 上传替换 docker 配置文件
|
||||
|
@@ -9,40 +9,48 @@ type ApiGroup struct {
|
||||
var ApiGroupApp = new(ApiGroup)
|
||||
|
||||
var (
|
||||
authService = service.ServiceGroupApp.AuthService
|
||||
dashboardService = service.ServiceGroupApp.DashboardService
|
||||
authService = service.NewIAuthService()
|
||||
dashboardService = service.NewIDashboardService()
|
||||
|
||||
appService = service.NewIAppService()
|
||||
appInstallService = service.ServiceGroupApp.AppInstallService
|
||||
appInstallService = service.NewIAppInstalledService()
|
||||
|
||||
containerService = service.ServiceGroupApp.ContainerService
|
||||
composeTemplateService = service.ServiceGroupApp.ComposeTemplateService
|
||||
imageRepoService = service.ServiceGroupApp.ImageRepoService
|
||||
imageService = service.ServiceGroupApp.ImageService
|
||||
dockerService = service.ServiceGroupApp.DockerService
|
||||
containerService = service.NewIContainerService()
|
||||
composeTemplateService = service.NewIComposeTemplateService()
|
||||
imageRepoService = service.NewIImageRepoService()
|
||||
imageService = service.NewIImageService()
|
||||
dockerService = service.NewIDockerService()
|
||||
|
||||
mysqlService = service.ServiceGroupApp.MysqlService
|
||||
redisService = service.ServiceGroupApp.RedisService
|
||||
mysqlService = service.NewIMysqlService()
|
||||
remoteDBService = service.NewIRemoteDBService()
|
||||
redisService = service.NewIRedisService()
|
||||
|
||||
cronjobService = service.ServiceGroupApp.CronjobService
|
||||
cronjobService = service.NewICronjobService()
|
||||
|
||||
hostService = service.ServiceGroupApp.HostService
|
||||
groupService = service.ServiceGroupApp.GroupService
|
||||
fileService = service.ServiceGroupApp.FileService
|
||||
hostService = service.NewIHostService()
|
||||
groupService = service.NewIGroupService()
|
||||
fileService = service.NewIFileService()
|
||||
sshService = service.NewISSHService()
|
||||
firewallService = service.NewIFirewallService()
|
||||
|
||||
settingService = service.ServiceGroupApp.SettingService
|
||||
backupService = service.ServiceGroupApp.BackupService
|
||||
settingService = service.NewISettingService()
|
||||
backupService = service.NewIBackupService()
|
||||
|
||||
commandService = service.ServiceGroupApp.CommandService
|
||||
commandService = service.NewICommandService()
|
||||
|
||||
websiteService = service.ServiceGroupApp.WebsiteService
|
||||
websiteDnsAccountService = service.ServiceGroupApp.WebsiteDnsAccountService
|
||||
websiteSSLService = service.ServiceGroupApp.WebsiteSSLService
|
||||
websiteAcmeAccountService = service.ServiceGroupApp.WebsiteAcmeAccountService
|
||||
websiteService = service.NewIWebsiteService()
|
||||
websiteDnsAccountService = service.NewIWebsiteDnsAccountService()
|
||||
websiteSSLService = service.NewIWebsiteSSLService()
|
||||
websiteAcmeAccountService = service.NewIWebsiteAcmeAccountService()
|
||||
|
||||
nginxService = service.ServiceGroupApp.NginxService
|
||||
nginxService = service.NewINginxService()
|
||||
|
||||
logService = service.ServiceGroupApp.LogService
|
||||
snapshotService = service.ServiceGroupApp.SnapshotService
|
||||
upgradeService = service.ServiceGroupApp.UpgradeService
|
||||
logService = service.NewILogService()
|
||||
snapshotService = service.NewISnapshotService()
|
||||
upgradeService = service.NewIUpgradeService()
|
||||
|
||||
runtimeService = service.NewRuntimeService()
|
||||
processService = service.NewIProcessService()
|
||||
|
||||
hostToolService = service.NewIHostToolService()
|
||||
)
|
||||
|
@@ -3,8 +3,9 @@ package v1
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -51,7 +52,7 @@ func (b *BaseApi) ListFiles(c *gin.Context) {
|
||||
// @Description 分页获取上传文件
|
||||
// @Accept json
|
||||
// @Param request body request.SearchUploadWithPage true "request"
|
||||
// @Success 200 {anrry} response.FileInfo
|
||||
// @Success 200 {array} response.FileInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/upload/search [post]
|
||||
func (b *BaseApi) SearchUploadWithPage(c *gin.Context) {
|
||||
@@ -80,7 +81,7 @@ func (b *BaseApi) SearchUploadWithPage(c *gin.Context) {
|
||||
// @Description 加载文件树
|
||||
// @Accept json
|
||||
// @Param request body request.FileOption true "request"
|
||||
// @Success 200 {anrry} response.FileTree
|
||||
// @Success 200 {array} response.FileTree
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/tree [post]
|
||||
func (b *BaseApi) GetFileTree(c *gin.Context) {
|
||||
@@ -186,7 +187,29 @@ func (b *BaseApi) ChangeFileMode(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Change file owner
|
||||
// @Description 修改文件用户/组
|
||||
// @Accept json
|
||||
// @Param request body request.FileRoleUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/owner [post]
|
||||
// @x-panel-log {"bodyKeys":["path","user","group"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改用户/组 [paths] => [user]/[group]","formatEN":"Change owner [paths] => [user]/[group]"}
|
||||
func (b *BaseApi) ChangeFileOwner(c *gin.Context) {
|
||||
var req request.FileRoleUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := fileService.ChangeOwner(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
@@ -432,39 +455,93 @@ func (b *BaseApi) MoveFile(c *gin.Context) {
|
||||
// @Router /files/download [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
|
||||
func (b *BaseApi) Download(c *gin.Context) {
|
||||
var req request.FileDownload
|
||||
filePath := c.Query("path")
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
}
|
||||
info, _ := file.Stat()
|
||||
c.Header("Content-Length", strconv.FormatInt(info.Size(), 10))
|
||||
c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(info.Name()))
|
||||
http.ServeContent(c.Writer, c.Request, info.Name(), info.ModTime(), file)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Chunk Download file
|
||||
// @Description 分片下载下载文件
|
||||
// @Accept json
|
||||
// @Param request body request.FileDownload true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/chunkdownload [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [name]","formatEN":"Download file [name]"}
|
||||
func (b *BaseApi) DownloadChunkFiles(c *gin.Context) {
|
||||
var req request.FileChunkDownload
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
filePath, err := fileService.FileDownload(req)
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(req.Path) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrPathNotFound, nil)
|
||||
return
|
||||
}
|
||||
filePath := req.Path
|
||||
fstFile, err := fileOp.OpenFile(filePath)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
c.File(filePath)
|
||||
}
|
||||
info, err := fstFile.Stat()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
if info.IsDir() {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrFileDownloadDir, err)
|
||||
return
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Download file with path
|
||||
// @Description 下载指定文件
|
||||
// @Accept json
|
||||
// @Param request body dto.FilePath true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/download/bypath [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [path]","formatEN":"Download file [path]"}
|
||||
func (b *BaseApi) DownloadFile(c *gin.Context) {
|
||||
var req dto.FilePath
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", req.Name))
|
||||
c.Writer.Header().Set("Content-Type", "application/octet-stream")
|
||||
c.Writer.Header().Set("Content-Length", strconv.FormatInt(info.Size(), 10))
|
||||
c.Writer.Header().Set("Accept-Ranges", "bytes")
|
||||
|
||||
if c.Request.Header.Get("Range") != "" {
|
||||
rangeHeader := c.Request.Header.Get("Range")
|
||||
rangeArr := strings.Split(rangeHeader, "=")[1]
|
||||
rangeParts := strings.Split(rangeArr, "-")
|
||||
|
||||
startPos, _ := strconv.ParseInt(rangeParts[0], 10, 64)
|
||||
|
||||
var endPos int64
|
||||
if rangeParts[1] == "" {
|
||||
endPos = info.Size() - 1
|
||||
} else {
|
||||
endPos, _ = strconv.ParseInt(rangeParts[1], 10, 64)
|
||||
}
|
||||
|
||||
c.Writer.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", startPos, endPos, info.Size()))
|
||||
c.Writer.WriteHeader(http.StatusPartialContent)
|
||||
|
||||
buffer := make([]byte, 1024*1024)
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, _ = file.Seek(startPos, 0)
|
||||
reader := io.LimitReader(file, endPos-startPos+1)
|
||||
_, err = io.CopyBuffer(c.Writer, reader, buffer)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.File(filePath)
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
c.File(req.Path)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
@@ -490,34 +567,6 @@ func (b *BaseApi) Size(c *gin.Context) {
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags File
|
||||
// @Summary Read file
|
||||
// @Description 读取文件
|
||||
// @Accept json
|
||||
// @Param request body dto.FilePath true "request"
|
||||
// @Success 200 {string} content
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/loadfile [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"读取文件 [path]","formatEN":"Read file [path]"}
|
||||
func (b *BaseApi) LoadFromFile(c *gin.Context) {
|
||||
var req dto.FilePath
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadFile(req.Path)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, string(content))
|
||||
}
|
||||
|
||||
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int) error {
|
||||
if _, err := os.Stat(path.Dir(dstDir)); err != nil && os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(path.Dir(dstDir), os.ModePerm); err != nil {
|
||||
@@ -533,7 +582,7 @@ func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int)
|
||||
|
||||
for i := 0; i < chunkCount; i++ {
|
||||
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", fileName, i))
|
||||
chunkData, err := ioutil.ReadFile(chunkPath)
|
||||
chunkData, err := os.ReadFile(chunkPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -554,6 +603,7 @@ func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int)
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /files/chunkupload [post]
|
||||
func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
||||
var err error
|
||||
fileForm, err := c.FormFile("chunk")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
@@ -564,19 +614,16 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
chunkIndex, err := strconv.Atoi(c.PostForm("chunkIndex"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
chunkCount, err := strconv.Atoi(c.PostForm("chunkCount"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
fileOp := files.NewFileOp()
|
||||
tmpDir := path.Join(global.CONF.System.TmpDir, "upload")
|
||||
if !fileOp.Stat(tmpDir) {
|
||||
@@ -585,37 +632,50 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
filename := c.PostForm("filename")
|
||||
fileDir := filepath.Join(tmpDir, filename)
|
||||
|
||||
_ = os.MkdirAll(fileDir, 0755)
|
||||
if chunkIndex == 0 {
|
||||
if fileOp.Stat(fileDir) {
|
||||
_ = fileOp.DeleteDir(fileDir)
|
||||
}
|
||||
_ = os.MkdirAll(fileDir, 0755)
|
||||
}
|
||||
filePath := filepath.Join(fileDir, filename)
|
||||
|
||||
emptyFile, err := os.Create(filePath)
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = os.Remove(fileDir)
|
||||
}
|
||||
}()
|
||||
var (
|
||||
emptyFile *os.File
|
||||
chunkData []byte
|
||||
)
|
||||
|
||||
emptyFile, err = os.Create(filePath)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
defer emptyFile.Close()
|
||||
|
||||
chunkData, err := ioutil.ReadAll(uploadFile)
|
||||
chunkData, err = io.ReadAll(uploadFile)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrFileUpload, err)
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, buserr.WithMap(constant.ErrFileUpload, map[string]interface{}{"name": filename, "detail": err.Error()}, err))
|
||||
return
|
||||
}
|
||||
|
||||
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", filename, chunkIndex))
|
||||
err = ioutil.WriteFile(chunkPath, chunkData, 0644)
|
||||
err = os.WriteFile(chunkPath, chunkData, 0644)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrFileUpload, err)
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, buserr.WithMap(constant.ErrFileUpload, map[string]interface{}{"name": filename, "detail": err.Error()}, err))
|
||||
return
|
||||
}
|
||||
|
||||
if chunkIndex+1 == chunkCount {
|
||||
err = mergeChunks(filename, fileDir, c.PostForm("path"), chunkCount)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrFileUpload, err)
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, buserr.WithMap(constant.ErrFileUpload, map[string]interface{}{"name": filename, "detail": err.Error()}, err))
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, true)
|
||||
@@ -630,19 +690,12 @@ var wsUpgrade = websocket.Upgrader{
|
||||
},
|
||||
}
|
||||
|
||||
var WsManager = websocket2.Manager{
|
||||
Group: make(map[string]*websocket2.Client),
|
||||
Register: make(chan *websocket2.Client, 128),
|
||||
UnRegister: make(chan *websocket2.Client, 128),
|
||||
ClientCount: 0,
|
||||
}
|
||||
|
||||
func (b *BaseApi) Ws(c *gin.Context) {
|
||||
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
wsClient := websocket2.NewWsClient("wsClient", ws)
|
||||
wsClient := websocket2.NewWsClient("fileClient", ws)
|
||||
go wsClient.Read()
|
||||
go wsClient.Write()
|
||||
}
|
||||
|
207
backend/app/api/v1/firewall.go
Normal file
207
backend/app/api/v1/firewall.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Load firewall base info
|
||||
// @Description 获取防火墙基础信息
|
||||
// @Success 200 {object} dto.FirewallBaseInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/base [get]
|
||||
func (b *BaseApi) LoadFirewallBaseInfo(c *gin.Context) {
|
||||
data, err := firewallService.LoadBaseInfo()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Page firewall rules
|
||||
// @Description 获取防火墙规则列表分页
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchWithPage true "request"
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/search [post]
|
||||
func (b *BaseApi) SearchFirewallRule(c *gin.Context) {
|
||||
var req dto.RuleSearch
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
total, list, err := firewallService.SearchWithPage(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Page firewall status
|
||||
// @Description 修改防火墙状态
|
||||
// @Accept json
|
||||
// @Param request body dto.FirewallOperation true "request"
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operation] 防火墙","formatEN":"[operation] firewall"}
|
||||
func (b *BaseApi) OperateFirewall(c *gin.Context) {
|
||||
var req dto.FirewallOperation
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := firewallService.OperateFirewall(req.Operation); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 创建防火墙端口规则
|
||||
// @Accept json
|
||||
// @Param request body dto.PortRuleOperate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/port [post]
|
||||
// @x-panel-log {"bodyKeys":["port","strategy"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"添加端口规则 [strategy] [port]","formatEN":"create port rules [strategy][port]"}
|
||||
func (b *BaseApi) OperatePortRule(c *gin.Context) {
|
||||
var req dto.PortRuleOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.OperatePortRule(req, true); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 创建防火墙 IP 规则
|
||||
// @Accept json
|
||||
// @Param request body dto.AddrRuleOperate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/ip [post]
|
||||
// @x-panel-log {"bodyKeys":["strategy","address"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"添加 ip 规则 [strategy] [address]","formatEN":"create address rules [strategy][address]"}
|
||||
func (b *BaseApi) OperateIPRule(c *gin.Context) {
|
||||
var req dto.AddrRuleOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.OperateAddressRule(req, true); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 批量删除防火墙规则
|
||||
// @Accept json
|
||||
// @Param request body dto.BatchRuleOperate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/batch [post]
|
||||
func (b *BaseApi) BatchOperateRule(c *gin.Context) {
|
||||
var req dto.BatchRuleOperate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.BatchOperateRule(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 更新端口防火墙规则
|
||||
// @Accept json
|
||||
// @Param request body dto.PortRuleUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/update/port [post]
|
||||
func (b *BaseApi) UpdatePortRule(c *gin.Context) {
|
||||
var req dto.PortRuleUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.UpdatePortRule(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Firewall
|
||||
// @Summary Create group
|
||||
// @Description 更新 ip 防火墙规则
|
||||
// @Accept json
|
||||
// @Param request body dto.AddrRuleUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/firewall/update/addr [post]
|
||||
func (b *BaseApi) UpdateAddrRule(c *gin.Context) {
|
||||
var req dto.AddrRuleUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := firewallService.UpdateAddrRule(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
@@ -15,7 +15,7 @@ import (
|
||||
// @Param request body dto.GroupCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/group [post]
|
||||
// @Router /groups [post]
|
||||
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建组 [name][type]","formatEN":"create group [name][type]"}
|
||||
func (b *BaseApi) CreateGroup(c *gin.Context) {
|
||||
var req dto.GroupCreate
|
||||
@@ -41,8 +41,8 @@ func (b *BaseApi) CreateGroup(c *gin.Context) {
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/group/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"groups","output_colume":"name","output_value":"name"},{"input_colume":"id","input_value":"id","isList":false,"db":"groups","output_colume":"type","output_value":"type"}],"formatZH":"删除组 [type][name]","formatEN":"delete group [type][name]"}
|
||||
// @Router /groups/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"groups","output_column":"name","output_value":"name"},{"input_column":"id","input_value":"id","isList":false,"db":"groups","output_column":"type","output_value":"type"}],"formatZH":"删除组 [type][name]","formatEN":"delete group [type][name]"}
|
||||
func (b *BaseApi) DeleteGroup(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -68,7 +68,7 @@ func (b *BaseApi) DeleteGroup(c *gin.Context) {
|
||||
// @Param request body dto.GroupUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/group/update [post]
|
||||
// @Router /groups/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新组 [name][type]","formatEN":"update group [name][type]"}
|
||||
func (b *BaseApi) UpdateGroup(c *gin.Context) {
|
||||
var req dto.GroupUpdate
|
||||
@@ -92,9 +92,9 @@ func (b *BaseApi) UpdateGroup(c *gin.Context) {
|
||||
// @Description 查询系统组
|
||||
// @Accept json
|
||||
// @Param request body dto.GroupSearch true "request"
|
||||
// @Success 200 {anrry} dto.GroupInfo
|
||||
// @Success 200 {array} dto.GroupInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/group/search [post]
|
||||
// @Router /groups/search [post]
|
||||
func (b *BaseApi) ListGroup(c *gin.Context) {
|
||||
var req dto.GroupSearch
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -83,6 +83,15 @@ func SuccessWithData(ctx *gin.Context, data interface{}) {
|
||||
ctx.Abort()
|
||||
}
|
||||
|
||||
func SuccessWithOutData(ctx *gin.Context) {
|
||||
res := dto.Response{
|
||||
Code: constant.CodeSuccess,
|
||||
Message: "success",
|
||||
}
|
||||
ctx.JSON(http.StatusOK, res)
|
||||
ctx.Abort()
|
||||
}
|
||||
|
||||
func SuccessWithMsg(ctx *gin.Context, msg string) {
|
||||
res := dto.Response{
|
||||
Code: constant.CodeSuccess,
|
||||
|
@@ -1,14 +1,11 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/copier"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/ssh"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/encrypt"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -31,22 +28,6 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if req.AuthMode == "password" && len(req.Password) != 0 {
|
||||
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.Password = string(password)
|
||||
}
|
||||
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.PrivateKey = string(privateKey)
|
||||
}
|
||||
|
||||
host, err := hostService.Create(req)
|
||||
if err != nil {
|
||||
@@ -74,33 +55,9 @@ func (b *BaseApi) TestByInfo(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if req.AuthMode == "password" && len(req.Password) != 0 {
|
||||
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.Password = string(password)
|
||||
}
|
||||
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.PrivateKey = string(privateKey)
|
||||
}
|
||||
|
||||
var connInfo ssh.ConnInfo
|
||||
_ = copier.Copy(&connInfo, &req)
|
||||
connInfo.PrivateKey = []byte(req.PrivateKey)
|
||||
client, err := connInfo.NewClient()
|
||||
if err != nil {
|
||||
helper.SuccessWithData(c, false)
|
||||
return
|
||||
}
|
||||
defer client.Close()
|
||||
helper.SuccessWithData(c, true)
|
||||
connStatus := hostService.TestByInfo(req)
|
||||
helper.SuccessWithData(c, connStatus)
|
||||
}
|
||||
|
||||
// @Tags Host
|
||||
@@ -127,7 +84,7 @@ func (b *BaseApi) TestByID(c *gin.Context) {
|
||||
// @Description 加载主机树
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchForTree true "request"
|
||||
// @Success 200 {anrry} dto.HostTree
|
||||
// @Success 200 {array} dto.HostTree
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/tree [post]
|
||||
func (b *BaseApi) HostTree(c *gin.Context) {
|
||||
@@ -151,7 +108,7 @@ func (b *BaseApi) HostTree(c *gin.Context) {
|
||||
// @Description 获取主机列表分页
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchHostWithPage true "request"
|
||||
// @Success 200 {anrry} dto.HostTree
|
||||
// @Success 200 {array} dto.HostTree
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/search [post]
|
||||
func (b *BaseApi) SearchHost(c *gin.Context) {
|
||||
@@ -173,33 +130,6 @@ func (b *BaseApi) SearchHost(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Host
|
||||
// @Summary Load host info
|
||||
// @Description 加载主机信息
|
||||
// @Accept json
|
||||
// @Param id path integer true "request"
|
||||
// @Success 200 {object} dto.HostInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/:id [get]
|
||||
func (b *BaseApi) GetHostInfo(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
host, err := hostService.GetHostInfo(id)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
var hostDto dto.HostInfo
|
||||
if err := copier.Copy(&hostDto, host); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, hostDto)
|
||||
}
|
||||
|
||||
// @Tags Host
|
||||
// @Summary Delete host
|
||||
// @Description 删除主机
|
||||
@@ -208,7 +138,7 @@ func (b *BaseApi) GetHostInfo(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"hosts","output_colume":"addr","output_value":"addrs"}],"formatZH":"删除主机 [addrs]","formatEN":"delete host [addrs]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"hosts","output_column":"addr","output_value":"addrs"}],"formatZH":"删除主机 [addrs]","formatEN":"delete host [addrs]"}
|
||||
func (b *BaseApi) DeleteHost(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -246,21 +176,30 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if req.AuthMode == "password" && len(req.Password) != 0 {
|
||||
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||
var err error
|
||||
if len(req.Password) != 0 && req.AuthMode == "password" {
|
||||
req.Password, err = hostService.EncryptHost(req.Password)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.Password = string(password)
|
||||
req.PrivateKey = ""
|
||||
req.PassPhrase = ""
|
||||
}
|
||||
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||
if len(req.PrivateKey) != 0 && req.AuthMode == "key" {
|
||||
req.PrivateKey, err = hostService.EncryptHost(req.PrivateKey)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.PrivateKey = string(privateKey)
|
||||
if len(req.PassPhrase) != 0 {
|
||||
req.PassPhrase, err = encrypt.StringEncrypt(req.PassPhrase)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
req.Password = ""
|
||||
}
|
||||
|
||||
upMap := make(map[string]interface{})
|
||||
@@ -270,11 +209,15 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
||||
upMap["port"] = req.Port
|
||||
upMap["user"] = req.User
|
||||
upMap["auth_mode"] = req.AuthMode
|
||||
if len(req.Password) != 0 {
|
||||
upMap["remember_password"] = req.RememberPassword
|
||||
if req.AuthMode == "password" {
|
||||
upMap["password"] = req.Password
|
||||
}
|
||||
if len(req.PrivateKey) != 0 {
|
||||
upMap["private_key"] = ""
|
||||
upMap["pass_phrase"] = ""
|
||||
} else {
|
||||
upMap["password"] = ""
|
||||
upMap["private_key"] = req.PrivateKey
|
||||
upMap["pass_phrase"] = req.PassPhrase
|
||||
}
|
||||
upMap["description"] = req.Description
|
||||
if err := hostService.Update(req.ID, upMap); err != nil {
|
||||
@@ -291,8 +234,8 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
||||
// @Param request body dto.ChangeHostGroup true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /hosts/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id","group"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"hosts","output_colume":"addr","output_value":"addr"}],"formatZH":"切换主机[addr]分组 => [group]","formatEN":"change host [addr] group => [group]"}
|
||||
// @Router /hosts/update/group [post]
|
||||
// @x-panel-log {"bodyKeys":["id","group"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"hosts","output_column":"addr","output_value":"addr"}],"formatZH":"切换主机[addr]分组 => [group]","formatEN":"change host [addr] group => [group]"}
|
||||
func (b *BaseApi) UpdateHostGroup(c *gin.Context) {
|
||||
var req dto.ChangeHostGroup
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
213
backend/app/api/v1/host_tool.go
Normal file
213
backend/app/api/v1/host_tool.go
Normal file
@@ -0,0 +1,213 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get tool
|
||||
// @Description 获取主机工具状态
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool [post]
|
||||
func (b *BaseApi) GetToolStatus(c *gin.Context) {
|
||||
var req request.HostToolReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
config, err := hostToolService.GetToolStatus(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, config)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Create Host tool Config
|
||||
// @Description 创建主机工具配置
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/create [post]
|
||||
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建 [type] 配置","formatEN":"create [type] config"}
|
||||
func (b *BaseApi) InitToolConfig(c *gin.Context) {
|
||||
var req request.HostToolCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := hostToolService.CreateToolConfig(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Operate tool
|
||||
// @Description 操作主机工具
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["operate","type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operate] [type] ","formatEN":"[operate] [type]"}
|
||||
func (b *BaseApi) OperateTool(c *gin.Context) {
|
||||
var req request.HostToolReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
err := hostToolService.OperateTool(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get tool config
|
||||
// @Description 操作主机工具配置文件
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolConfig true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/config [post]
|
||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operate] 主机工具配置文件 ","formatEN":"[operate] tool config"}
|
||||
func (b *BaseApi) OperateToolConfig(c *gin.Context) {
|
||||
var req request.HostToolConfig
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
config, err := hostToolService.OperateToolConfig(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, config)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get tool
|
||||
// @Description 获取主机工具日志
|
||||
// @Accept json
|
||||
// @Param request body request.HostToolLogReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/log [post]
|
||||
func (b *BaseApi) GetToolLog(c *gin.Context) {
|
||||
var req request.HostToolLogReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
logContent, err := hostToolService.GetToolLog(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, logContent)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Create Supervisor process
|
||||
// @Description 操作守护进程
|
||||
// @Accept json
|
||||
// @Param request body request.SupervisorProcessConfig true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/supervisor/process [post]
|
||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operate] 守护进程 ","formatEN":"[operate] process"}
|
||||
func (b *BaseApi) OperateProcess(c *gin.Context) {
|
||||
var req request.SupervisorProcessConfig
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
err := hostToolService.OperateSupervisorProcess(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get Supervisor process config
|
||||
// @Description 获取 Supervisor 进程配置
|
||||
// @Accept json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/supervisor/process [get]
|
||||
func (b *BaseApi) GetProcess(c *gin.Context) {
|
||||
configs, err := hostToolService.GetSupervisorProcessConfig()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, configs)
|
||||
}
|
||||
|
||||
// @Tags Host tool
|
||||
// @Summary Get Supervisor process config
|
||||
// @Description 操作 Supervisor 进程文件
|
||||
// @Accept json
|
||||
// @Param request body request.SupervisorProcessFileReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/tool/supervisor/process/file [post]
|
||||
// @x-panel-log {"bodyKeys":["operate"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operate] Supervisor 进程文件 ","formatEN":"[operate] Supervisor Process Config file"}
|
||||
func (b *BaseApi) GetProcessFile(c *gin.Context) {
|
||||
var req request.SupervisorProcessFileReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
content, err := hostToolService.OperateSupervisorProcessFile(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, content)
|
||||
}
|
@@ -44,7 +44,7 @@ func (b *BaseApi) SearchImage(c *gin.Context) {
|
||||
// @Summary List images
|
||||
// @Description 获取镜像列表
|
||||
// @Produce json
|
||||
// @Success 200 {anrry} dto.Options
|
||||
// @Success 200 {array} dto.Options
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image [get]
|
||||
func (b *BaseApi) ListImage(c *gin.Context) {
|
||||
@@ -93,7 +93,7 @@ func (b *BaseApi) ImageBuild(c *gin.Context) {
|
||||
// @Success 200 {string} log
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/pull [post]
|
||||
// @x-panel-log {"bodyKeys":["repoID","imageName"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"repoID","isList":false,"db":"image_repos","output_colume":"name","output_value":"reponame"}],"formatZH":"镜像拉取 [reponame][imageName]","formatEN":"image pull [reponame][imageName]"}
|
||||
// @x-panel-log {"bodyKeys":["repoID","imageName"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"镜像拉取 [reponame][imageName]","formatEN":"image pull [reponame][imageName]"}
|
||||
func (b *BaseApi) ImagePull(c *gin.Context) {
|
||||
var req dto.ImagePull
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -122,7 +122,7 @@ func (b *BaseApi) ImagePull(c *gin.Context) {
|
||||
// @Success 200 {string} log
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/push [post]
|
||||
// @x-panel-log {"bodyKeys":["repoID","tagName","name"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"repoID","isList":false,"db":"image_repos","output_colume":"name","output_value":"reponame"}],"formatZH":"[tagName] 推送到 [reponame][name]","formatEN":"push [tagName] to [reponame][name]"}
|
||||
// @x-panel-log {"bodyKeys":["repoID","tagName","name"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"[tagName] 推送到 [reponame][name]","formatEN":"push [tagName] to [reponame][name]"}
|
||||
func (b *BaseApi) ImagePush(c *gin.Context) {
|
||||
var req dto.ImagePush
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -207,7 +207,7 @@ func (b *BaseApi) ImageSave(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/image/tag [post]
|
||||
// @x-panel-log {"bodyKeys":["repoID","targetName"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"repoID","isList":false,"db":"image_repos","output_colume":"name","output_value":"reponame"}],"formatZH":"tag 镜像 [reponame][targetName]","formatEN":"tag image [reponame][targetName]"}
|
||||
// @x-panel-log {"bodyKeys":["repoID","targetName"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"repoID","isList":false,"db":"image_repos","output_column":"name","output_value":"reponame"}],"formatZH":"tag 镜像 [reponame][targetName]","formatEN":"tag image [reponame][targetName]"}
|
||||
func (b *BaseApi) ImageTag(c *gin.Context) {
|
||||
var req dto.ImageTag
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -44,7 +44,7 @@ func (b *BaseApi) SearchRepo(c *gin.Context) {
|
||||
// @Summary List image repos
|
||||
// @Description 获取镜像仓库列表
|
||||
// @Produce json
|
||||
// @Success 200 {anrry} dto.ImageRepoOption
|
||||
// @Success 200 {array} dto.ImageRepoOption
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/repo [get]
|
||||
func (b *BaseApi) ListRepo(c *gin.Context) {
|
||||
@@ -119,7 +119,7 @@ func (b *BaseApi) CreateRepo(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/repo/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"image_repos","output_colume":"name","output_value":"names"}],"formatZH":"删除镜像仓库 [names]","formatEN":"delete image repo [names]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"image_repos","output_column":"name","output_value":"names"}],"formatZH":"删除镜像仓库 [names]","formatEN":"delete image repo [names]"}
|
||||
func (b *BaseApi) DeleteRepo(c *gin.Context) {
|
||||
var req dto.ImageRepoDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -147,7 +147,7 @@ func (b *BaseApi) DeleteRepo(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/repo/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_colume":"name","output_value":"name"}],"formatZH":"更新镜像仓库 [name]","formatEN":"update image repo information [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_column":"name","output_value":"name"}],"formatZH":"更新镜像仓库 [name]","formatEN":"update image repo information [name]"}
|
||||
func (b *BaseApi) UpdateRepo(c *gin.Context) {
|
||||
var req dto.ImageRepoUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -89,3 +89,19 @@ func (b *BaseApi) CleanLogs(c *gin.Context) {
|
||||
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Logs
|
||||
// @Summary Load system logs
|
||||
// @Description 获取系统日志
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /logs/system [get]
|
||||
func (b *BaseApi) GetSystemLogs(c *gin.Context) {
|
||||
data, err := logService.LoadSystemLog()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/shirou/gopsutil/v3/net"
|
||||
@@ -24,8 +25,9 @@ func (b *BaseApi) LoadMonitor(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
req.StartTime = req.StartTime.Add(8 * time.Hour)
|
||||
req.EndTime = req.EndTime.Add(8 * time.Hour)
|
||||
loc, _ := time.LoadLocation(common.LoadTimeZone())
|
||||
req.StartTime = req.StartTime.In(loc)
|
||||
req.EndTime = req.EndTime.In(loc)
|
||||
|
||||
var backdatas []dto.MonitorData
|
||||
if req.Param == "all" || req.Param == "cpu" || req.Param == "memory" || req.Param == "load" {
|
||||
|
@@ -27,7 +27,7 @@ func (b *BaseApi) GetNginx(c *gin.Context) {
|
||||
// @Description 获取部分 OpenResty 配置信息
|
||||
// @Accept json
|
||||
// @Param request body request.NginxScopeReq true "request"
|
||||
// @Success 200 {anrry} response.NginxParam
|
||||
// @Success 200 {array} response.NginxParam
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /openResty/scope [post]
|
||||
func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
|
||||
@@ -53,7 +53,7 @@ func (b *BaseApi) GetNginxConfigByScope(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /openResty/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteId","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"更新 nginx 配置 [domain]","formatEN":"Update nginx conf [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新 nginx 配置 [domain]","formatEN":"Update nginx conf [domain]"}
|
||||
func (b *BaseApi) UpdateNginxConfigByScope(c *gin.Context) {
|
||||
var req request.NginxConfigUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
40
backend/app/api/v1/process.go
Normal file
40
backend/app/api/v1/process.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
websocket2 "github.com/1Panel-dev/1Panel/backend/utils/websocket"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (b *BaseApi) ProcessWs(c *gin.Context) {
|
||||
ws, err := wsUpgrade.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
wsClient := websocket2.NewWsClient("processClient", ws)
|
||||
go wsClient.Read()
|
||||
go wsClient.Write()
|
||||
}
|
||||
|
||||
// @Tags Process
|
||||
// @Summary Stop Process
|
||||
// @Description 停止进程
|
||||
// @Param request body request.ProcessReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /process/stop [post]
|
||||
// @x-panel-log {"bodyKeys":["PID"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"结束进程 [PID]","formatEN":"结束进程 [PID]"}
|
||||
func (b *BaseApi) StopProcess(c *gin.Context) {
|
||||
var req request.ProcessReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := processService.StopProcess(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
180
backend/app/api/v1/remote_db.go
Normal file
180
backend/app/api/v1/remote_db.go
Normal file
@@ -0,0 +1,180 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Create remote database
|
||||
// @Description 创建远程数据库
|
||||
// @Accept json
|
||||
// @Param request body dto.RemoteDBCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote [post]
|
||||
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建远程数据库 [name][type]","formatEN":"create remote database [name][type]"}
|
||||
func (b *BaseApi) CreateRemoteDB(c *gin.Context) {
|
||||
var req dto.RemoteDBCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := remoteDBService.Create(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Check remote database
|
||||
// @Description 检测远程数据库连接性
|
||||
// @Accept json
|
||||
// @Param request body dto.RemoteDBCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote/check [post]
|
||||
// @x-panel-log {"bodyKeys":["name", "type"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"检测远程数据库 [name][type] 连接性","formatEN":"check if remote database [name][type] is connectable"}
|
||||
func (b *BaseApi) CheckeRemoteDB(c *gin.Context) {
|
||||
var req dto.RemoteDBCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, remoteDBService.CheckeRemoteDB(req))
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Page remote databases
|
||||
// @Description 获取远程数据库列表分页
|
||||
// @Accept json
|
||||
// @Param request body dto.RemoteDBSearch true "request"
|
||||
// @Success 200 {object} dto.PageResult
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote/search [post]
|
||||
func (b *BaseApi) SearchRemoteDB(c *gin.Context) {
|
||||
var req dto.RemoteDBSearch
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
total, list, err := remoteDBService.SearchWithPage(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Items: list,
|
||||
Total: total,
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary List remote databases
|
||||
// @Description 获取远程数据库列表
|
||||
// @Success 200 {array} dto.RemoteDBOption
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote/list/:type [get]
|
||||
func (b *BaseApi) ListRemoteDB(c *gin.Context) {
|
||||
dbType, err := helper.GetStrParamByKey(c, "type")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
list, err := remoteDBService.List(dbType)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Get remote databases
|
||||
// @Description 获取远程数据库
|
||||
// @Success 200 {object} dto.RemoteDBInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote/:name [get]
|
||||
func (b *BaseApi) GetRemoteDB(c *gin.Context) {
|
||||
name, err := helper.GetStrParamByKey(c, "name")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
data, err := remoteDBService.Get(name)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Delete remote database
|
||||
// @Description 删除远程数据库
|
||||
// @Accept json
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"databases","output_column":"name","output_value":"names"}],"formatZH":"删除远程数据库 [names]","formatEN":"delete remote database [names]"}
|
||||
func (b *BaseApi) DeleteRemoteDB(c *gin.Context) {
|
||||
var req dto.OperateByID
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := remoteDBService.Delete(req.ID); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Database
|
||||
// @Summary Update remote database
|
||||
// @Description 更新远程数据库
|
||||
// @Accept json
|
||||
// @Param request body dto.RemoteDBUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /databases/remote/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新远程数据库 [name]","formatEN":"update remote database [name]"}
|
||||
func (b *BaseApi) UpdateRemoteDB(c *gin.Context) {
|
||||
var req dto.RemoteDBUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := remoteDBService.Update(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
123
backend/app/api/v1/runtime.go
Normal file
123
backend/app/api/v1/runtime.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary List runtimes
|
||||
// @Description 获取运行环境列表
|
||||
// @Accept json
|
||||
// @Param request body request.RuntimeSearch true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/search [post]
|
||||
func (b *BaseApi) SearchRuntimes(c *gin.Context) {
|
||||
var req request.RuntimeSearch
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
total, items, err := runtimeService.Page(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, dto.PageResult{
|
||||
Total: total,
|
||||
Items: items,
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Create runtime
|
||||
// @Description 创建运行环境
|
||||
// @Accept json
|
||||
// @Param request body request.RuntimeCreate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建运行环境 [name]","formatEN":"Create runtime [name]"}
|
||||
func (b *BaseApi) CreateRuntime(c *gin.Context) {
|
||||
var req request.RuntimeCreate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := runtimeService.Create(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Delete runtime
|
||||
// @Description 删除运行环境
|
||||
// @Accept json
|
||||
// @Param request body request.RuntimeDelete true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"删除网站 [name]","formatEN":"Delete website [name]"}
|
||||
func (b *BaseApi) DeleteRuntime(c *gin.Context) {
|
||||
var req request.RuntimeDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
err := runtimeService.Delete(req.ID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Update runtime
|
||||
// @Description 更新运行环境
|
||||
// @Accept json
|
||||
// @Param request body request.RuntimeUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/update [post]
|
||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新运行环境 [name]","formatEN":"Update runtime [name]"}
|
||||
func (b *BaseApi) UpdateRuntime(c *gin.Context) {
|
||||
var req request.RuntimeUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := runtimeService.Update(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Get runtime
|
||||
// @Description 获取运行环境
|
||||
// @Accept json
|
||||
// @Param id path string true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /runtimes/:id [get]
|
||||
func (b *BaseApi) GetRuntime(c *gin.Context) {
|
||||
id, err := helper.GetIntParamByKey(c, "id")
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
res, err := runtimeService.Get(id)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
@@ -2,14 +2,16 @@ package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/mfa"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/ntp"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -92,6 +94,64 @@ func (b *BaseApi) UpdatePassword(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Update system ssl
|
||||
// @Description 修改系统 ssl 登录
|
||||
// @Accept json
|
||||
// @Param request body dto.SSLUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/ssl/update [post]
|
||||
// @x-panel-log {"bodyKeys":["ssl"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改系统 ssl => [ssl]","formatEN":"update system ssl => [ssl]"}
|
||||
func (b *BaseApi) UpdateSSL(c *gin.Context) {
|
||||
var req dto.SSLUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := settingService.UpdateSSL(c, req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Load system cert info
|
||||
// @Description 获取证书信息
|
||||
// @Success 200 {object} dto.SettingInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/ssl/info [get]
|
||||
func (b *BaseApi) LoadFromCert(c *gin.Context) {
|
||||
info, err := settingService.LoadFromCert()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, info)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Download system cert
|
||||
// @Description 下载证书
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/ssl/download [post]
|
||||
func (b *BaseApi) DownloadSSL(c *gin.Context) {
|
||||
pathItem := path.Join(global.CONF.System.BaseDir, "1panel/secret/server.crt")
|
||||
if _, err := os.Stat(pathItem); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.File(pathItem)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Update system port
|
||||
// @Description 更新系统端口
|
||||
@@ -147,26 +207,40 @@ func (b *BaseApi) HandlePasswordExpired(c *gin.Context) {
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
// @Summary Sync system time
|
||||
// @Description 系统时间同步
|
||||
// @Success 200 {string} ntime
|
||||
// @Summary Load time zone options
|
||||
// @Description 加载系统可用时区
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/time/sync [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"系统时间同步","formatEN":"sync system time"}
|
||||
func (b *BaseApi) SyncTime(c *gin.Context) {
|
||||
ntime, err := ntp.Getremotetime()
|
||||
// @Router /settings/time/option [get]
|
||||
func (b *BaseApi) LoadTimeZone(c *gin.Context) {
|
||||
zones, err := settingService.LoadTimeZone()
|
||||
if err != nil {
|
||||
helper.SuccessWithData(c, time.Now().Format("2006-01-02 15:04:05 MST -0700"))
|
||||
return
|
||||
}
|
||||
|
||||
ts := ntime.Format("2006-01-02 15:04:05")
|
||||
if err := ntp.UpdateSystemDate(ts); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, zones)
|
||||
}
|
||||
|
||||
helper.SuccessWithData(c, ntime.Format("2006-01-02 15:04:05 MST -0700"))
|
||||
// @Tags System Setting
|
||||
// @Summary Sync system time
|
||||
// @Description 系统时间同步
|
||||
// @Accept json
|
||||
// @Param request body dto.SyncTime true "request"
|
||||
// @Success 200 {string} ntime
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/time/sync [post]
|
||||
// @x-panel-log {"bodyKeys":["ntpSite"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"系统时间同步[ntpSite]","formatEN":"sync system time [ntpSite]"}
|
||||
func (b *BaseApi) SyncTime(c *gin.Context) {
|
||||
var req dto.SyncTime
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := settingService.SyncTime(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags System Setting
|
||||
@@ -206,11 +280,23 @@ func (b *BaseApi) CleanMonitor(c *gin.Context) {
|
||||
// @Tags System Setting
|
||||
// @Summary Load mfa info
|
||||
// @Description 获取 mfa 信息
|
||||
// @Param interval path string true "request"
|
||||
// @Success 200 {object} mfa.Otp
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/mfa [get]
|
||||
// @Router /settings/mfa/:interval [get]
|
||||
func (b *BaseApi) GetMFA(c *gin.Context) {
|
||||
otp, err := mfa.GetOtp("admin")
|
||||
intervalStr, ok := c.Params.Get("interval")
|
||||
if !ok {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error interval in path"))
|
||||
return
|
||||
}
|
||||
interval, err := strconv.Atoi(intervalStr)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, fmt.Errorf("type conversion failed, err: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
otp, err := mfa.GetOtp("admin", interval)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -234,12 +320,17 @@ func (b *BaseApi) MFABind(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
success := mfa.ValidCode(req.Code, req.Secret)
|
||||
success := mfa.ValidCode(req.Code, req.Interval, req.Secret)
|
||||
if !success {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, errors.New("code is not valid"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := settingService.Update("MFAInterval", req.Interval); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := settingService.Update("MFAStatus", "enable"); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
@@ -68,7 +68,7 @@ func (b *BaseApi) ImportSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/description/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"snapshots","output_colume":"name","output_value":"name"}],"formatZH":"快照 [name] 描述信息修改 [description]","formatEN":"The description of the snapshot [name] is modified => [description]"}
|
||||
// @x-panel-log {"bodyKeys":["id","description"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"快照 [name] 描述信息修改 [description]","formatEN":"The description of the snapshot [name] is modified => [description]"}
|
||||
func (b *BaseApi) UpdateSnapDescription(c *gin.Context) {
|
||||
var req dto.UpdateDescription
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -119,7 +119,7 @@ func (b *BaseApi) SearchSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/recover [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"snapshots","output_colume":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 恢复","formatEN":"Recover from system backup [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 恢复","formatEN":"Recover from system backup [name]"}
|
||||
func (b *BaseApi) RecoverSnapshot(c *gin.Context) {
|
||||
var req dto.SnapshotRecover
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -146,7 +146,7 @@ func (b *BaseApi) RecoverSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/rollback [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"snapshots","output_colume":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 回滚","formatEN":"Rollback from system backup [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"从系统快照 [name] 回滚","formatEN":"Rollback from system backup [name]"}
|
||||
func (b *BaseApi) RollbackSnapshot(c *gin.Context) {
|
||||
var req dto.SnapshotRecover
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -173,7 +173,7 @@ func (b *BaseApi) RollbackSnapshot(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /settings/snapshot/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"ids","isList":true,"db":"snapshots","output_colume":"name","output_value":"name"}],"formatZH":"删除系统快照 [name]","formatEN":"Delete system backup [name]"}
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"ids","isList":true,"db":"snapshots","output_column":"name","output_value":"name"}],"formatZH":"删除系统快照 [name]","formatEN":"Delete system backup [name]"}
|
||||
func (b *BaseApi) DeleteSnapshot(c *gin.Context) {
|
||||
var req dto.BatchDeleteReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
200
backend/app/api/v1/ssh.go
Normal file
200
backend/app/api/v1/ssh.go
Normal file
@@ -0,0 +1,200 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host ssh setting info
|
||||
// @Description 加载 SSH 配置信息
|
||||
// @Success 200 {object} dto.SSHInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/search [post]
|
||||
func (b *BaseApi) GetSSHInfo(c *gin.Context) {
|
||||
info, err := sshService.GetSSHInfo()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, info)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Operate ssh
|
||||
// @Description 修改 SSH 服务状态
|
||||
// @Accept json
|
||||
// @Param request body dto.Operate true "request"
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["operation"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"[operation] SSH ","formatEN":"[operation] SSH"}
|
||||
func (b *BaseApi) OperateSSH(c *gin.Context) {
|
||||
var req dto.Operate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := sshService.OperateSSH(req.Operation); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Update host ssh setting
|
||||
// @Description 更新 SSH 配置
|
||||
// @Accept json
|
||||
// @Param request body dto.SettingUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/update [post]
|
||||
// @x-panel-log {"bodyKeys":["key","value"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改 SSH 配置 [key] => [value]","formatEN":"update SSH setting [key] => [value]"}
|
||||
func (b *BaseApi) UpdateSSH(c *gin.Context) {
|
||||
var req dto.SettingUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := sshService.Update(req.Key, req.Value); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Update host ssh setting by file
|
||||
// @Description 上传文件更新 SSH 配置
|
||||
// @Accept json
|
||||
// @Param request body dto.SSHConf true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/conffile/update [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"修改 SSH 配置文件","formatEN":"update SSH conf"}
|
||||
func (b *BaseApi) UpdateSSHByfile(c *gin.Context) {
|
||||
var req dto.SSHConf
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := sshService.UpdateByFile(req.File); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Generate host ssh secret
|
||||
// @Description 生成 ssh 密钥
|
||||
// @Accept json
|
||||
// @Param request body dto.GenerateSSH true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/generate [post]
|
||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"生成 SSH 密钥 ","formatEN":"generate SSH secret"}
|
||||
func (b *BaseApi) GenerateSSH(c *gin.Context) {
|
||||
var req dto.GenerateSSH
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := sshService.GenerateSSH(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host ssh secret
|
||||
// @Description 获取 ssh 密钥
|
||||
// @Accept json
|
||||
// @Param request body dto.GenerateLoad true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/secret [post]
|
||||
func (b *BaseApi) LoadSSHSecret(c *gin.Context) {
|
||||
var req dto.GenerateLoad
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := sshService.LoadSSHSecret(req.EncryptionMode)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host ssh logs
|
||||
// @Description 获取 ssh 登录日志
|
||||
// @Accept json
|
||||
// @Param request body dto.SearchSSHLog true "request"
|
||||
// @Success 200 {object} dto.SSHLog
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/logs [post]
|
||||
func (b *BaseApi) LoadSSHLogs(c *gin.Context) {
|
||||
var req dto.SearchSSHLog
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := global.VALID.Struct(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := sshService.LoadLog(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags SSH
|
||||
// @Summary Load host ssh conf
|
||||
// @Description 获取 ssh 配置文件
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /host/ssh/conf [get]
|
||||
func (b *BaseApi) LoadSSHConf(c *gin.Context) {
|
||||
data, err := sshService.LoadSSHConf()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
@@ -1,13 +1,14 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/copier"
|
||||
@@ -19,30 +20,6 @@ import (
|
||||
)
|
||||
|
||||
func (b *BaseApi) WsSsh(c *gin.Context) {
|
||||
id, err := strconv.Atoi(c.Query("id"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
host, err := hostService.GetHostInfo(uint(id))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
var connInfo ssh.ConnInfo
|
||||
_ = copier.Copy(&connInfo, &host)
|
||||
connInfo.PrivateKey = []byte(host.PrivateKey)
|
||||
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
@@ -50,17 +27,35 @@ func (b *BaseApi) WsSsh(c *gin.Context) {
|
||||
}
|
||||
defer wsConn.Close()
|
||||
|
||||
id, err := strconv.Atoi(c.Query("id"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param id in request")) {
|
||||
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
|
||||
}
|
||||
host, err := hostService.GetHostInfo(uint(id))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "load host info by id failed")) {
|
||||
return
|
||||
}
|
||||
var connInfo ssh.ConnInfo
|
||||
_ = copier.Copy(&connInfo, &host)
|
||||
connInfo.PrivateKey = []byte(host.PrivateKey)
|
||||
if len(host.PassPhrase) != 0 {
|
||||
connInfo.PassPhrase = []byte(host.PassPhrase)
|
||||
}
|
||||
|
||||
client, err := connInfo.NewClient()
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) {
|
||||
return
|
||||
}
|
||||
defer client.Close()
|
||||
ssConn, err := connInfo.NewSshConn(cols, rows)
|
||||
if wshandleError(wsConn, err) {
|
||||
return
|
||||
}
|
||||
defer ssConn.Close()
|
||||
|
||||
|
||||
sws, err := terminal.NewLogicSshWsSession(cols, rows, true, connInfo.Client, wsConn)
|
||||
if wshandleError(wsConn, err) {
|
||||
return
|
||||
@@ -79,37 +74,36 @@ func (b *BaseApi) WsSsh(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) RedisWsSsh(c *gin.Context) {
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
redisConf, err := redisService.LoadConf()
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load redis container failed, err: %v", err)
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
defer wsConn.Close()
|
||||
commands := fmt.Sprintf("docker exec -it %s redis-cli", redisConf.ContainerName)
|
||||
if len(redisConf.Requirepass) != 0 {
|
||||
commands = fmt.Sprintf("docker exec -it %s redis-cli -a %s --no-auth-warning", redisConf.ContainerName, redisConf.Requirepass)
|
||||
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param cols in request")) {
|
||||
return
|
||||
}
|
||||
slave, err := terminal.NewCommand(commands)
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
|
||||
return
|
||||
}
|
||||
redisConf, err := redisService.LoadConf()
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "load redis container failed")) {
|
||||
return
|
||||
}
|
||||
|
||||
defer wsConn.Close()
|
||||
commands := "redis-cli"
|
||||
if len(redisConf.Requirepass) != 0 {
|
||||
commands = fmt.Sprintf("redis-cli -a %s --no-auth-warning", redisConf.Requirepass)
|
||||
}
|
||||
pidMap := loadMapFromDockerTop(redisConf.ContainerName)
|
||||
slave, err := terminal.NewCommand(fmt.Sprintf("docker exec -it %s %s", redisConf.ContainerName, commands))
|
||||
if wshandleError(wsConn, err) {
|
||||
return
|
||||
}
|
||||
defer killBash(redisConf.ContainerName, commands, pidMap)
|
||||
defer slave.Close()
|
||||
|
||||
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave)
|
||||
@@ -130,24 +124,6 @@ func (b *BaseApi) RedisWsSsh(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
|
||||
containerID := c.Query("containerid")
|
||||
command := c.Query("command")
|
||||
user := c.Query("user")
|
||||
if len(command) == 0 || len(containerID) == 0 {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error param of command or containerID"))
|
||||
return
|
||||
}
|
||||
cols, err := strconv.Atoi(c.DefaultQuery("cols", "80"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
rows, err := strconv.Atoi(c.DefaultQuery("rows", "40"))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
|
||||
wsConn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("gin context http handler failed, err: %v", err)
|
||||
@@ -155,11 +131,33 @@ func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
|
||||
}
|
||||
defer wsConn.Close()
|
||||
|
||||
cmds := fmt.Sprintf("docker exec %s %s", containerID, command)
|
||||
if len(user) != 0 {
|
||||
cmds = fmt.Sprintf("docker exec -u %s %s %s", user, containerID, command)
|
||||
containerID := c.Query("containerid")
|
||||
command := c.Query("command")
|
||||
user := c.Query("user")
|
||||
if len(command) == 0 || len(containerID) == 0 {
|
||||
if wshandleError(wsConn, errors.New("error param of command or containerID")) {
|
||||
return
|
||||
}
|
||||
}
|
||||
stdout, err := cmd.Exec(cmds)
|
||||
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
|
||||
}
|
||||
|
||||
cmds := []string{"exec", containerID, command}
|
||||
if len(user) != 0 {
|
||||
cmds = []string{"exec", "-u", user, containerID, command}
|
||||
}
|
||||
if cmd.CheckIllegal(user, containerID, command) {
|
||||
if wshandleError(wsConn, errors.New(" The command contains illegal characters.")) {
|
||||
return
|
||||
}
|
||||
}
|
||||
stdout, err := cmd.ExecWithCheck("docker", cmds...)
|
||||
if wshandleError(wsConn, errors.WithMessage(err, stdout)) {
|
||||
return
|
||||
}
|
||||
@@ -168,10 +166,12 @@ func (b *BaseApi) ContainerWsSsh(c *gin.Context) {
|
||||
if len(user) != 0 {
|
||||
commands = fmt.Sprintf("docker exec -it -u %s %s %s", user, containerID, command)
|
||||
}
|
||||
pidMap := loadMapFromDockerTop(containerID)
|
||||
slave, err := terminal.NewCommand(commands)
|
||||
if wshandleError(wsConn, err) {
|
||||
return
|
||||
}
|
||||
defer killBash(containerID, command, pidMap)
|
||||
defer slave.Close()
|
||||
|
||||
tty, err := terminal.NewLocalWsSession(cols, rows, wsConn, slave)
|
||||
@@ -196,13 +196,57 @@ func wshandleError(ws *websocket.Conn, err error) bool {
|
||||
global.LOG.Errorf("handler ws faled:, err: %v", err)
|
||||
dt := time.Now().Add(time.Second)
|
||||
if ctlerr := ws.WriteControl(websocket.CloseMessage, []byte(err.Error()), dt); ctlerr != nil {
|
||||
_ = ws.WriteMessage(websocket.TextMessage, []byte(err.Error()))
|
||||
wsData, err := json.Marshal(terminal.WsMsg{
|
||||
Type: terminal.WsMsgCmd,
|
||||
Data: base64.StdEncoding.EncodeToString([]byte(err.Error())),
|
||||
})
|
||||
if err != nil {
|
||||
_ = ws.WriteMessage(websocket.TextMessage, []byte("{\"type\":\"cmd\",\"data\":\"failed to encoding to json\"}"))
|
||||
} else {
|
||||
_ = ws.WriteMessage(websocket.TextMessage, wsData)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func loadMapFromDockerTop(containerID string) map[string]string {
|
||||
pidMap := make(map[string]string)
|
||||
sudo := cmd.SudoHandleCmd()
|
||||
|
||||
stdout, err := cmd.Execf("%s docker top %s -eo pid,command ", sudo, containerID)
|
||||
if err != nil {
|
||||
return pidMap
|
||||
}
|
||||
lines := strings.Split(stdout, "\n")
|
||||
for _, line := range lines {
|
||||
parts := strings.Fields(line)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
pidMap[parts[0]] = parts[1]
|
||||
}
|
||||
return pidMap
|
||||
}
|
||||
|
||||
func killBash(containerID, comm string, pidMap map[string]string) {
|
||||
sudo := cmd.SudoHandleCmd()
|
||||
newPidMap := loadMapFromDockerTop(containerID)
|
||||
for pid, command := range newPidMap {
|
||||
isOld := false
|
||||
for pid2 := range pidMap {
|
||||
if pid == pid2 {
|
||||
isOld = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isOld && command == comm {
|
||||
_, _ = cmd.Execf("%s kill -9 %s", sudo, pid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var upGrader = websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024 * 1024 * 10,
|
||||
|
@@ -36,7 +36,7 @@ func (b *BaseApi) PageWebsite(c *gin.Context) {
|
||||
// @Tags Website
|
||||
// @Summary List websites
|
||||
// @Description 获取网站列表
|
||||
// @Success 200 {anrry} response.WebsiteDTO
|
||||
// @Success 200 {array} response.WebsiteDTO
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/list [get]
|
||||
func (b *BaseApi) GetWebsites(c *gin.Context) {
|
||||
@@ -51,7 +51,7 @@ func (b *BaseApi) GetWebsites(c *gin.Context) {
|
||||
// @Tags Website
|
||||
// @Summary List website names
|
||||
// @Description 获取网站列表
|
||||
// @Success 200 {anrry} string
|
||||
// @Success 200 {array} string
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/options [get]
|
||||
func (b *BaseApi) GetWebsiteOptions(c *gin.Context) {
|
||||
@@ -78,14 +78,12 @@ func (b *BaseApi) CreateWebsite(c *gin.Context) {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
tx, ctx := helper.GetTxAndContext()
|
||||
err := websiteService.CreateWebsite(ctx, req)
|
||||
|
||||
err := websiteService.CreateWebsite(req)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
@@ -97,7 +95,7 @@ func (b *BaseApi) CreateWebsite(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/operate [post]
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"[operate] 网站 [domain]","formatEN":"[operate] website [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[operate] 网站 [domain]","formatEN":"[operate] website [domain]"}
|
||||
func (b *BaseApi) OpWebsite(c *gin.Context) {
|
||||
var req request.WebsiteOp
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -120,21 +118,19 @@ func (b *BaseApi) OpWebsite(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"删除网站 [domain]","formatEN":"Delete website [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除网站 [domain]","formatEN":"Delete website [domain]"}
|
||||
func (b *BaseApi) DeleteWebsite(c *gin.Context) {
|
||||
var req request.WebsiteDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
tx, ctx := helper.GetTxAndContext()
|
||||
err := websiteService.DeleteWebsite(ctx, req)
|
||||
|
||||
err := websiteService.DeleteWebsite(req)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
tx.Commit()
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
@@ -189,14 +185,16 @@ func (b *BaseApi) GetWebsite(c *gin.Context) {
|
||||
// @Param id path integer true "request"
|
||||
// @Success 200 {object} response.FileInfo
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/:id/nginx [get]
|
||||
// @Router /websites/:id/config/:type [get]
|
||||
func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
fileInfo, err := websiteService.GetWebsiteNginxConfig(id)
|
||||
configType := c.Param("type")
|
||||
|
||||
fileInfo, err := websiteService.GetWebsiteNginxConfig(id, configType)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -209,7 +207,7 @@ func (b *BaseApi) GetWebsiteNginx(c *gin.Context) {
|
||||
// @Description 通过网站 id 查询域名
|
||||
// @Accept json
|
||||
// @Param websiteId path integer true "request"
|
||||
// @Success 200 {anrry} model.WebsiteDomain
|
||||
// @Success 200 {array} model.WebsiteDomain
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/domains/:websiteId [get]
|
||||
func (b *BaseApi) GetWebDomains(c *gin.Context) {
|
||||
@@ -234,7 +232,7 @@ func (b *BaseApi) GetWebDomains(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/domains/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_domains","output_colume":"domain","output_value":"domain"}],"formatZH":"删除域名 [domain]","formatEN":"Delete domain [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_domains","output_column":"domain","output_value":"domain"}],"formatZH":"删除域名 [domain]","formatEN":"Delete domain [domain]"}
|
||||
func (b *BaseApi) DeleteWebDomain(c *gin.Context) {
|
||||
var req request.WebsiteDomainDelete
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -302,7 +300,7 @@ func (b *BaseApi) GetNginxConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/config/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteId","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"nginx 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"nginx 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
|
||||
func (b *BaseApi) UpdateNginxConfig(c *gin.Context) {
|
||||
var req request.NginxConfigUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -346,7 +344,7 @@ func (b *BaseApi) GetHTTPSConfig(c *gin.Context) {
|
||||
// @Success 200 {object} response.WebsiteHTTPS
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/:id/https [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteId","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] https 配置","formatEN":"Update website https [domain] conf"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"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) {
|
||||
var req request.WebsiteHTTPSOp
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -369,7 +367,7 @@ func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) {
|
||||
// @Description 网站创建前检查
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteInstallCheckReq true "request"
|
||||
// @Success 200 {anrry} request.WebsitePreInstallCheck
|
||||
// @Success 200 {array} response.WebsitePreInstallCheck
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/check [post]
|
||||
func (b *BaseApi) CreateWebsiteCheck(c *gin.Context) {
|
||||
@@ -416,7 +414,7 @@ func (b *BaseApi) GetWebsiteWafConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/waf/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"websiteId","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"WAF 配置修改 [domain]","formatEN":"WAF conf update [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"WAF 配置修改 [domain]","formatEN":"WAF conf update [domain]"}
|
||||
func (b *BaseApi) UpdateWebsiteWafConfig(c *gin.Context) {
|
||||
var req request.WebsiteWafUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -430,6 +428,28 @@ func (b *BaseApi) UpdateWebsiteWafConfig(c *gin.Context) {
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website WAF
|
||||
// @Summary Update website waf file
|
||||
// @Description 更新 网站 waf 配置文件
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteWafUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/waf/file/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"WAF 配置文件修改 [domain]","formatEN":"WAF conf file update [domain]"}
|
||||
func (b *BaseApi) UpdateWebsiteWafFile(c *gin.Context) {
|
||||
var req request.WebsiteWafFileUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateWafFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website Nginx
|
||||
// @Summary Update website nginx conf
|
||||
// @Description 更新 网站 nginx 配置
|
||||
@@ -438,7 +458,7 @@ func (b *BaseApi) UpdateWebsiteWafConfig(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/nginx/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"[domain] Nginx 配置修改","formatEN":"[domain] Nginx conf update"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain] Nginx 配置修改","formatEN":"[domain] Nginx conf update"}
|
||||
func (b *BaseApi) UpdateWebsiteNginxConfig(c *gin.Context) {
|
||||
var req request.WebsiteNginxUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -460,7 +480,7 @@ func (b *BaseApi) UpdateWebsiteNginxConfig(c *gin.Context) {
|
||||
// @Success 200 {object} response.WebsiteLog
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/log [post]
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"[domain][operate] 日志","formatEN":"[domain][operate] logs"}
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"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) {
|
||||
var req request.WebsiteLogReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -483,7 +503,7 @@ func (b *BaseApi) OpWebsiteLog(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/default/server [post]
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"websites","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"修改默认 server => [domain]","formatEN":"Change default server => [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["id", "operate"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改默认 server => [domain]","formatEN":"Change default server => [domain]"}
|
||||
func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
|
||||
var req request.WebsiteDefaultUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -496,3 +516,399 @@ func (b *BaseApi) ChangeDefaultServer(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Load websit php conf
|
||||
// @Description 获取网站 php 配置
|
||||
// @Accept json
|
||||
// @Param id path integer true "request"
|
||||
// @Success 200 {object} response.PHPConfig
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/config/:id [get]
|
||||
func (b *BaseApi) GetWebsitePHPConfig(c *gin.Context) {
|
||||
id, err := helper.GetParamID(c)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInternalServer, nil)
|
||||
return
|
||||
}
|
||||
data, err := websiteService.GetPHPConfig(id)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Website PHP
|
||||
// @Summary Update website php conf
|
||||
// @Description 更新 网站 PHP 配置
|
||||
// @Accept json
|
||||
// @Param request body request.WebsitePHPConfigUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/config [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"[domain] PHP 配置修改","formatEN":"[domain] PHP conf update"}
|
||||
func (b *BaseApi) UpdateWebsitePHPConfig(c *gin.Context) {
|
||||
var req request.WebsitePHPConfigUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdatePHPConfig(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website PHP
|
||||
// @Summary Update php conf
|
||||
// @Description 更新 php 配置文件
|
||||
// @Accept json
|
||||
// @Param request body request.WebsitePHPFileUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"php 配置修改 [domain]","formatEN":"Nginx conf update [domain]"}
|
||||
func (b *BaseApi) UpdatePHPFile(c *gin.Context) {
|
||||
var req request.WebsitePHPFileUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdatePHPConfigFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website PHP
|
||||
// @Summary Update php version
|
||||
// @Description 变更 php 版本
|
||||
// @Accept json
|
||||
// @Param request body request.WebsitePHPVersionReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/php/version [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteId","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"php 版本变更 [domain]","formatEN":"php version update [domain]"}
|
||||
func (b *BaseApi) ChangePHPVersion(c *gin.Context) {
|
||||
var req request.WebsitePHPVersionReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.ChangePHPVersion(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get rewrite conf
|
||||
// @Description 获取伪静态配置
|
||||
// @Accept json
|
||||
// @Param request body request.NginxRewriteReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/rewrite [post]
|
||||
func (b *BaseApi) GetRewriteConfig(c *gin.Context) {
|
||||
var req request.NginxRewriteReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := websiteService.GetRewriteConfig(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update rewrite conf
|
||||
// @Description 更新伪静态配置
|
||||
// @Accept json
|
||||
// @Param request body request.NginxRewriteUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/rewrite/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"伪静态配置修改 [domain]","formatEN":"Nginx conf rewrite update [domain]"}
|
||||
func (b *BaseApi) UpdateRewriteConfig(c *gin.Context) {
|
||||
var req request.NginxRewriteUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateRewriteConfig(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update Site Dir
|
||||
// @Description 更新网站目录
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteUpdateDir true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dir/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] 目录","formatEN":"Update domain [domain] dir"}
|
||||
func (b *BaseApi) UpdateSiteDir(c *gin.Context) {
|
||||
var req request.WebsiteUpdateDir
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateSiteDir(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update Site Dir permission
|
||||
// @Description 更新网站目录权限
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteUpdateDirPermission true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dir/permission [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新网站 [domain] 目录权限","formatEN":"Update domain [domain] dir permission"}
|
||||
func (b *BaseApi) UpdateSiteDirPermission(c *gin.Context) {
|
||||
var req request.WebsiteUpdateDirPermission
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateSitePermission(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get proxy conf
|
||||
// @Description 获取反向代理配置
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteProxyReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/proxies [post]
|
||||
func (b *BaseApi) GetProxyConfig(c *gin.Context) {
|
||||
var req request.WebsiteProxyReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := websiteService.GetProxies(req.ID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update proxy conf
|
||||
// @Description 修改反向代理配置
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteProxyConfig true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/proxies/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"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"}
|
||||
func (b *BaseApi) UpdateProxyConfig(c *gin.Context) {
|
||||
var req request.WebsiteProxyConfig
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
err := websiteService.OperateProxy(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update proxy file
|
||||
// @Description 更新反向代理文件
|
||||
// @Accept json
|
||||
// @Param request body request.NginxProxyUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/proxy/file [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新反向代理文件 [domain]","formatEN":"Nginx conf proxy file update [domain]"}
|
||||
func (b *BaseApi) UpdateProxyConfigFile(c *gin.Context) {
|
||||
var req request.NginxProxyUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateProxyFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get AuthBasic conf
|
||||
// @Description 获取密码访问配置
|
||||
// @Accept json
|
||||
// @Param request body request.NginxAuthReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/auths [post]
|
||||
func (b *BaseApi) GetAuthConfig(c *gin.Context) {
|
||||
var req request.NginxAuthReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := websiteService.GetAuthBasics(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get AuthBasic conf
|
||||
// @Description 更新密码访问配置
|
||||
// @Accept json
|
||||
// @Param request body request.NginxAuthUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/auths/update [post]
|
||||
func (b *BaseApi) UpdateAuthConfig(c *gin.Context) {
|
||||
var req request.NginxAuthUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateAuthBasic(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get AntiLeech conf
|
||||
// @Description 获取防盗链配置
|
||||
// @Accept json
|
||||
// @Param request body request.NginxCommonReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/leech [post]
|
||||
func (b *BaseApi) GetAntiLeech(c *gin.Context) {
|
||||
var req request.NginxCommonReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := websiteService.GetAntiLeech(req.WebsiteID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update AntiLeech
|
||||
// @Description 更新防盗链配置
|
||||
// @Accept json
|
||||
// @Param request body request.NginxAntiLeechUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/leech/update [post]
|
||||
func (b *BaseApi) UpdateAntiLeech(c *gin.Context) {
|
||||
var req request.NginxAntiLeechUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateAntiLeech(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update redirect conf
|
||||
// @Description 修改重定向配置
|
||||
// @Accept json
|
||||
// @Param request body request.NginxRedirectReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/redirect/update [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"修改网站 [domain] 重定向理配置 ","formatEN":"Update domain [domain] redirect config"}
|
||||
func (b *BaseApi) UpdateRedirectConfig(c *gin.Context) {
|
||||
var req request.NginxRedirectReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
err := websiteService.OperateRedirect(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Get redirect conf
|
||||
// @Description 获取重定向配置
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteProxyReq true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/redirect [post]
|
||||
func (b *BaseApi) GetRedirectConfig(c *gin.Context) {
|
||||
var req request.WebsiteRedirectReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
res, err := websiteService.GetRedirect(req.WebsiteID)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, res)
|
||||
}
|
||||
|
||||
// @Tags Website
|
||||
// @Summary Update redirect file
|
||||
// @Description 更新重定向文件
|
||||
// @Accept json
|
||||
// @Param request body request.NginxRedirectUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/redirect/file [post]
|
||||
// @x-panel-log {"bodyKeys":["websiteID"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"websiteID","isList":false,"db":"websites","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新重定向文件 [domain]","formatEN":"Nginx conf redirect file update [domain]"}
|
||||
func (b *BaseApi) UpdateRedirectConfigFile(c *gin.Context) {
|
||||
var req request.NginxRedirectUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||
return
|
||||
}
|
||||
if err := websiteService.UpdateRedirectFile(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithOutData(c)
|
||||
}
|
||||
|
@@ -64,7 +64,7 @@ func (b *BaseApi) CreateWebsiteAcmeAccount(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/acme/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_acme_accounts","output_colume":"email","output_value":"email"}],"formatZH":"删除网站 acme [email]","formatEN":"Delete website acme [email]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_acme_accounts","output_column":"email","output_value":"email"}],"formatZH":"删除网站 acme [email]","formatEN":"Delete website acme [email]"}
|
||||
func (b *BaseApi) DeleteWebsiteAcmeAccount(c *gin.Context) {
|
||||
var req request.WebsiteResourceReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -85,7 +85,7 @@ func (b *BaseApi) UpdateWebsiteDnsAccount(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/dns/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_dns_accounts","output_colume":"name","output_value":"name"}],"formatZH":"删除网站 dns [name]","formatEN":"Delete website dns [name]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_dns_accounts","output_column":"name","output_value":"name"}],"formatZH":"删除网站 dns [name]","formatEN":"Delete website dns [name]"}
|
||||
func (b *BaseApi) DeleteWebsiteDnsAccount(c *gin.Context) {
|
||||
var req request.WebsiteResourceReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -35,7 +35,7 @@ func (b *BaseApi) PageWebsiteSSL(c *gin.Context) {
|
||||
Items: accounts,
|
||||
})
|
||||
} else {
|
||||
list, err := websiteSSLService.Search()
|
||||
list, err := websiteSSLService.Search(req)
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
@@ -75,7 +75,7 @@ func (b *BaseApi) CreateWebsiteSSL(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/renew [post]
|
||||
// @x-panel-log {"bodyKeys":["SSLId"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"SSLId","isList":false,"db":"website_ssls","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"重置 ssl [domain]","formatEN":"Renew ssl [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["SSLId"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"SSLId","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"重置 ssl [domain]","formatEN":"Renew ssl [domain]"}
|
||||
func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) {
|
||||
var req request.WebsiteSSLRenew
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -94,7 +94,7 @@ func (b *BaseApi) RenewWebsiteSSL(c *gin.Context) {
|
||||
// @Description 解析网站 ssl
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteDNSReq true "request"
|
||||
// @Success 200 {anrry} response.WebsiteDNSRes
|
||||
// @Success 200 {array} response.WebsiteDNSRes
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/resolve [post]
|
||||
func (b *BaseApi) GetDNSResolve(c *gin.Context) {
|
||||
@@ -119,7 +119,7 @@ func (b *BaseApi) GetDNSResolve(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/del [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_ssls","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"删除 ssl [domain]","formatEN":"Delete ssl [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除 ssl [domain]","formatEN":"Delete ssl [domain]"}
|
||||
func (b *BaseApi) DeleteWebsiteSSL(c *gin.Context) {
|
||||
var req request.WebsiteResourceReq
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -185,7 +185,7 @@ func (b *BaseApi) GetWebsiteSSLById(c *gin.Context) {
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/update [post]
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_ssls","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"更新证书设置 [domain]","formatEN":"Update ssl config [domain]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"更新证书设置 [domain]","formatEN":"Update ssl config [domain]"}
|
||||
func (b *BaseApi) UpdateWebsiteSSL(c *gin.Context) {
|
||||
var req request.WebsiteSSLUpdate
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
)
|
||||
|
||||
type AppDatabase struct {
|
||||
@@ -15,6 +15,10 @@ type AuthParam struct {
|
||||
RootPassword string `json:"PANEL_DB_ROOT_PASSWORD"`
|
||||
}
|
||||
|
||||
type RedisAuthParam struct {
|
||||
RootPassword string `json:"PANEL_REDIS_ROOT_PASSWORD"`
|
||||
}
|
||||
|
||||
type ContainerExec struct {
|
||||
ContainerName string `json:"containerName"`
|
||||
DbParam AppDatabase `json:"dbParam"`
|
||||
@@ -32,19 +36,47 @@ type AppVersion struct {
|
||||
}
|
||||
|
||||
type AppList struct {
|
||||
Version string `json:"version"`
|
||||
Tags []Tag `json:"tags"`
|
||||
Items []AppDefine `json:"items"`
|
||||
Valid bool `json:"valid"`
|
||||
Violations []string `json:"violations"`
|
||||
LastModified int `json:"lastModified"`
|
||||
|
||||
Apps []AppDefine `json:"apps"`
|
||||
Extra ExtraProperties `json:"additionalProperties"`
|
||||
}
|
||||
|
||||
type AppDefine struct {
|
||||
Key string `json:"key"`
|
||||
Icon string `json:"icon"`
|
||||
Name string `json:"name"`
|
||||
ReadMe string `json:"readMe"`
|
||||
LastModified int `json:"lastModified"`
|
||||
|
||||
AppProperty AppProperty `json:"additionalProperties"`
|
||||
Versions []AppConfigVersion `json:"versions"`
|
||||
}
|
||||
|
||||
type LocalAppAppDefine struct {
|
||||
AppProperty model.App `json:"additionalProperties" yaml:"additionalProperties"`
|
||||
}
|
||||
|
||||
type LocalAppParam struct {
|
||||
AppParams LocalAppInstallDefine `json:"additionalProperties" yaml:"additionalProperties"`
|
||||
}
|
||||
|
||||
type LocalAppInstallDefine struct {
|
||||
FormFields interface{} `json:"formFields" yaml:"formFields"`
|
||||
}
|
||||
|
||||
type ExtraProperties struct {
|
||||
Tags []Tag `json:"tags"`
|
||||
}
|
||||
|
||||
type AppProperty struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Tags []string `json:"tags"`
|
||||
Versions []string `json:"versions"`
|
||||
ShortDescZh string `json:"shortDescZh"`
|
||||
ShortDescEn string `json:"shortDescEn"`
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
Required []string `json:"Required"`
|
||||
CrossVersionUpdate bool `json:"crossVersionUpdate"`
|
||||
Limit int `json:"limit"`
|
||||
@@ -54,9 +86,12 @@ type AppDefine struct {
|
||||
Document string `json:"document"`
|
||||
}
|
||||
|
||||
func (define AppDefine) GetRequired() string {
|
||||
by, _ := json.Marshal(define.Required)
|
||||
return string(by)
|
||||
type AppConfigVersion struct {
|
||||
Name string `json:"name"`
|
||||
LastModified int `json:"lastModified"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
DownloadCallBackUrl string `json:"downloadCallBackUrl"`
|
||||
AppForm interface{} `json:"additionalProperties"`
|
||||
}
|
||||
|
||||
type Tag struct {
|
||||
@@ -78,6 +113,8 @@ type AppFormFields struct {
|
||||
Disabled bool `json:"disabled"`
|
||||
Edit bool `json:"edit"`
|
||||
Rule string `json:"rule"`
|
||||
Multiple bool `json:"multiple"`
|
||||
Child interface{} `json:"child"`
|
||||
Values []AppFormValue `json:"values"`
|
||||
}
|
||||
|
||||
|
@@ -12,16 +12,19 @@ type UserLoginInfo struct {
|
||||
}
|
||||
|
||||
type MfaCredential struct {
|
||||
Secret string `json:"secret"`
|
||||
Code string `json:"code"`
|
||||
Secret string `json:"secret"`
|
||||
Code string `json:"code"`
|
||||
Interval string `json:"interval"`
|
||||
}
|
||||
|
||||
type Login struct {
|
||||
Name string `json:"name"`
|
||||
Password string `json:"password"`
|
||||
Captcha string `json:"captcha"`
|
||||
CaptchaID string `json:"captchaID"`
|
||||
AuthMethod string `json:"authMethod"`
|
||||
Name string `json:"name"`
|
||||
Password string `json:"password"`
|
||||
IgnoreCaptcha bool `json:"ignoreCaptcha"`
|
||||
Captcha string `json:"captcha"`
|
||||
CaptchaID string `json:"captchaID"`
|
||||
AuthMethod string `json:"authMethod"`
|
||||
Language string `json:"language"`
|
||||
}
|
||||
|
||||
type MFALogin struct {
|
||||
@@ -30,8 +33,3 @@ type MFALogin struct {
|
||||
Code string `json:"code"`
|
||||
AuthMethod string `json:"authMethod"`
|
||||
}
|
||||
|
||||
type InitUser struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
}
|
||||
|
@@ -8,15 +8,17 @@ type BackupOperate struct {
|
||||
Bucket string `json:"bucket"`
|
||||
AccessKey string `json:"accessKey"`
|
||||
Credential string `json:"credential"`
|
||||
BackupPath string `json:"backupPath"`
|
||||
Vars string `json:"vars" validate:"required"`
|
||||
}
|
||||
|
||||
type BackupInfo struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Type string `json:"type"`
|
||||
Bucket string `json:"bucket"`
|
||||
Vars string `json:"vars"`
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Type string `json:"type"`
|
||||
Bucket string `json:"bucket"`
|
||||
BackupPath string `json:"backupPath"`
|
||||
Vars string `json:"vars"`
|
||||
}
|
||||
|
||||
type BackupSearch struct {
|
||||
@@ -36,6 +38,7 @@ type CommonBackup struct {
|
||||
DetailName string `json:"detailName"`
|
||||
}
|
||||
type CommonRecover struct {
|
||||
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO OneDrive"`
|
||||
Type string `json:"type" validate:"required,oneof=app mysql redis website"`
|
||||
Name string `json:"name"`
|
||||
DetailName string `json:"detailName"`
|
||||
@@ -59,7 +62,7 @@ type BackupRecords struct {
|
||||
}
|
||||
|
||||
type DownloadRecord struct {
|
||||
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL"`
|
||||
Source string `json:"source" validate:"required,oneof=OSS S3 SFTP MINIO LOCAL COS KODO OneDrive"`
|
||||
FileDir string `json:"fileDir" validate:"required"`
|
||||
FileName string `json:"fileName" validate:"required"`
|
||||
}
|
||||
|
@@ -2,7 +2,9 @@ package dto
|
||||
|
||||
type SearchWithPage struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Info string `json:"info"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
}
|
||||
|
||||
type PageInfo struct {
|
||||
@@ -12,7 +14,7 @@ type PageInfo struct {
|
||||
|
||||
type UpdateDescription struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Description string `json:"description"`
|
||||
Description string `json:"description" validate:"max=256"`
|
||||
}
|
||||
|
||||
type OperationWithName struct {
|
||||
@@ -23,6 +25,10 @@ type OperateByID struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type Operate struct {
|
||||
Operation string `json:"operation" validate:"required"`
|
||||
}
|
||||
|
||||
type BatchDeleteReq struct {
|
||||
Ids []uint `json:"ids" validate:"required"`
|
||||
}
|
||||
|
@@ -5,6 +5,8 @@ import "time"
|
||||
type PageContainer struct {
|
||||
PageInfo
|
||||
Name string `json:"name"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
Filters string `json:"filters"`
|
||||
}
|
||||
|
||||
@@ -22,18 +24,29 @@ type ContainerInfo struct {
|
||||
State string `json:"state"`
|
||||
RunTime string `json:"runTime"`
|
||||
|
||||
Ports []string `json:"ports"`
|
||||
|
||||
IsFromApp bool `json:"isFromApp"`
|
||||
IsFromCompose bool `json:"isFromCompose"`
|
||||
}
|
||||
|
||||
type ContainerCreate struct {
|
||||
type ResourceLimit struct {
|
||||
CPU int `json:"cpu"`
|
||||
Memory int `json:"memory"`
|
||||
}
|
||||
|
||||
type ContainerOperate struct {
|
||||
ContainerID string `json:"containerID"`
|
||||
ForcePull bool `json:"forcePull"`
|
||||
Name string `json:"name"`
|
||||
Image string `json:"image"`
|
||||
Network string `json:"network"`
|
||||
PublishAllPorts bool `json:"publishAllPorts"`
|
||||
ExposedPorts []PortHelper `json:"exposedPorts"`
|
||||
Cmd []string `json:"cmd"`
|
||||
NanoCPUs int64 `json:"nanoCPUs"`
|
||||
Memory int64 `json:"memory"`
|
||||
CPUShares int64 `json:"cpuShares"`
|
||||
NanoCPUs float64 `json:"nanoCPUs"`
|
||||
Memory float64 `json:"memory"`
|
||||
AutoRemove bool `json:"autoRemove"`
|
||||
Volumes []VolumeHelper `json:"volumes"`
|
||||
Labels []string `json:"labels"`
|
||||
@@ -41,7 +54,19 @@ type ContainerCreate struct {
|
||||
RestartPolicy string `json:"restartPolicy"`
|
||||
}
|
||||
|
||||
type ContainterStats struct {
|
||||
type ContainerUpgrade struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Image string `json:"image" validate:"required"`
|
||||
ForcePull bool `json:"forcePull"`
|
||||
}
|
||||
|
||||
type ContainerListStats struct {
|
||||
ContainerID string `json:"containerID"`
|
||||
CPUPercent float64 `json:"cpuPercent"`
|
||||
MemoryPercent float64 `json:"memoryPercent"`
|
||||
}
|
||||
|
||||
type ContainerStats struct {
|
||||
CPUPercent float64 `json:"cpuPercent"`
|
||||
Memory float64 `json:"memory"`
|
||||
Cache float64 `json:"cache"`
|
||||
@@ -59,13 +84,10 @@ type VolumeHelper struct {
|
||||
Mode string `json:"mode"`
|
||||
}
|
||||
type PortHelper struct {
|
||||
ContainerPort int `json:"containerPort"`
|
||||
HostPort int `json:"hostPort"`
|
||||
}
|
||||
|
||||
type ContainerLog struct {
|
||||
ContainerID string `json:"containerID" validate:"required"`
|
||||
Mode string `json:"mode" validate:"required"`
|
||||
HostIP string `json:"hostIP"`
|
||||
HostPort string `json:"hostPort"`
|
||||
ContainerPort string `json:"containerPort"`
|
||||
Protocol string `json:"protocol"`
|
||||
}
|
||||
|
||||
type ContainerOperation struct {
|
||||
@@ -74,6 +96,16 @@ type ContainerOperation struct {
|
||||
NewName string `json:"newName"`
|
||||
}
|
||||
|
||||
type ContainerPrune struct {
|
||||
PruneType string `json:"pruneType" validate:"required,oneof=container image volume network"`
|
||||
WithTagAll bool `json:"withTagAll"`
|
||||
}
|
||||
|
||||
type ContainerPruneReport struct {
|
||||
DeletedNumber int `json:"deletedNumber"`
|
||||
SpaceReclaimed int `json:"spaceReclaimed"`
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
@@ -85,7 +117,7 @@ type Network struct {
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Attachable bool `json:"attachable"`
|
||||
}
|
||||
type NetworkCreat struct {
|
||||
type NetworkCreate struct {
|
||||
Name string `json:"name"`
|
||||
Driver string `json:"driver"`
|
||||
Options []string `json:"options"`
|
||||
@@ -102,7 +134,7 @@ type Volume struct {
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
}
|
||||
type VolumeCreat struct {
|
||||
type VolumeCreate struct {
|
||||
Name string `json:"name"`
|
||||
Driver string `json:"driver"`
|
||||
Options []string `json:"options"`
|
||||
@@ -140,6 +172,7 @@ type ComposeOperation struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
Operation string `json:"operation" validate:"required,oneof=start stop down"`
|
||||
WithFile bool `json:"withFile"`
|
||||
}
|
||||
type ComposeUpdate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
|
@@ -6,12 +6,14 @@ type CronjobCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
SpecType string `json:"specType" validate:"required"`
|
||||
Week int `json:"week" validate:"number,max=7,min=1"`
|
||||
Week int `json:"week" validate:"number,max=6,min=0"`
|
||||
Day int `json:"day" validate:"number"`
|
||||
Hour int `json:"hour" validate:"number"`
|
||||
Minute int `json:"minute" validate:"number"`
|
||||
Second int `json:"second" validate:"number"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@@ -26,12 +28,14 @@ type CronjobUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
SpecType string `json:"specType" validate:"required"`
|
||||
Week int `json:"week" validate:"number,max=7,min=1"`
|
||||
Week int `json:"week" validate:"number,max=6,min=0"`
|
||||
Day int `json:"day" validate:"number"`
|
||||
Hour int `json:"hour" validate:"number"`
|
||||
Minute int `json:"minute" validate:"number"`
|
||||
Second int `json:"second" validate:"number"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@@ -52,6 +56,16 @@ type CronjobDownload struct {
|
||||
BackupAccountID uint `json:"backupAccountID" validate:"required"`
|
||||
}
|
||||
|
||||
type CronjobClean struct {
|
||||
CleanData bool `json:"cleanData"`
|
||||
CronjobID uint `json:"cronjobID" validate:"required"`
|
||||
}
|
||||
|
||||
type CronjobBatchDelete struct {
|
||||
CleanData bool `json:"cleanData"`
|
||||
IDs []uint `json:"ids"`
|
||||
}
|
||||
|
||||
type CronjobInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
@@ -61,8 +75,10 @@ type CronjobInfo struct {
|
||||
Day int `json:"day"`
|
||||
Hour int `json:"hour"`
|
||||
Minute int `json:"minute"`
|
||||
Second int `json:"second"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@@ -73,7 +89,7 @@ type CronjobInfo struct {
|
||||
TargetDirID int `json:"targetDirID"`
|
||||
RetainCopies int `json:"retainCopies"`
|
||||
|
||||
LastRecrodTime string `json:"lastRecrodTime"`
|
||||
LastRecordTime string `json:"lastRecordTime"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
|
@@ -2,10 +2,20 @@ package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type MysqlDBSearch struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
From string `json:"from"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
}
|
||||
|
||||
type MysqlDBInfo struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Name string `json:"name"`
|
||||
From string `json:"from"`
|
||||
MysqlName string `json:"mysqlName"`
|
||||
Format string `json:"format"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
@@ -14,8 +24,15 @@ type MysqlDBInfo struct {
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type MysqlOption struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
From string `json:"from"`
|
||||
}
|
||||
|
||||
type MysqlDBCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
From string `json:"from" validate:"required"`
|
||||
Format string `json:"format" validate:"required,oneof=utf8mb4 utf8 gbk big5"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
@@ -100,6 +117,7 @@ type MysqlConfUpdateByFile struct {
|
||||
|
||||
type ChangeDBInfo struct {
|
||||
ID uint `json:"id"`
|
||||
From string `json:"from"`
|
||||
Value string `json:"value" validate:"required"`
|
||||
}
|
||||
|
||||
|
@@ -5,16 +5,24 @@ type DaemonJsonUpdateByFile struct {
|
||||
}
|
||||
|
||||
type DaemonJsonConf struct {
|
||||
IsSwarm bool `json:"isSwarm"`
|
||||
Status string `json:"status"`
|
||||
Version string `json:"version"`
|
||||
Mirrors []string `json:"registryMirrors"`
|
||||
Registries []string `json:"insecureRegistries"`
|
||||
LiveRestore bool `json:"liveRestore"`
|
||||
IPTables bool `json:"iptables"`
|
||||
CgroupDriver string `json:"cgroupDriver"`
|
||||
|
||||
LogMaxSize string `json:"logMaxSize"`
|
||||
LogMaxFile string `json:"logMaxFile"`
|
||||
}
|
||||
|
||||
type LogOption struct {
|
||||
LogMaxSize string `json:"logMaxSize"`
|
||||
LogMaxFile string `json:"logMaxFile"`
|
||||
}
|
||||
|
||||
type DockerOperation struct {
|
||||
StopSocket bool `json:"stopSocket"`
|
||||
StopService bool `json:"stopService"`
|
||||
Operation string `json:"operation" validate:"required,oneof=start restart stop"`
|
||||
Operation string `json:"operation" validate:"required,oneof=start restart stop"`
|
||||
}
|
||||
|
47
backend/app/dto/firewall.go
Normal file
47
backend/app/dto/firewall.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package dto
|
||||
|
||||
type FirewallBaseInfo struct {
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
Version string `json:"version"`
|
||||
PingStatus string `json:"pingStatus"`
|
||||
}
|
||||
|
||||
type RuleSearch struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
}
|
||||
|
||||
type FirewallOperation struct {
|
||||
Operation string `json:"operation" validate:"required,oneof=start stop disablePing enablePing"`
|
||||
}
|
||||
|
||||
type PortRuleOperate struct {
|
||||
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
||||
Address string `json:"address"`
|
||||
Port string `json:"port" validate:"required"`
|
||||
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
|
||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||
}
|
||||
|
||||
type AddrRuleOperate struct {
|
||||
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
||||
Address string `json:"address" validate:"required"`
|
||||
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||
}
|
||||
|
||||
type PortRuleUpdate struct {
|
||||
OldRule PortRuleOperate `json:"oldRule"`
|
||||
NewRule PortRuleOperate `json:"newRule"`
|
||||
}
|
||||
|
||||
type AddrRuleUpdate struct {
|
||||
OldRule AddrRuleOperate `json:"oldRule"`
|
||||
NewRule AddrRuleOperate `json:"newRule"`
|
||||
}
|
||||
|
||||
type BatchRuleOperate struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
Rules []PortRuleOperate `json:"rules"`
|
||||
}
|
@@ -5,15 +5,17 @@ import (
|
||||
)
|
||||
|
||||
type HostOperate struct {
|
||||
ID uint `json:"id"`
|
||||
GroupID uint `json:"groupID"`
|
||||
Name string `json:"name"`
|
||||
Addr string `json:"addr" validate:"required"`
|
||||
Port uint `json:"port" validate:"required,number,max=65535,min=1"`
|
||||
User string `json:"user" validate:"required"`
|
||||
AuthMode string `json:"authMode" validate:"oneof=password key"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Password string `json:"password"`
|
||||
ID uint `json:"id"`
|
||||
GroupID uint `json:"groupID"`
|
||||
Name string `json:"name"`
|
||||
Addr string `json:"addr" validate:"required"`
|
||||
Port uint `json:"port" validate:"required,number,max=65535,min=1"`
|
||||
User string `json:"user" validate:"required"`
|
||||
AuthMode string `json:"authMode" validate:"oneof=password key"`
|
||||
Password string `json:"password"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
PassPhrase string `json:"passPhrase"`
|
||||
RememberPassword bool `json:"rememberPassword"`
|
||||
|
||||
Description string `json:"description"`
|
||||
}
|
||||
@@ -23,8 +25,9 @@ type HostConnTest struct {
|
||||
Port uint `json:"port" validate:"required,number,max=65535,min=1"`
|
||||
User string `json:"user" validate:"required"`
|
||||
AuthMode string `json:"authMode" validate:"oneof=password key"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Password string `json:"password"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
PassPhrase string `json:"passPhrase"`
|
||||
}
|
||||
|
||||
type SearchHostWithPage struct {
|
||||
@@ -43,15 +46,19 @@ type ChangeHostGroup struct {
|
||||
}
|
||||
|
||||
type HostInfo struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
GroupID uint `json:"groupID"`
|
||||
GroupBelong string `json:"groupBelong"`
|
||||
Name string `json:"name"`
|
||||
Addr string `json:"addr"`
|
||||
Port uint `json:"port"`
|
||||
User string `json:"user"`
|
||||
AuthMode string `json:"authMode"`
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
GroupID uint `json:"groupID"`
|
||||
GroupBelong string `json:"groupBelong"`
|
||||
Name string `json:"name"`
|
||||
Addr string `json:"addr"`
|
||||
Port uint `json:"port"`
|
||||
User string `json:"user"`
|
||||
AuthMode string `json:"authMode"`
|
||||
Password string `json:"password"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
PassPhrase string `json:"passPhrase"`
|
||||
RememberPassword bool `json:"rememberPassword"`
|
||||
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
@@ -10,35 +10,35 @@ type ImageInfo struct {
|
||||
}
|
||||
|
||||
type ImageLoad struct {
|
||||
Path string `josn:"path" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
}
|
||||
|
||||
type ImageBuild struct {
|
||||
From string `josn:"from" validate:"required"`
|
||||
From string `json:"from" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Dockerfile string `josn:"dockerfile" validate:"required"`
|
||||
Tags []string `josn:"tags"`
|
||||
Dockerfile string `json:"dockerfile" validate:"required"`
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
type ImagePull struct {
|
||||
RepoID uint `josn:"repoID"`
|
||||
ImageName string `josn:"imageName" validate:"required"`
|
||||
RepoID uint `json:"repoID"`
|
||||
ImageName string `json:"imageName" validate:"required"`
|
||||
}
|
||||
|
||||
type ImageTag struct {
|
||||
RepoID uint `josn:"repoID"`
|
||||
RepoID uint `json:"repoID"`
|
||||
SourceID string `json:"sourceID" validate:"required"`
|
||||
TargetName string `josn:"targetName" validate:"required"`
|
||||
TargetName string `json:"targetName" validate:"required"`
|
||||
}
|
||||
|
||||
type ImagePush struct {
|
||||
RepoID uint `josn:"repoID" validate:"required"`
|
||||
RepoID uint `json:"repoID" validate:"required"`
|
||||
TagName string `json:"tagName" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type ImageSave struct {
|
||||
TagName string `json:"tagName" validate:"required"`
|
||||
Path string `josn:"path" validate:"required"`
|
||||
Path string `json:"path" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
@@ -6,8 +6,8 @@ type ImageRepoCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
Protocol string `json:"protocol"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Username string `json:"username" validate:"max=256"`
|
||||
Password string `json:"password" validate:"max=256"`
|
||||
Auth bool `json:"auth"`
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ type ImageRepoUpdate struct {
|
||||
ID uint `json:"id"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
Protocol string `json:"protocol"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Username string `json:"username" validate:"max=256"`
|
||||
Password string `json:"password" validate:"max=256"`
|
||||
Auth bool `json:"auth"`
|
||||
}
|
||||
|
||||
|
@@ -28,13 +28,20 @@ type NginxParam struct {
|
||||
Params []string
|
||||
}
|
||||
|
||||
type NginxAuth struct {
|
||||
Username string `json:"username"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type NginxKey string
|
||||
|
||||
const (
|
||||
Index NginxKey = "index"
|
||||
LimitConn NginxKey = "limit-conn"
|
||||
SSL NginxKey = "ssl"
|
||||
HttpPer NginxKey = "http-per"
|
||||
Index NginxKey = "index"
|
||||
LimitConn NginxKey = "limit-conn"
|
||||
SSL NginxKey = "ssl"
|
||||
CACHE NginxKey = "cache"
|
||||
HttpPer NginxKey = "http-per"
|
||||
ProxyCache NginxKey = "proxy-cache"
|
||||
)
|
||||
|
||||
var ScopeKeyMap = map[NginxKey][]string{
|
||||
@@ -46,5 +53,7 @@ var ScopeKeyMap = map[NginxKey][]string{
|
||||
|
||||
var StaticFileKeyMap = map[NginxKey]struct {
|
||||
}{
|
||||
SSL: {},
|
||||
SSL: {},
|
||||
CACHE: {},
|
||||
ProxyCache: {},
|
||||
}
|
||||
|
52
backend/app/dto/remote_db.go
Normal file
52
backend/app/dto/remote_db.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type RemoteDBSearch struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Type string `json:"type"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
}
|
||||
|
||||
type RemoteDBInfo struct {
|
||||
ID uint `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Name string `json:"name" validate:"max=256"`
|
||||
From string `json:"from"`
|
||||
Version string `json:"version"`
|
||||
Address string `json:"address"`
|
||||
Port uint `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type RemoteDBOption struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
||||
type RemoteDBCreate struct {
|
||||
Name string `json:"name" validate:"required,max=256"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql"`
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Version string `json:"version" validate:"required"`
|
||||
Address string `json:"address"`
|
||||
Port uint `json:"port"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
type RemoteDBUpdate struct {
|
||||
ID uint `json:"id"`
|
||||
Version string `json:"version" validate:"required"`
|
||||
Address string `json:"address"`
|
||||
Port uint `json:"port"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Description string `json:"description"`
|
||||
}
|
@@ -18,6 +18,18 @@ type AppInstallCreate struct {
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Services map[string]string `json:"services"`
|
||||
AppContainerConfig
|
||||
}
|
||||
|
||||
type AppContainerConfig struct {
|
||||
Advanced bool `json:"advanced"`
|
||||
CpuQuota float64 `json:"cpuQuota"`
|
||||
MemoryLimit float64 `json:"memoryLimit"`
|
||||
MemoryUnit string `json:"memoryUnit"`
|
||||
ContainerName string `json:"containerName"`
|
||||
AllowPort bool `json:"allowPort"`
|
||||
EditCompose bool `json:"editCompose"`
|
||||
DockerCompose string `json:"dockerCompose"`
|
||||
}
|
||||
|
||||
type AppInstalledSearch struct {
|
||||
@@ -46,11 +58,18 @@ type AppInstalledOperate struct {
|
||||
ForceDelete bool `json:"forceDelete"`
|
||||
DeleteBackup bool `json:"deleteBackup"`
|
||||
DeleteDB bool `json:"deleteDB"`
|
||||
Backup bool `json:"backup"`
|
||||
}
|
||||
|
||||
type AppInstalledUpdate struct {
|
||||
InstallId uint `json:"installId" validate:"required"`
|
||||
Params map[string]interface{} `json:"params" validate:"required"`
|
||||
AppContainerConfig
|
||||
}
|
||||
|
||||
type AppInstalledIgnoreUpgrade struct {
|
||||
DetailID uint `json:"detailID" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required,oneof=cancel ignore"`
|
||||
}
|
||||
|
||||
type PortUpdate struct {
|
||||
|
@@ -22,6 +22,7 @@ type FileCreate struct {
|
||||
IsLink bool `json:"isLink"`
|
||||
IsSymlink bool `json:"isSymlink"`
|
||||
LinkPath string `json:"linkPath"`
|
||||
Sub bool `json:"sub"`
|
||||
}
|
||||
|
||||
type FileDelete struct {
|
||||
@@ -81,6 +82,11 @@ type FileDownload struct {
|
||||
Compress bool `json:"compress" validate:"required"`
|
||||
}
|
||||
|
||||
type FileChunkDownload struct {
|
||||
Path string `json:"path" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type DirSizeReq struct {
|
||||
Path string `json:"path" validate:"required"`
|
||||
}
|
||||
@@ -88,3 +94,10 @@ type DirSizeReq struct {
|
||||
type FileProcessReq struct {
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
type FileRoleUpdate struct {
|
||||
Path string `json:"path" validate:"required"`
|
||||
User string `json:"user" validate:"required"`
|
||||
Group string `json:"group" validate:"required"`
|
||||
Sub bool `json:"sub" validate:"required"`
|
||||
}
|
||||
|
41
backend/app/dto/request/host_tool.go
Normal file
41
backend/app/dto/request/host_tool.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package request
|
||||
|
||||
type HostToolReq struct {
|
||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||
Operate string `json:"operate" validate:"oneof=status restart start stop"`
|
||||
}
|
||||
|
||||
type HostToolCreate struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
SupervisorConfig
|
||||
}
|
||||
|
||||
type SupervisorConfig struct {
|
||||
ConfigPath string `json:"configPath"`
|
||||
ServiceName string `json:"serviceName"`
|
||||
}
|
||||
|
||||
type HostToolLogReq struct {
|
||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||
}
|
||||
|
||||
type HostToolConfig struct {
|
||||
Type string `json:"type" validate:"required,oneof=supervisord"`
|
||||
Operate string `json:"operate" validate:"oneof=get set"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type SupervisorProcessConfig struct {
|
||||
Name string `json:"name"`
|
||||
Operate string `json:"operate"`
|
||||
Command string `json:"command"`
|
||||
User string `json:"user"`
|
||||
Dir string `json:"dir"`
|
||||
Numprocs string `json:"numprocs"`
|
||||
}
|
||||
type SupervisorProcessFileReq struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required,oneof=get clear update" `
|
||||
Content string `json:"content"`
|
||||
File string `json:"file" validate:"required,oneof=out.log err.log config"`
|
||||
}
|
@@ -3,9 +3,8 @@ package request
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
|
||||
type NginxConfigFileUpdate struct {
|
||||
Content string `json:"content" validate:"required"`
|
||||
FilePath string `json:"filePath" validate:"required"`
|
||||
Backup bool `json:"backup" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Backup bool `json:"backup" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxScopeReq struct {
|
||||
@@ -19,3 +18,70 @@ type NginxConfigUpdate struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Params interface{} `json:"params"`
|
||||
}
|
||||
|
||||
type NginxRewriteReq struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxRewriteUpdate struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxProxyUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxAuthUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type NginxAuthReq struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxCommonReq struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
}
|
||||
|
||||
type NginxAntiLeechUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Extends string `json:"extends" validate:"required"`
|
||||
Return string `json:"return" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
ServerNames []string `json:"serverNames"`
|
||||
Cache bool `json:"cache"`
|
||||
CacheTime int `json:"cacheTime"`
|
||||
CacheUint string `json:"cacheUint"`
|
||||
NoneRef bool `json:"noneRef"`
|
||||
LogEnable bool `json:"logEnable"`
|
||||
Blocked bool `json:"blocked"`
|
||||
}
|
||||
|
||||
type NginxRedirectReq struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Domains []string `json:"domains"`
|
||||
KeepPath bool `json:"keepPath" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
Redirect string `json:"redirect" validate:"required"`
|
||||
Path string `json:"path"`
|
||||
Target string `json:"target" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
RedirectRoot bool `json:"redirectRoot"`
|
||||
}
|
||||
|
||||
type NginxRedirectUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
}
|
||||
|
5
backend/app/dto/request/process.go
Normal file
5
backend/app/dto/request/process.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package request
|
||||
|
||||
type ProcessReq struct {
|
||||
PID int32 `json:"PID" validate:"required"`
|
||||
}
|
32
backend/app/dto/request/runtime.go
Normal file
32
backend/app/dto/request/runtime.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package request
|
||||
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
|
||||
type RuntimeSearch struct {
|
||||
dto.PageInfo
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type RuntimeCreate struct {
|
||||
AppDetailID uint `json:"appDetailId"`
|
||||
Name string `json:"name"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Resource string `json:"resource"`
|
||||
Image string `json:"image"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type RuntimeDelete struct {
|
||||
ID uint `json:"id"`
|
||||
}
|
||||
|
||||
type RuntimeUpdate struct {
|
||||
Name string `json:"name"`
|
||||
ID uint `json:"id"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Image string `json:"image"`
|
||||
Version string `json:"version"`
|
||||
}
|
@@ -7,6 +7,8 @@ import (
|
||||
type WebsiteSearch struct {
|
||||
dto.PageInfo
|
||||
Name string `json:"name"`
|
||||
OrderBy string `json:"orderBy"`
|
||||
Order string `json:"order"`
|
||||
WebsiteGroupID uint `json:"websiteGroupId"`
|
||||
}
|
||||
|
||||
@@ -18,17 +20,28 @@ type WebsiteCreate struct {
|
||||
OtherDomains string `json:"otherDomains"`
|
||||
Proxy string `json:"proxy"`
|
||||
WebsiteGroupID uint `json:"webSiteGroupID" validate:"required"`
|
||||
IPV6 bool `json:"IPV6"`
|
||||
|
||||
AppType string `json:"appType" validate:"oneof=new installed"`
|
||||
AppInstall NewAppInstall `json:"appInstall"`
|
||||
AppID uint `json:"appID"`
|
||||
AppInstallID uint `json:"appInstallID"`
|
||||
|
||||
RuntimeID uint `json:"runtimeID"`
|
||||
RuntimeConfig
|
||||
}
|
||||
|
||||
type RuntimeConfig struct {
|
||||
ProxyType string `json:"proxyType"`
|
||||
Port int `json:"port"`
|
||||
}
|
||||
|
||||
type NewAppInstall struct {
|
||||
Name string `json:"name"`
|
||||
AppDetailId uint `json:"appDetailID"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
|
||||
AppContainerConfig
|
||||
}
|
||||
|
||||
type WebsiteInstallCheckReq struct {
|
||||
@@ -41,6 +54,7 @@ type WebsiteUpdate struct {
|
||||
Remark string `json:"remark"`
|
||||
WebsiteGroupID uint `json:"webSiteGroupID" validate:"required"`
|
||||
ExpireDate string `json:"expireDate"`
|
||||
IPV6 bool `json:"IPV6"`
|
||||
}
|
||||
|
||||
type WebsiteDelete struct {
|
||||
@@ -61,6 +75,12 @@ type WebsiteWafReq struct {
|
||||
Rule string `json:"rule" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteRedirectUpdate struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Key string `json:"key" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteWafUpdate struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Key string `json:"key" validate:"required"`
|
||||
@@ -101,15 +121,18 @@ type WebsiteDomainDelete struct {
|
||||
}
|
||||
|
||||
type WebsiteHTTPSOp struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
HttpConfig string `json:"HttpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||
SSLProtocol []string `json:"SSLProtocol"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
WebsiteSSLID uint `json:"websiteSSLId"`
|
||||
Type string `json:"type" validate:"oneof=existed auto manual"`
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
PrivateKeyPath string `json:"privateKeyPath"`
|
||||
CertificatePath string `json:"certificatePath"`
|
||||
ImportType string `json:"importType"`
|
||||
HttpConfig string `json:"httpConfig" validate:"oneof=HTTPSOnly HTTPAlso HTTPToHTTPS"`
|
||||
SSLProtocol []string `json:"SSLProtocol"`
|
||||
Algorithm string `json:"algorithm"`
|
||||
}
|
||||
|
||||
type WebsiteNginxUpdate struct {
|
||||
@@ -126,3 +149,65 @@ type WebsiteLogReq struct {
|
||||
type WebsiteDefaultUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsitePHPConfigUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Params map[string]string `json:"params"`
|
||||
Scope string `json:"scope" validate:"required"`
|
||||
DisableFunctions []string `json:"disableFunctions"`
|
||||
UploadMaxSize string `json:"uploadMaxSize"`
|
||||
}
|
||||
|
||||
type WebsitePHPFileUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsitePHPVersionReq struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
RuntimeID uint `json:"runtimeID" validate:"required"`
|
||||
RetainConfig bool `json:"retainConfig" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteUpdateDir struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
SiteDir string `json:"siteDir" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteUpdateDirPermission struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
User string `json:"user" validate:"required"`
|
||||
Group string `json:"group" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteProxyConfig struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Operate string `json:"operate" validate:"required"`
|
||||
Enable bool `json:"enable" validate:"required"`
|
||||
Cache bool `json:"cache" validate:"required"`
|
||||
CacheTime int `json:"cacheTime" validate:"required"`
|
||||
CacheUnit string `json:"cacheUnit" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Modifier string `json:"modifier" validate:"required"`
|
||||
Match string `json:"match" validate:"required"`
|
||||
ProxyPass string `json:"proxyPass" validate:"required"`
|
||||
ProxyHost string `json:"proxyHost" validate:"required"`
|
||||
Content string `json:"content"`
|
||||
FilePath string `json:"filePath"`
|
||||
Replaces map[string]string `json:"replaces"`
|
||||
}
|
||||
|
||||
type WebsiteProxyReq struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteRedirectReq struct {
|
||||
WebsiteID uint `json:"websiteId" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteWafFileUpdate struct {
|
||||
WebsiteID uint `json:"websiteID" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Type string `json:"type" validate:"required,oneof=cc ip_white ip_block url_white url_block cookie_block args_check post_check ua_check file_ext_block"`
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ import "github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
|
||||
type WebsiteSSLSearch struct {
|
||||
dto.PageInfo
|
||||
AcmeAccountID string `json:"acmeAccountID"`
|
||||
}
|
||||
|
||||
type WebsiteSSLCreate struct {
|
||||
|
@@ -1,8 +1,10 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
)
|
||||
|
||||
type AppRes struct {
|
||||
@@ -11,15 +13,15 @@ type AppRes struct {
|
||||
}
|
||||
|
||||
type AppUpdateRes struct {
|
||||
Version string `json:"version"`
|
||||
CanUpdate bool `json:"canUpdate"`
|
||||
DownloadPath string `json:"downloadPath"`
|
||||
CanUpdate bool `json:"canUpdate"`
|
||||
AppStoreLastModified int `json:"appStoreLastModified"`
|
||||
}
|
||||
|
||||
type AppDTO struct {
|
||||
model.App
|
||||
Versions []string `json:"versions"`
|
||||
Tags []model.Tag `json:"tags"`
|
||||
Installed bool `json:"installed"`
|
||||
Versions []string `json:"versions"`
|
||||
Tags []model.Tag `json:"tags"`
|
||||
}
|
||||
|
||||
type TagDTO struct {
|
||||
@@ -43,6 +45,14 @@ type AppDetailDTO struct {
|
||||
model.AppDetail
|
||||
Enable bool `json:"enable"`
|
||||
Params interface{} `json:"params"`
|
||||
Image string `json:"image"`
|
||||
}
|
||||
|
||||
type IgnoredApp struct {
|
||||
Icon string `json:"icon"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
DetailID uint `json:"detailID"`
|
||||
}
|
||||
|
||||
type AppInstalledDTO struct {
|
||||
@@ -52,6 +62,13 @@ type AppInstalledDTO struct {
|
||||
AppName string `json:"appName"`
|
||||
Icon string `json:"icon"`
|
||||
CanUpdate bool `json:"canUpdate"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type DatabaseConn struct {
|
||||
Password string `json:"password"`
|
||||
ServiceName string `json:"serviceName"`
|
||||
Port int64 `json:"port"`
|
||||
}
|
||||
|
||||
type AppService struct {
|
||||
@@ -70,4 +87,11 @@ type AppParam struct {
|
||||
Type string `json:"type"`
|
||||
Values interface{} `json:"values"`
|
||||
ShowValue string `json:"showValue"`
|
||||
Required bool `json:"required"`
|
||||
Multiple bool `json:"multiple"`
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
Params []AppParam `json:"params"`
|
||||
request.AppContainerConfig
|
||||
}
|
||||
|
41
backend/app/dto/response/host_tool.go
Normal file
41
backend/app/dto/response/host_tool.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package response
|
||||
|
||||
type HostToolRes struct {
|
||||
Type string `json:"type"`
|
||||
Config interface{} `json:"config"`
|
||||
}
|
||||
|
||||
type Supervisor struct {
|
||||
ConfigPath string `json:"configPath"`
|
||||
IncludeDir string `json:"includeDir"`
|
||||
LogPath string `json:"logPath"`
|
||||
IsExist bool `json:"isExist"`
|
||||
Init bool `json:"init"`
|
||||
Msg string `json:"msg"`
|
||||
Version string `json:"version"`
|
||||
Status string `json:"status"`
|
||||
CtlExist bool `json:"ctlExist"`
|
||||
ServiceName string `json:"serviceName"`
|
||||
}
|
||||
|
||||
type HostToolConfig struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type SupervisorProcessConfig struct {
|
||||
Name string `json:"name"`
|
||||
Command string `json:"command"`
|
||||
User string `json:"user"`
|
||||
Dir string `json:"dir"`
|
||||
Numprocs string `json:"numprocs"`
|
||||
Msg string `json:"msg"`
|
||||
Status []ProcessStatus `json:"status"`
|
||||
}
|
||||
|
||||
type ProcessStatus struct {
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
PID string `json:"PID"`
|
||||
Uptime string `json:"uptime"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
package response
|
||||
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
|
||||
type NginxStatus struct {
|
||||
Active string `json:"active"`
|
||||
Accepts string `json:"accepts"`
|
||||
@@ -14,3 +16,40 @@ type NginxParam struct {
|
||||
Name string `json:"name"`
|
||||
Params []string `json:"params"`
|
||||
}
|
||||
|
||||
type NginxAuthRes struct {
|
||||
Enable bool `json:"enable"`
|
||||
Items []dto.NginxAuth `json:"items"`
|
||||
}
|
||||
|
||||
type NginxAntiLeechRes struct {
|
||||
Enable bool `json:"enable"`
|
||||
Extends string `json:"extends"`
|
||||
Return string `json:"return"`
|
||||
ServerNames []string `json:"serverNames"`
|
||||
Cache bool `json:"cache"`
|
||||
CacheTime int `json:"cacheTime"`
|
||||
CacheUint string `json:"cacheUint"`
|
||||
NoneRef bool `json:"noneRef"`
|
||||
LogEnable bool `json:"logEnable"`
|
||||
Blocked bool `json:"blocked"`
|
||||
}
|
||||
|
||||
type NginxRedirectConfig struct {
|
||||
WebsiteID uint `json:"websiteID"`
|
||||
Name string `json:"name"`
|
||||
Domains []string `json:"domains"`
|
||||
KeepPath bool `json:"keepPath"`
|
||||
Enable bool `json:"enable"`
|
||||
Type string `json:"type"`
|
||||
Redirect string `json:"redirect"`
|
||||
Path string `json:"path"`
|
||||
Target string `json:"target"`
|
||||
FilePath string `json:"filePath"`
|
||||
Content string `json:"content"`
|
||||
RedirectRoot bool `json:"redirectRoot"`
|
||||
}
|
||||
|
||||
type NginxFile struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
9
backend/app/dto/response/runtime.go
Normal file
9
backend/app/dto/response/runtime.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package response
|
||||
|
||||
import "github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
|
||||
type RuntimeRes struct {
|
||||
model.Runtime
|
||||
AppParams []AppParam `json:"appParams"`
|
||||
AppID uint `json:"appId"`
|
||||
}
|
@@ -10,6 +10,7 @@ type WebsiteDTO struct {
|
||||
AccessLogPath string `json:"accessLogPath"`
|
||||
SitePath string `json:"sitePath"`
|
||||
AppName string `json:"appName"`
|
||||
RuntimeName string `json:"runtimeName"`
|
||||
}
|
||||
|
||||
type WebsitePreInstallCheck struct {
|
||||
@@ -25,9 +26,8 @@ type WebsiteNginxConfig struct {
|
||||
}
|
||||
|
||||
type WebsiteWafConfig struct {
|
||||
Enable bool `json:"enable"`
|
||||
FilePath string `json:"filePath"`
|
||||
Content string `json:"content"`
|
||||
Enable bool `json:"enable"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type WebsiteHTTPS struct {
|
||||
@@ -42,3 +42,13 @@ type WebsiteLog struct {
|
||||
Enable bool `json:"enable"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type PHPConfig struct {
|
||||
Params map[string]string `json:"params"`
|
||||
DisableFunctions []string `json:"disableFunctions"`
|
||||
UploadMaxSize string `json:"uploadMaxSize"`
|
||||
}
|
||||
|
||||
type NginxRewriteRes struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
@@ -5,10 +5,13 @@ import "time"
|
||||
type SettingInfo struct {
|
||||
UserName string `json:"userName"`
|
||||
Email string `json:"email"`
|
||||
SystemIP string `json:"systemIP"`
|
||||
SystemVersion string `json:"systemVersion"`
|
||||
|
||||
SessionTimeout string `json:"sessionTimeout"`
|
||||
LocalTime string `json:"localTime"`
|
||||
TimeZone string `json:"timeZone"`
|
||||
NtpSite string `json:"ntpSite"`
|
||||
|
||||
Port string `json:"port"`
|
||||
PanelName string `json:"panelName"`
|
||||
@@ -16,14 +19,20 @@ type SettingInfo struct {
|
||||
Language string `json:"language"`
|
||||
|
||||
ServerPort string `json:"serverPort"`
|
||||
SSL string `json:"ssl"`
|
||||
SSLType string `json:"sslType"`
|
||||
BindDomain string `json:"bindDomain"`
|
||||
AllowIPs string `json:"allowIPs"`
|
||||
SecurityEntrance string `json:"securityEntrance"`
|
||||
ExpirationDays string `json:"expirationDays"`
|
||||
ExpirationTime string `json:"expirationTime"`
|
||||
ComplexityVerification string `json:"complexityVerification"`
|
||||
MFAStatus string `json:"mfaStatus"`
|
||||
MFASecret string `json:"mfaSecret"`
|
||||
MFAInterval string `json:"mfaInterval"`
|
||||
|
||||
MonitorStatus string `json:"monitorStatus"`
|
||||
MonitorInterval string `json:"monitorInterval"`
|
||||
MonitorStoreDays string `json:"monitorStoreDays"`
|
||||
|
||||
MessageType string `json:"messageType"`
|
||||
@@ -31,7 +40,8 @@ type SettingInfo struct {
|
||||
WeChatVars string `json:"weChatVars"`
|
||||
DingVars string `json:"dingVars"`
|
||||
|
||||
AppStoreVersion string `json:"appStoreVersion"`
|
||||
AppStoreVersion string `json:"appStoreVersion"`
|
||||
AppStoreLastModified string `json:"appStoreLastModified"`
|
||||
}
|
||||
|
||||
type SettingUpdate struct {
|
||||
@@ -39,6 +49,23 @@ type SettingUpdate struct {
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type SSLUpdate struct {
|
||||
SSLType string `json:"sslType"`
|
||||
Domain string `json:"domain"`
|
||||
SSL string `json:"ssl" validate:"required,oneof=enable disable"`
|
||||
Cert string `json:"cert"`
|
||||
Key string `json:"key"`
|
||||
SSLID uint `json:"sslID"`
|
||||
}
|
||||
type SSLInfo struct {
|
||||
Domain string `json:"domain"`
|
||||
Timeout string `json:"timeout"`
|
||||
RootPath string `json:"rootPath"`
|
||||
Cert string `json:"cert"`
|
||||
Key string `json:"key"`
|
||||
SSLID uint `json:"sslID"`
|
||||
}
|
||||
|
||||
type PasswordUpdate struct {
|
||||
OldPassword string `json:"oldPassword" validate:"required"`
|
||||
NewPassword string `json:"newPassword" validate:"required"`
|
||||
@@ -49,8 +76,8 @@ type PortUpdate struct {
|
||||
}
|
||||
|
||||
type SnapshotCreate struct {
|
||||
From string `json:"from" validate:"required,oneof=OSS S3 SFTP MINIO"`
|
||||
Description string `json:"description"`
|
||||
From string `json:"from" validate:"required,oneof=OSS S3 SFTP MINIO COS KODO OneDrive"`
|
||||
Description string `json:"description" validate:"max=256"`
|
||||
}
|
||||
type SnapshotRecover struct {
|
||||
IsNew bool `json:"isNew"`
|
||||
@@ -60,12 +87,12 @@ type SnapshotRecover struct {
|
||||
type SnapshotImport struct {
|
||||
From string `json:"from"`
|
||||
Names []string `json:"names"`
|
||||
Description string `json:"description"`
|
||||
Description string `json:"description" validate:"max=256"`
|
||||
}
|
||||
type SnapshotInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Description string `json:"description" validate:"max=256"`
|
||||
From string `json:"from"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
@@ -87,6 +114,10 @@ type UpgradeInfo struct {
|
||||
ReleaseNote string `json:"releaseNote"`
|
||||
}
|
||||
|
||||
type SyncTime struct {
|
||||
NtpSite string `json:"ntpSite"`
|
||||
}
|
||||
|
||||
type Upgrade struct {
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
49
backend/app/dto/ssh.go
Normal file
49
backend/app/dto/ssh.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
type SSHInfo struct {
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
Port string `json:"port"`
|
||||
ListenAddress string `json:"listenAddress"`
|
||||
PasswordAuthentication string `json:"passwordAuthentication"`
|
||||
PubkeyAuthentication string `json:"pubkeyAuthentication"`
|
||||
PermitRootLogin string `json:"permitRootLogin"`
|
||||
UseDNS string `json:"useDNS"`
|
||||
}
|
||||
|
||||
type GenerateSSH struct {
|
||||
EncryptionMode string `json:"encryptionMode" validate:"required,oneof=rsa ed25519 ecdsa dsa"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type GenerateLoad struct {
|
||||
EncryptionMode string `json:"encryptionMode" validate:"required,oneof=rsa ed25519 ecdsa dsa"`
|
||||
}
|
||||
|
||||
type SSHConf struct {
|
||||
File string `json:"file"`
|
||||
}
|
||||
type SearchSSHLog struct {
|
||||
PageInfo
|
||||
Info string `json:"info"`
|
||||
Status string `json:"Status" validate:"required,oneof=Success Failed All"`
|
||||
}
|
||||
type SSHLog struct {
|
||||
Logs []SSHHistory `json:"logs"`
|
||||
TotalCount int `json:"totalCount"`
|
||||
SuccessfulCount int `json:"successfulCount"`
|
||||
FailedCount int `json:"failedCount"`
|
||||
}
|
||||
type SSHHistory struct {
|
||||
Date time.Time `json:"date"`
|
||||
DateStr string `json:"dateStr"`
|
||||
Area string `json:"area"`
|
||||
User string `json:"user"`
|
||||
AuthMode string `json:"authMode"`
|
||||
Address string `json:"address"`
|
||||
Port string `json:"port"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
}
|
@@ -2,21 +2,25 @@ package model
|
||||
|
||||
type App struct {
|
||||
BaseModel
|
||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||
Key string `json:"key" gorm:"type:varchar(64);not null;uniqueIndex"`
|
||||
ShortDescZh string `json:"shortDescZh" gorm:"type:longtext;"`
|
||||
ShortDescEn string `json:"shortDescEn" gorm:"type:longtext;"`
|
||||
Icon string `json:"icon" gorm:"type:longtext;"`
|
||||
Type string `json:"type" gorm:"type:varchar(64);not null"`
|
||||
Status string `json:"status" gorm:"type:varchar(64);not null"`
|
||||
Required string `json:"required" gorm:"type:varchar(64);not null"`
|
||||
CrossVersionUpdate bool `json:"crossVersionUpdate"`
|
||||
Limit int `json:"limit" gorm:"type:Integer;not null"`
|
||||
Website string `json:"website" gorm:"type:varchar(64);not null"`
|
||||
Github string `json:"github" gorm:"type:varchar(64);not null"`
|
||||
Document string `json:"document" gorm:"type:varchar(64);not null"`
|
||||
Recommend int `json:"recommend" gorm:"type:Integer;not null"`
|
||||
Details []AppDetail `json:"-" gorm:"-:migration"`
|
||||
TagsKey []string `json:"-" gorm:"-"`
|
||||
AppTags []AppTag `json:"-" gorm:"-:migration"`
|
||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||
Key string `json:"key" gorm:"type:varchar(64);not null;"`
|
||||
ShortDescZh string `json:"shortDescZh" yaml:"shortDescZh" gorm:"type:longtext;"`
|
||||
ShortDescEn string `json:"shortDescEn" yaml:"shortDescEn" gorm:"type:longtext;"`
|
||||
Icon string `json:"icon" gorm:"type:longtext;"`
|
||||
Type string `json:"type" gorm:"type:varchar(64);not null"`
|
||||
Status string `json:"status" gorm:"type:varchar(64);not null"`
|
||||
Required string `json:"required" gorm:"type:varchar(64);"`
|
||||
CrossVersionUpdate bool `json:"crossVersionUpdate"`
|
||||
Limit int `json:"limit" gorm:"type:Integer;not null"`
|
||||
Website string `json:"website" gorm:"type:varchar(64);not null"`
|
||||
Github string `json:"github" gorm:"type:varchar(64);not null"`
|
||||
Document string `json:"document" gorm:"type:varchar(64);not null"`
|
||||
Recommend int `json:"recommend" gorm:"type:Integer;not null"`
|
||||
Resource string `json:"resource" gorm:"type:varchar;not null;default:remote"`
|
||||
ReadMe string `json:"readMe" gorm:"type:varchar;"`
|
||||
LastModified int `json:"lastModified" gorm:"type:Integer;"`
|
||||
|
||||
Details []AppDetail `json:"-" gorm:"-:migration"`
|
||||
TagsKey []string `json:"tags" yaml:"tags" gorm:"-"`
|
||||
AppTags []AppTag `json:"-" gorm:"-:migration"`
|
||||
}
|
||||
|
@@ -2,11 +2,15 @@ package model
|
||||
|
||||
type AppDetail struct {
|
||||
BaseModel
|
||||
AppId uint `json:"appId" gorm:"type:integer;not null"`
|
||||
Version string `json:"version" gorm:"type:varchar(64);not null"`
|
||||
Params string `json:"-" gorm:"type:longtext;"`
|
||||
DockerCompose string `json:"-" gorm:"type:longtext;not null"`
|
||||
Readme string `json:"readme" gorm:"type:longtext;"`
|
||||
Status string `json:"status" gorm:"type:varchar(64);not null"`
|
||||
LastVersion string `json:"lastVersion" gorm:"type:varchar(64);"`
|
||||
AppId uint `json:"appId" gorm:"type:integer;not null"`
|
||||
Version string `json:"version" gorm:"type:varchar(64);not null"`
|
||||
Params string `json:"-" gorm:"type:longtext;"`
|
||||
DockerCompose string `json:"dockerCompose" gorm:"type:longtext;"`
|
||||
Status string `json:"status" gorm:"type:varchar(64);not null"`
|
||||
LastVersion string `json:"lastVersion" gorm:"type:varchar(64);"`
|
||||
LastModified int `json:"lastModified" gorm:"type:integer;"`
|
||||
DownloadUrl string `json:"downloadUrl" gorm:"type:varchar;"`
|
||||
DownloadCallBackUrl string `json:"downloadCallBackUrl" gorm:"type:longtext;"`
|
||||
Update bool `json:"update"`
|
||||
IgnoreUpgrade bool `json:"ignoreUpgrade"`
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package model
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
)
|
||||
@@ -26,9 +27,21 @@ type AppInstall struct {
|
||||
}
|
||||
|
||||
func (i *AppInstall) GetPath() string {
|
||||
return path.Join(constant.AppInstallDir, i.App.Key, i.Name)
|
||||
return path.Join(i.getAppPath(), i.Name)
|
||||
}
|
||||
|
||||
func (i *AppInstall) GetComposePath() string {
|
||||
return path.Join(constant.AppInstallDir, i.App.Key, i.Name, "docker-compose.yml")
|
||||
return path.Join(i.getAppPath(), i.Name, "docker-compose.yml")
|
||||
}
|
||||
|
||||
func (i *AppInstall) GetEnvPath() string {
|
||||
return path.Join(i.getAppPath(), i.Name, ".env")
|
||||
}
|
||||
|
||||
func (i *AppInstall) getAppPath() string {
|
||||
if i.App.Resource == constant.AppResourceLocal {
|
||||
return path.Join(constant.LocalAppInstallDir, strings.TrimPrefix(i.App.Key, constant.AppResourceLocal))
|
||||
} else {
|
||||
return path.Join(constant.AppInstallDir, i.App.Key)
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ type BackupAccount struct {
|
||||
Bucket string `gorm:"type:varchar(256)" json:"bucket"`
|
||||
AccessKey string `gorm:"type:varchar(256)" json:"accessKey"`
|
||||
Credential string `gorm:"type:varchar(256)" json:"credential"`
|
||||
BackupPath string `gorm:"type:varchar(256)" json:"backupPath"`
|
||||
Vars string `gorm:"type:longText" json:"vars"`
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,9 @@ type Cronjob struct {
|
||||
Day uint64 `gorm:"type:decimal" json:"day"`
|
||||
Hour uint64 `gorm:"type:decimal" json:"hour"`
|
||||
Minute uint64 `gorm:"type:decimal" json:"minute"`
|
||||
Second uint64 `gorm:"type:decimal" json:"second"`
|
||||
|
||||
ContainerName string `gorm:"type:varchar(64)" json:"containerName"`
|
||||
Script string `gorm:"longtext" json:"script"`
|
||||
Website string `gorm:"type:varchar(64)" json:"website"`
|
||||
DBName string `gorm:"type:varchar(64)" json:"dbName"`
|
||||
|
@@ -3,6 +3,7 @@ package model
|
||||
type DatabaseMysql struct {
|
||||
BaseModel
|
||||
Name string `json:"name" gorm:"type:varchar(256);not null"`
|
||||
From string `json:"from" gorm:"type:varchar(256);not null;default:local"`
|
||||
MysqlName string `json:"mysqlName" gorm:"type:varchar(64);not null"`
|
||||
Format string `json:"format" gorm:"type:varchar(64);not null"`
|
||||
Username string `json:"username" gorm:"type:varchar(256);not null"`
|
||||
|
@@ -2,14 +2,17 @@ package model
|
||||
|
||||
type Host struct {
|
||||
BaseModel
|
||||
GroupID uint `gorm:"type:decimal;not null" json:"group_id"`
|
||||
Name string `gorm:"type:varchar(64);not null" json:"name"`
|
||||
Addr string `gorm:"type:varchar(16);not null" json:"addr"`
|
||||
Port int `gorm:"type:decimal;not null" json:"port"`
|
||||
User string `gorm:"type:varchar(64);not null" json:"user"`
|
||||
AuthMode string `gorm:"type:varchar(16);not null" json:"authMode"`
|
||||
Password string `gorm:"type:varchar(64)" json:"password"`
|
||||
PrivateKey string `gorm:"type:varchar(256)" json:"privateKey"`
|
||||
|
||||
GroupID uint `gorm:"type:decimal;not null" json:"group_id"`
|
||||
Name string `gorm:"type:varchar(64);not null" json:"name"`
|
||||
Addr string `gorm:"type:varchar(16);not null" json:"addr"`
|
||||
Port int `gorm:"type:decimal;not null" json:"port"`
|
||||
User string `gorm:"type:varchar(64);not null" json:"user"`
|
||||
AuthMode string `gorm:"type:varchar(16);not null" json:"authMode"`
|
||||
Password string `gorm:"type:varchar(64)" json:"password"`
|
||||
PrivateKey string `gorm:"type:varchar(256)" json:"privateKey"`
|
||||
PassPhrase string `gorm:"type:varchar(256)" json:"passPhrase"`
|
||||
RememberPassword bool `json:"rememberPassword"`
|
||||
|
||||
Description string `gorm:"type:varchar(256)" json:"description"`
|
||||
}
|
||||
|
14
backend/app/model/remote_db.go
Normal file
14
backend/app/model/remote_db.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package model
|
||||
|
||||
type RemoteDB struct {
|
||||
BaseModel
|
||||
Name string `json:"name" gorm:"type:varchar(64);not null"`
|
||||
Type string `json:"type" gorm:"type:varchar(64);not null"`
|
||||
Version string `json:"version" gorm:"type:varchar(64);not null"`
|
||||
From string `json:"from" gorm:"type:varchar(64);not null"`
|
||||
Address string `json:"address" gorm:"type:varchar(64);not null"`
|
||||
Port uint `json:"port" gorm:"type:decimal;not null"`
|
||||
Username string `json:"username" gorm:"type:varchar(64)"`
|
||||
Password string `json:"password" gorm:"type:varchar(64)"`
|
||||
Description string `json:"description" gorm:"type:varchar(256);"`
|
||||
}
|
17
backend/app/model/runtime.go
Normal file
17
backend/app/model/runtime.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package model
|
||||
|
||||
type Runtime struct {
|
||||
BaseModel
|
||||
Name string `gorm:"type:varchar;not null" json:"name"`
|
||||
AppDetailID uint `gorm:"type:integer" json:"appDetailId"`
|
||||
Image string `gorm:"type:varchar" json:"image"`
|
||||
WorkDir string `gorm:"type:varchar" json:"workDir"`
|
||||
DockerCompose string `gorm:"type:varchar" json:"dockerCompose"`
|
||||
Env string `gorm:"type:varchar" json:"env"`
|
||||
Params string `gorm:"type:varchar" json:"params"`
|
||||
Version string `gorm:"type:varchar;not null" json:"version"`
|
||||
Type string `gorm:"type:varchar;not null" json:"type"`
|
||||
Status string `gorm:"type:varchar;not null" json:"status"`
|
||||
Resource string `gorm:"type:varchar;not null" json:"resource"`
|
||||
Message string `gorm:"type:longtext;" json:"message"`
|
||||
}
|
@@ -4,23 +4,34 @@ import "time"
|
||||
|
||||
type Website struct {
|
||||
BaseModel
|
||||
Protocol string `gorm:"type:varchar(64);not null" json:"protocol"`
|
||||
PrimaryDomain string `gorm:"type:varchar(128);not null" json:"primaryDomain"`
|
||||
Type string `gorm:"type:varchar(64);not null" json:"type"`
|
||||
Alias string `gorm:"type:varchar(128);not null" json:"alias"`
|
||||
Remark string `gorm:"type:longtext;" json:"remark"`
|
||||
Status string `gorm:"type:varchar(64);not null" json:"status"`
|
||||
HttpConfig string `gorm:"type:varchar(64);not null" json:"httpConfig"`
|
||||
ExpireDate time.Time `json:"expireDate"`
|
||||
AppInstallID uint `gorm:"type:integer" json:"appInstallId"`
|
||||
WebsiteGroupID uint `gorm:"type:integer" json:"webSiteGroupId"`
|
||||
WebsiteSSLID uint `gorm:"type:integer" json:"webSiteSSLId"`
|
||||
Proxy string `gorm:"type:varchar(128);not null" json:"proxy"`
|
||||
ErrorLog bool `json:"errorLog"`
|
||||
AccessLog bool `json:"accessLog"`
|
||||
DefaultServer bool `json:"defaultServer"`
|
||||
Domains []WebsiteDomain `json:"domains" gorm:"-:migration"`
|
||||
WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"`
|
||||
Protocol string `gorm:"type:varchar;not null" json:"protocol"`
|
||||
PrimaryDomain string `gorm:"type:varchar;not null" json:"primaryDomain"`
|
||||
Type string `gorm:"type:varchar;not null" json:"type"`
|
||||
Alias string `gorm:"type:varchar;not null" json:"alias"`
|
||||
Remark string `gorm:"type:longtext;" json:"remark"`
|
||||
Status string `gorm:"type:varchar;not null" json:"status"`
|
||||
HttpConfig string `gorm:"type:varchar;not null" json:"httpConfig"`
|
||||
ExpireDate time.Time `json:"expireDate"`
|
||||
|
||||
Proxy string `gorm:"type:varchar;" json:"proxy"`
|
||||
ProxyType string `gorm:"type:varchar;" json:"proxyType"`
|
||||
SiteDir string `gorm:"type:varchar;" json:"siteDir"`
|
||||
ErrorLog bool `json:"errorLog"`
|
||||
AccessLog bool `json:"accessLog"`
|
||||
DefaultServer bool `json:"defaultServer"`
|
||||
IPV6 bool `json:"IPV6"`
|
||||
Rewrite string `gorm:"type:varchar" json:"rewrite"`
|
||||
|
||||
WebsiteGroupID uint `gorm:"type:integer" json:"webSiteGroupId"`
|
||||
WebsiteSSLID uint `gorm:"type:integer" json:"webSiteSSLId"`
|
||||
RuntimeID uint `gorm:"type:integer" json:"runtimeID"`
|
||||
AppInstallID uint `gorm:"type:integer" json:"appInstallId"`
|
||||
|
||||
User string `gorm:"type:varchar;" json:"user"`
|
||||
Group string `gorm:"type:varchar;" json:"group"`
|
||||
|
||||
Domains []WebsiteDomain `json:"domains" gorm:"-:migration"`
|
||||
WebsiteSSL WebsiteSSL `json:"webSiteSSL" gorm:"-:migration"`
|
||||
}
|
||||
|
||||
func (w Website) TableName() string {
|
||||
|
@@ -11,6 +11,26 @@ import (
|
||||
type AppRepo struct {
|
||||
}
|
||||
|
||||
type IAppRepo interface {
|
||||
WithKey(key string) DBOption
|
||||
WithType(typeStr string) DBOption
|
||||
OrderByRecommend() DBOption
|
||||
GetRecommend() DBOption
|
||||
WithResource(resource string) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.App, error)
|
||||
GetFirst(opts ...DBOption) (model.App, error)
|
||||
GetBy(opts ...DBOption) ([]model.App, error)
|
||||
BatchCreate(ctx context.Context, apps []model.App) error
|
||||
GetByKey(ctx context.Context, key string) (model.App, error)
|
||||
Create(ctx context.Context, app *model.App) error
|
||||
Save(ctx context.Context, app *model.App) error
|
||||
BatchDelete(ctx context.Context, apps []model.App) error
|
||||
}
|
||||
|
||||
func NewIAppRepo() IAppRepo {
|
||||
return &AppRepo{}
|
||||
}
|
||||
|
||||
func (a AppRepo) WithKey(key string) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("key = ?", key)
|
||||
@@ -35,12 +55,18 @@ func (a AppRepo) GetRecommend() DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppRepo) WithResource(resource string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("resource = ?", resource)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppRepo) Page(page, size int, opts ...DBOption) (int64, []model.App, error) {
|
||||
var apps []model.App
|
||||
db := getDb(opts...).Model(&model.App{})
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error
|
||||
err := db.Debug().Limit(size).Offset(size * (page - 1)).Preload("AppTags").Find(&apps).Error
|
||||
return count, apps, err
|
||||
}
|
||||
|
||||
@@ -81,3 +107,7 @@ func (a AppRepo) Create(ctx context.Context, app *model.App) error {
|
||||
func (a AppRepo) Save(ctx context.Context, app *model.App) error {
|
||||
return getTx(ctx).Omit(clause.Associations).Save(app).Error
|
||||
}
|
||||
|
||||
func (a AppRepo) BatchDelete(ctx context.Context, apps []model.App) error {
|
||||
return getTx(ctx).Omit(clause.Associations).Delete(&apps).Error
|
||||
}
|
||||
|
@@ -4,22 +4,47 @@ import (
|
||||
"context"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type AppDetailRepo struct {
|
||||
}
|
||||
|
||||
type IAppDetailRepo interface {
|
||||
WithVersion(version string) DBOption
|
||||
WithAppId(id uint) DBOption
|
||||
WithIgnored() DBOption
|
||||
GetFirst(opts ...DBOption) (model.AppDetail, error)
|
||||
Update(ctx context.Context, detail model.AppDetail) error
|
||||
BatchCreate(ctx context.Context, details []model.AppDetail) error
|
||||
DeleteByAppIds(ctx context.Context, appIds []uint) error
|
||||
GetBy(opts ...DBOption) ([]model.AppDetail, error)
|
||||
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
|
||||
BatchDelete(ctx context.Context, appDetails []model.AppDetail) error
|
||||
}
|
||||
|
||||
func NewIAppDetailRepo() IAppDetailRepo {
|
||||
return &AppDetailRepo{}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) WithVersion(version string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("version = ?", version)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) WithAppId(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_id = ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) WithIgnored() DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("ignore_upgrade = 1")
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) GetFirst(opts ...DBOption) (model.AppDetail, error) {
|
||||
var detail model.AppDetail
|
||||
err := getDb(opts...).Model(&model.AppDetail{}).Find(&detail).Error
|
||||
@@ -51,3 +76,7 @@ func (a AppDetailRepo) BatchUpdateBy(maps map[string]interface{}, opts ...DBOpti
|
||||
}
|
||||
return db.Updates(&maps).Error
|
||||
}
|
||||
|
||||
func (a AppDetailRepo) BatchDelete(ctx context.Context, appDetails []model.AppDetail) error {
|
||||
return getTx(ctx).Omit(clause.Associations).Delete(&appDetails).Error
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package repo
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"gorm.io/gorm/clause"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
@@ -11,6 +12,33 @@ import (
|
||||
|
||||
type AppInstallRepo struct{}
|
||||
|
||||
type IAppInstallRepo interface {
|
||||
WithDetailIdsIn(detailIds []uint) DBOption
|
||||
WithDetailIdNotIn(detailIds []uint) DBOption
|
||||
WithAppId(appId uint) DBOption
|
||||
WithAppIdsIn(appIds []uint) DBOption
|
||||
WithStatus(status string) DBOption
|
||||
WithServiceName(serviceName string) DBOption
|
||||
WithContainerName(containerName string) DBOption
|
||||
WithPort(port int) DBOption
|
||||
WithIdNotInWebsite() DBOption
|
||||
WithIDNotIs(id uint) DBOption
|
||||
ListBy(opts ...DBOption) ([]model.AppInstall, error)
|
||||
GetFirst(opts ...DBOption) (model.AppInstall, error)
|
||||
Create(ctx context.Context, install *model.AppInstall) error
|
||||
Save(ctx context.Context, install *model.AppInstall) error
|
||||
DeleteBy(opts ...DBOption) error
|
||||
Delete(ctx context.Context, install model.AppInstall) error
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.AppInstall, error)
|
||||
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
|
||||
LoadBaseInfo(key string, name string) (*RootInfo, error)
|
||||
GetFirstByCtx(ctx context.Context, opts ...DBOption) (model.AppInstall, error)
|
||||
}
|
||||
|
||||
func NewIAppInstallRepo() IAppInstallRepo {
|
||||
return &AppInstallRepo{}
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) WithDetailIdsIn(detailIds []uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_detail_id in (?)", detailIds)
|
||||
@@ -29,6 +57,12 @@ func (a *AppInstallRepo) WithAppId(appId uint) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) WithIDNotIs(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id != ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) WithAppIdsIn(appIds []uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_id in (?)", appIds)
|
||||
@@ -47,6 +81,12 @@ func (a *AppInstallRepo) WithServiceName(serviceName string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) WithContainerName(containerName string) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("container_name = ?", containerName)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) WithPort(port int) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("https_port = ? or http_port = ?", port, port)
|
||||
@@ -73,13 +113,20 @@ func (a *AppInstallRepo) GetFirst(opts ...DBOption) (model.AppInstall, error) {
|
||||
return install, err
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) Create(ctx context.Context, install *model.AppInstall) error {
|
||||
db := getTx(ctx).Model(&model.AppInstall{})
|
||||
return db.Create(&install).Error
|
||||
func (a *AppInstallRepo) GetFirstByCtx(ctx context.Context, opts ...DBOption) (model.AppInstall, error) {
|
||||
var install model.AppInstall
|
||||
db := getTx(ctx, opts...).Model(&model.AppInstall{})
|
||||
err := db.Preload("App").First(&install).Error
|
||||
return install, err
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) Save(install *model.AppInstall) error {
|
||||
return getDb().Save(&install).Error
|
||||
func (a *AppInstallRepo) Create(ctx context.Context, install *model.AppInstall) error {
|
||||
db := getTx(ctx).Model(&model.AppInstall{})
|
||||
return db.Omit(clause.Associations).Create(&install).Error
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) Save(ctx context.Context, install *model.AppInstall) error {
|
||||
return getTx(ctx).Save(&install).Error
|
||||
}
|
||||
|
||||
func (a *AppInstallRepo) DeleteBy(opts ...DBOption) error {
|
||||
@@ -112,9 +159,11 @@ type RootInfo struct {
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Port int64 `json:"port"`
|
||||
HttpsPort int64 `json:"httpsPort"`
|
||||
Password string `json:"password"`
|
||||
UserPassword string `json:"userPassword"`
|
||||
ContainerName string `json:"containerName"`
|
||||
ServiceName string `json:"serviceName"`
|
||||
Param string `json:"param"`
|
||||
Env string `json:"env"`
|
||||
Key string `json:"key"`
|
||||
@@ -143,16 +192,27 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
|
||||
if err := json.Unmarshal([]byte(appInstall.Env), &envMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
switch app.Key {
|
||||
case "mysql":
|
||||
password, ok := envMap["PANEL_DB_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
case "redis":
|
||||
password, ok := envMap["PANEL_REDIS_ROOT_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.Password = password
|
||||
}
|
||||
}
|
||||
|
||||
userPassword, ok := envMap["PANEL_DB_USER_PASSWORD"].(string)
|
||||
if ok {
|
||||
info.UserPassword = userPassword
|
||||
}
|
||||
info.Port = int64(appInstall.HttpPort)
|
||||
info.HttpsPort = int64(appInstall.HttpsPort)
|
||||
info.ID = appInstall.ID
|
||||
info.ServiceName = appInstall.ServiceName
|
||||
info.ContainerName = appInstall.ContainerName
|
||||
info.Name = appInstall.Name
|
||||
info.Env = appInstall.Env
|
||||
|
@@ -11,6 +11,21 @@ import (
|
||||
type AppInstallResourceRpo struct {
|
||||
}
|
||||
|
||||
type IAppInstallResourceRpo interface {
|
||||
WithAppInstallId(appInstallId uint) DBOption
|
||||
WithLinkId(linkId uint) DBOption
|
||||
WithResourceId(resourceId uint) DBOption
|
||||
GetBy(opts ...DBOption) ([]model.AppInstallResource, error)
|
||||
GetFirst(opts ...DBOption) (model.AppInstallResource, error)
|
||||
Create(ctx context.Context, resource *model.AppInstallResource) error
|
||||
DeleteBy(ctx context.Context, opts ...DBOption) error
|
||||
BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error
|
||||
}
|
||||
|
||||
func NewIAppInstallResourceRpo() IAppInstallResourceRpo {
|
||||
return &AppInstallResourceRpo{}
|
||||
}
|
||||
|
||||
func (a AppInstallResourceRpo) WithAppInstallId(appInstallId uint) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("app_install_id = ?", appInstallId)
|
||||
@@ -57,3 +72,11 @@ func (a AppInstallResourceRpo) Create(ctx context.Context, resource *model.AppIn
|
||||
func (a AppInstallResourceRpo) DeleteBy(ctx context.Context, opts ...DBOption) error {
|
||||
return getTx(ctx, opts...).Delete(&model.AppInstallResource{}).Error
|
||||
}
|
||||
|
||||
func (a *AppInstallResourceRpo) BatchUpdateBy(maps map[string]interface{}, opts ...DBOption) error {
|
||||
db := getDb(opts...).Model(&model.AppInstallResource{})
|
||||
if len(opts) == 0 {
|
||||
db = db.Where("1=1")
|
||||
}
|
||||
return db.Updates(&maps).Error
|
||||
}
|
||||
|
@@ -8,6 +8,18 @@ import (
|
||||
type AppTagRepo struct {
|
||||
}
|
||||
|
||||
type IAppTagRepo interface {
|
||||
BatchCreate(ctx context.Context, tags []*model.AppTag) error
|
||||
DeleteByAppIds(ctx context.Context, appIds []uint) error
|
||||
DeleteAll(ctx context.Context) error
|
||||
GetByAppId(appId uint) ([]model.AppTag, error)
|
||||
GetByTagIds(tagIds []uint) ([]model.AppTag, error)
|
||||
}
|
||||
|
||||
func NewIAppTagRepo() IAppTagRepo {
|
||||
return &AppTagRepo{}
|
||||
}
|
||||
|
||||
func (a AppTagRepo) BatchCreate(ctx context.Context, tags []*model.AppTag) error {
|
||||
return getTx(ctx).Create(&tags).Error
|
||||
}
|
||||
|
@@ -20,6 +20,8 @@ type IBackupRepo interface {
|
||||
Delete(opts ...DBOption) error
|
||||
DeleteRecord(ctx context.Context, opts ...DBOption) error
|
||||
WithByDetailName(detailName string) DBOption
|
||||
WithByFileName(fileName string) DBOption
|
||||
WithByType(backupType string) DBOption
|
||||
}
|
||||
|
||||
func NewIBackupRepo() IBackupRepo {
|
||||
|
@@ -15,6 +15,7 @@ type ICommandRepo interface {
|
||||
Create(command *model.Command) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
Get(opts ...DBOption) (model.Command, error)
|
||||
}
|
||||
|
||||
func NewICommandRepo() ICommandRepo {
|
||||
|
@@ -2,6 +2,7 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
@@ -16,15 +17,21 @@ type ICommonRepo interface {
|
||||
WithByName(name string) DBOption
|
||||
WithByType(tp string) DBOption
|
||||
WithOrderBy(orderStr string) DBOption
|
||||
WithOrderRuleBy(orderBy, order string) DBOption
|
||||
WithByGroupID(groupID uint) DBOption
|
||||
WithLikeName(name string) DBOption
|
||||
WithIdsIn(ids []uint) DBOption
|
||||
WithByDate(startTime, endTime time.Time) DBOption
|
||||
WithByStartDate(startTime time.Time) DBOption
|
||||
WithByStatus(status string) DBOption
|
||||
}
|
||||
|
||||
type CommonRepo struct{}
|
||||
|
||||
func NewCommonRepo() ICommonRepo {
|
||||
return &CommonRepo{}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithByID(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id = ?", id)
|
||||
@@ -88,6 +95,21 @@ func (c *CommonRepo) WithOrderBy(orderStr string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithOrderRuleBy(orderBy, order string) DBOption {
|
||||
switch order {
|
||||
case constant.OrderDesc:
|
||||
order = "desc"
|
||||
case constant.OrderAsc:
|
||||
order = "asc"
|
||||
default:
|
||||
orderBy = "created_at"
|
||||
order = "desc"
|
||||
}
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Order(fmt.Sprintf("%s %s", orderBy, order))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommonRepo) WithIdsIn(ids []uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id in (?)", ids)
|
||||
|
@@ -15,8 +15,10 @@ type IComposeTemplateRepo interface {
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
|
||||
GetRecord(opts ...DBOption) (model.Compose, error)
|
||||
CreateRecord(compose *model.Compose) error
|
||||
DeleteRecord(opts ...DBOption) error
|
||||
ListRecord() ([]model.Compose, error)
|
||||
}
|
||||
|
||||
func NewIComposeTemplateRepo() IComposeTemplateRepo {
|
||||
@@ -71,6 +73,16 @@ func (u *ComposeTemplateRepo) Delete(opts ...DBOption) error {
|
||||
return db.Delete(&model.ComposeTemplate{}).Error
|
||||
}
|
||||
|
||||
func (u *ComposeTemplateRepo) GetRecord(opts ...DBOption) (model.Compose, error) {
|
||||
var compose model.Compose
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&compose).Error
|
||||
return compose, err
|
||||
}
|
||||
|
||||
func (u *ComposeTemplateRepo) ListRecord() ([]model.Compose, error) {
|
||||
var composes []model.Compose
|
||||
if err := global.DB.Find(&composes).Error; err != nil {
|
||||
|
@@ -20,12 +20,15 @@ type ICronjobRepo interface {
|
||||
Page(limit, offset int, opts ...DBOption) (int64, []model.Cronjob, error)
|
||||
Create(cronjob *model.Cronjob) error
|
||||
WithByJobID(id int) DBOption
|
||||
WithByBackupID(id uint) DBOption
|
||||
WithByRecordDropID(id int) DBOption
|
||||
Save(id uint, cronjob model.Cronjob) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
DeleteRecord(opts ...DBOption) error
|
||||
StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords
|
||||
EndRecords(record model.JobRecords, status, message, records string)
|
||||
PageRecords(page, size int, opts ...DBOption) (int64, []model.JobRecords, error)
|
||||
}
|
||||
|
||||
func NewICronjobRepo() ICronjobRepo {
|
||||
@@ -80,7 +83,7 @@ func (u *CronjobRepo) Page(page, size int, opts ...DBOption) (int64, []model.Cro
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Order("created_at desc").Limit(size).Offset(size * (page - 1)).Find(&cronjobs).Error
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&cronjobs).Error
|
||||
return count, cronjobs, err
|
||||
}
|
||||
|
||||
@@ -112,6 +115,18 @@ func (c *CronjobRepo) WithByJobID(id int) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CronjobRepo) WithByBackupID(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("target_dir_id = ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CronjobRepo) WithByRecordDropID(id int) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id < ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *CronjobRepo) StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords {
|
||||
var record model.JobRecords
|
||||
record.StartTime = time.Now()
|
||||
|
@@ -13,13 +13,14 @@ type MysqlRepo struct{}
|
||||
type IMysqlRepo interface {
|
||||
Get(opts ...DBOption) (model.DatabaseMysql, error)
|
||||
WithByMysqlName(mysqlName string) DBOption
|
||||
WithByFrom(from string) DBOption
|
||||
List(opts ...DBOption) ([]model.DatabaseMysql, error)
|
||||
Page(limit, offset int, opts ...DBOption) (int64, []model.DatabaseMysql, error)
|
||||
Create(ctx context.Context, mysql *model.DatabaseMysql) error
|
||||
Delete(ctx context.Context, opts ...DBOption) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
UpdateDatabaseInfo(id uint, vars map[string]interface{}) error
|
||||
DeleteAll(ctx context.Context) error
|
||||
DeleteLocal(ctx context.Context) error
|
||||
}
|
||||
|
||||
func NewIMysqlRepo() IMysqlRepo {
|
||||
@@ -66,8 +67,8 @@ func (u *MysqlRepo) Delete(ctx context.Context, opts ...DBOption) error {
|
||||
return getTx(ctx, opts...).Delete(&model.DatabaseMysql{}).Error
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) DeleteAll(ctx context.Context) error {
|
||||
return getTx(ctx).Where("1 = 1").Delete(&model.DatabaseMysql{}).Error
|
||||
func (u *MysqlRepo) DeleteLocal(ctx context.Context) error {
|
||||
return getTx(ctx).Where("`from` = ?", "local").Delete(&model.DatabaseMysql{}).Error
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) Update(id uint, vars map[string]interface{}) error {
|
||||
@@ -86,3 +87,12 @@ func (u *MysqlRepo) WithByMysqlName(mysqlName string) DBOption {
|
||||
return g.Where("mysql_name = ?", mysqlName)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *MysqlRepo) WithByFrom(from string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
if len(from) != 0 {
|
||||
return g.Where("`from` = ?", from)
|
||||
}
|
||||
return g
|
||||
}
|
||||
}
|
||||
|
@@ -1,29 +0,0 @@
|
||||
package repo
|
||||
|
||||
type RepoGroup struct {
|
||||
CommonRepo
|
||||
AppRepo
|
||||
AppTagRepo
|
||||
TagRepo
|
||||
AppDetailRepo
|
||||
AppInstallRepo
|
||||
AppInstallResourceRpo
|
||||
ImageRepoRepo
|
||||
ComposeTemplateRepo
|
||||
MysqlRepo
|
||||
CronjobRepo
|
||||
HostRepo
|
||||
CommandRepo
|
||||
GroupRepo
|
||||
SettingRepo
|
||||
BackupRepo
|
||||
WebsiteRepo
|
||||
WebsiteDomainRepo
|
||||
WebsiteDnsAccountRepo
|
||||
WebsiteSSLRepo
|
||||
WebsiteAcmeAccountRepo
|
||||
LogRepo
|
||||
SnapshotRepo
|
||||
}
|
||||
|
||||
var RepoGroupApp = new(RepoGroup)
|
@@ -25,7 +25,7 @@ func NewIHostRepo() IHostRepo {
|
||||
return &HostRepo{}
|
||||
}
|
||||
|
||||
func (u *HostRepo) Get(opts ...DBOption) (model.Host, error) {
|
||||
func (h *HostRepo) Get(opts ...DBOption) (model.Host, error) {
|
||||
var host model.Host
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
@@ -35,7 +35,7 @@ func (u *HostRepo) Get(opts ...DBOption) (model.Host, error) {
|
||||
return host, err
|
||||
}
|
||||
|
||||
func (u *HostRepo) GetList(opts ...DBOption) ([]model.Host, error) {
|
||||
func (h *HostRepo) GetList(opts ...DBOption) ([]model.Host, error) {
|
||||
var hosts []model.Host
|
||||
db := global.DB.Model(&model.Host{})
|
||||
for _, opt := range opts {
|
||||
@@ -45,7 +45,7 @@ func (u *HostRepo) GetList(opts ...DBOption) ([]model.Host, error) {
|
||||
return hosts, err
|
||||
}
|
||||
|
||||
func (u *HostRepo) Page(page, size int, opts ...DBOption) (int64, []model.Host, error) {
|
||||
func (h *HostRepo) Page(page, size int, opts ...DBOption) (int64, []model.Host, error) {
|
||||
var users []model.Host
|
||||
db := global.DB.Model(&model.Host{})
|
||||
for _, opt := range opts {
|
||||
@@ -57,7 +57,7 @@ func (u *HostRepo) Page(page, size int, opts ...DBOption) (int64, []model.Host,
|
||||
return count, users, err
|
||||
}
|
||||
|
||||
func (c *HostRepo) WithByInfo(info string) DBOption {
|
||||
func (h *HostRepo) WithByInfo(info string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
if len(info) == 0 {
|
||||
return g
|
||||
@@ -67,22 +67,22 @@ func (c *HostRepo) WithByInfo(info string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *HostRepo) WithByPort(port uint) DBOption {
|
||||
func (h *HostRepo) WithByPort(port uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("port = ?", port)
|
||||
}
|
||||
}
|
||||
func (u *HostRepo) WithByUser(user string) DBOption {
|
||||
func (h *HostRepo) WithByUser(user string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("user = ?", user)
|
||||
}
|
||||
}
|
||||
func (u *HostRepo) WithByAddr(addr string) DBOption {
|
||||
func (h *HostRepo) WithByAddr(addr string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("addr = ?", addr)
|
||||
}
|
||||
}
|
||||
func (u *HostRepo) WithByGroup(group string) DBOption {
|
||||
func (h *HostRepo) WithByGroup(group string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
if len(group) == 0 {
|
||||
return g
|
||||
@@ -91,15 +91,15 @@ func (u *HostRepo) WithByGroup(group string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (u *HostRepo) Create(host *model.Host) error {
|
||||
func (h *HostRepo) Create(host *model.Host) error {
|
||||
return global.DB.Create(host).Error
|
||||
}
|
||||
|
||||
func (u *HostRepo) Update(id uint, vars map[string]interface{}) 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 (u *HostRepo) Delete(opts ...DBOption) error {
|
||||
func (h *HostRepo) Delete(opts ...DBOption) error {
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
|
84
backend/app/repo/remote_db.go
Normal file
84
backend/app/repo/remote_db.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type RemoteDBRepo struct{}
|
||||
|
||||
type IRemoteDBRepo interface {
|
||||
GetList(opts ...DBOption) ([]model.RemoteDB, error)
|
||||
Page(limit, offset int, opts ...DBOption) (int64, []model.RemoteDB, error)
|
||||
Create(database *model.RemoteDB) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Delete(opts ...DBOption) error
|
||||
Get(opts ...DBOption) (model.RemoteDB, error)
|
||||
WithByFrom(from string) DBOption
|
||||
WithoutByFrom(from string) DBOption
|
||||
}
|
||||
|
||||
func NewIRemoteDBRepo() IRemoteDBRepo {
|
||||
return &RemoteDBRepo{}
|
||||
}
|
||||
|
||||
func (u *RemoteDBRepo) Get(opts ...DBOption) (model.RemoteDB, error) {
|
||||
var database model.RemoteDB
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.First(&database).Error
|
||||
return database, err
|
||||
}
|
||||
|
||||
func (u *RemoteDBRepo) Page(page, size int, opts ...DBOption) (int64, []model.RemoteDB, error) {
|
||||
var users []model.RemoteDB
|
||||
db := global.DB.Model(&model.RemoteDB{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&users).Error
|
||||
return count, users, err
|
||||
}
|
||||
|
||||
func (u *RemoteDBRepo) GetList(opts ...DBOption) ([]model.RemoteDB, error) {
|
||||
var databases []model.RemoteDB
|
||||
db := global.DB.Model(&model.RemoteDB{})
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
err := db.Find(&databases).Error
|
||||
return databases, err
|
||||
}
|
||||
|
||||
func (c *RemoteDBRepo) WithByFrom(from string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`from` == ?", from)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *RemoteDBRepo) WithoutByFrom(from string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`from` != ?", from)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *RemoteDBRepo) Create(database *model.RemoteDB) error {
|
||||
return global.DB.Create(database).Error
|
||||
}
|
||||
|
||||
func (u *RemoteDBRepo) Update(id uint, vars map[string]interface{}) error {
|
||||
return global.DB.Model(&model.RemoteDB{}).Where("id = ?", id).Updates(vars).Error
|
||||
}
|
||||
|
||||
func (u *RemoteDBRepo) Delete(opts ...DBOption) error {
|
||||
db := global.DB
|
||||
for _, opt := range opts {
|
||||
db = opt(db)
|
||||
}
|
||||
return db.Delete(&model.RemoteDB{}).Error
|
||||
}
|
87
backend/app/repo/runtime.go
Normal file
87
backend/app/repo/runtime.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type RuntimeRepo struct {
|
||||
}
|
||||
|
||||
type IRuntimeRepo interface {
|
||||
WithName(name string) DBOption
|
||||
WithImage(image string) DBOption
|
||||
WithNotId(id uint) DBOption
|
||||
WithStatus(status string) DBOption
|
||||
WithDetailId(id uint) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error)
|
||||
Create(ctx context.Context, runtime *model.Runtime) error
|
||||
Save(runtime *model.Runtime) error
|
||||
DeleteBy(opts ...DBOption) error
|
||||
GetFirst(opts ...DBOption) (*model.Runtime, error)
|
||||
}
|
||||
|
||||
func NewIRunTimeRepo() IRuntimeRepo {
|
||||
return &RuntimeRepo{}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) WithName(name string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("name = ?", name)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) WithStatus(status string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("status = ?", status)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) WithImage(image string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("image = ?", image)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) WithDetailId(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("app_detail_id = ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) WithNotId(id uint) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("id != ?", id)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) Page(page, size int, opts ...DBOption) (int64, []model.Runtime, error) {
|
||||
var runtimes []model.Runtime
|
||||
db := getDb(opts...).Model(&model.Runtime{})
|
||||
count := int64(0)
|
||||
db = db.Count(&count)
|
||||
err := db.Limit(size).Offset(size * (page - 1)).Find(&runtimes).Error
|
||||
return count, runtimes, err
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) Create(ctx context.Context, runtime *model.Runtime) error {
|
||||
db := getTx(ctx).Model(&model.Runtime{})
|
||||
return db.Create(&runtime).Error
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) Save(runtime *model.Runtime) error {
|
||||
return getDb().Save(&runtime).Error
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) DeleteBy(opts ...DBOption) error {
|
||||
return getDb(opts...).Delete(&model.Runtime{}).Error
|
||||
}
|
||||
|
||||
func (r *RuntimeRepo) GetFirst(opts ...DBOption) (*model.Runtime, error) {
|
||||
var runtime model.Runtime
|
||||
if err := getDb(opts...).First(&runtime).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &runtime, nil
|
||||
}
|
@@ -1,6 +1,8 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"gorm.io/gorm"
|
||||
@@ -14,6 +16,13 @@ type ISettingRepo interface {
|
||||
Create(key, value string) error
|
||||
Update(key, value string) error
|
||||
WithByKey(key string) DBOption
|
||||
|
||||
CreateMonitorBase(model model.MonitorBase) error
|
||||
BatchCreateMonitorIO(ioList []model.MonitorIO) error
|
||||
BatchCreateMonitorNet(ioList []model.MonitorNetwork) error
|
||||
DelMonitorBase(timeForDelete time.Time) error
|
||||
DelMonitorIO(timeForDelete time.Time) error
|
||||
DelMonitorNet(timeForDelete time.Time) error
|
||||
}
|
||||
|
||||
func NewISettingRepo() ISettingRepo {
|
||||
@@ -57,3 +66,22 @@ func (c *SettingRepo) WithByKey(key string) DBOption {
|
||||
func (u *SettingRepo) Update(key, value string) error {
|
||||
return global.DB.Model(&model.Setting{}).Where("key = ?", key).Updates(map[string]interface{}{"value": value}).Error
|
||||
}
|
||||
|
||||
func (u *SettingRepo) CreateMonitorBase(model model.MonitorBase) error {
|
||||
return global.DB.Create(&model).Error
|
||||
}
|
||||
func (u *SettingRepo) BatchCreateMonitorIO(ioList []model.MonitorIO) error {
|
||||
return global.DB.CreateInBatches(ioList, len(ioList)).Error
|
||||
}
|
||||
func (u *SettingRepo) BatchCreateMonitorNet(ioList []model.MonitorNetwork) error {
|
||||
return global.DB.CreateInBatches(ioList, len(ioList)).Error
|
||||
}
|
||||
func (u *SettingRepo) DelMonitorBase(timeForDelete time.Time) error {
|
||||
return global.DB.Where("created_at < ?", timeForDelete).Delete(&model.MonitorBase{}).Error
|
||||
}
|
||||
func (u *SettingRepo) DelMonitorIO(timeForDelete time.Time) error {
|
||||
return global.DB.Where("created_at < ?", timeForDelete).Delete(&model.MonitorIO{}).Error
|
||||
}
|
||||
func (u *SettingRepo) DelMonitorNet(timeForDelete time.Time) error {
|
||||
return global.DB.Where("created_at < ?", timeForDelete).Delete(&model.MonitorNetwork{}).Error
|
||||
}
|
||||
|
@@ -8,6 +8,19 @@ import (
|
||||
type TagRepo struct {
|
||||
}
|
||||
|
||||
type ITagRepo interface {
|
||||
BatchCreate(ctx context.Context, tags []*model.Tag) error
|
||||
DeleteAll(ctx context.Context) error
|
||||
All() ([]model.Tag, error)
|
||||
GetByIds(ids []uint) ([]model.Tag, error)
|
||||
GetByKeys(keys []string) ([]model.Tag, error)
|
||||
GetByAppId(appId uint) ([]model.Tag, error)
|
||||
}
|
||||
|
||||
func NewITagRepo() ITagRepo {
|
||||
return &TagRepo{}
|
||||
}
|
||||
|
||||
func (t TagRepo) BatchCreate(ctx context.Context, tags []*model.Tag) error {
|
||||
return getTx(ctx).Create(&tags).Error
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ type IWebsiteRepo interface {
|
||||
WithGroupID(groupId uint) DBOption
|
||||
WithDefaultServer() DBOption
|
||||
WithDomainLike(domain string) DBOption
|
||||
WithRuntimeID(runtimeID uint) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.Website, error)
|
||||
List(opts ...DBOption) ([]model.Website, error)
|
||||
GetFirst(opts ...DBOption) (model.Website, error)
|
||||
@@ -40,6 +41,12 @@ func (w *WebsiteRepo) WithAppInstallId(appInstallId uint) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WebsiteRepo) WithRuntimeID(runtimeID uint) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("runtime_id = ?", runtimeID)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WebsiteRepo) WithDomain(domain string) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("primary_domain = ?", domain)
|
||||
|
@@ -7,6 +7,19 @@ import (
|
||||
type WebsiteDnsAccountRepo struct {
|
||||
}
|
||||
|
||||
type IWebsiteDnsAccountRepo interface {
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.WebsiteDnsAccount, error)
|
||||
GetFirst(opts ...DBOption) (*model.WebsiteDnsAccount, error)
|
||||
List(opts ...DBOption) ([]model.WebsiteDnsAccount, error)
|
||||
Create(account model.WebsiteDnsAccount) error
|
||||
Save(account model.WebsiteDnsAccount) error
|
||||
DeleteBy(opts ...DBOption) error
|
||||
}
|
||||
|
||||
func NewIWebsiteDnsAccountRepo() IWebsiteDnsAccountRepo {
|
||||
return &WebsiteDnsAccountRepo{}
|
||||
}
|
||||
|
||||
func (w WebsiteDnsAccountRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebsiteDnsAccount, error) {
|
||||
var accounts []model.WebsiteDnsAccount
|
||||
db := getDb(opts...).Model(&model.WebsiteDnsAccount{})
|
||||
|
@@ -10,6 +10,23 @@ import (
|
||||
type WebsiteDomainRepo struct {
|
||||
}
|
||||
|
||||
type IWebsiteDomainRepo interface {
|
||||
WithWebsiteId(websiteId uint) DBOption
|
||||
WithPort(port int) DBOption
|
||||
WithDomain(domain string) DBOption
|
||||
Page(page, size int, opts ...DBOption) (int64, []model.WebsiteDomain, error)
|
||||
GetFirst(opts ...DBOption) (model.WebsiteDomain, error)
|
||||
GetBy(opts ...DBOption) ([]model.WebsiteDomain, error)
|
||||
BatchCreate(ctx context.Context, domains []model.WebsiteDomain) error
|
||||
Create(ctx context.Context, app *model.WebsiteDomain) error
|
||||
Save(ctx context.Context, app *model.WebsiteDomain) error
|
||||
DeleteBy(ctx context.Context, opts ...DBOption) error
|
||||
}
|
||||
|
||||
func NewIWebsiteDomainRepo() IWebsiteDomainRepo {
|
||||
return &WebsiteDomainRepo{}
|
||||
}
|
||||
|
||||
func (w WebsiteDomainRepo) WithWebsiteId(websiteId uint) DBOption {
|
||||
return func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("website_id = ?", websiteId)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user