
    ,Wi4                        S r SSKJrJr  SSKJr  SSKJr  SSKJ	r	J
r
JrJrJr  SSKrSSKrSSKrSSKJrJr  \R&                  " S	5      \S
 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       r\R&                  " S5      \S 5       5       rg)u   
管理员工具 API 路由
    )jsonifycurrent_app   )admin_bp)admin_required)dbUserChallengeRecordDeploymentRecordUserSessionN)datetime	timedeltaz/api/db/checkc                      SSK Jn   [        R                  R	                  5       [
        R                  R	                  5       [        R                  R	                  5       [        R                  R	                  5       U R                  S.nU R                  S:X  a  [        R                  R                  U R                  U R                  5      n[        R                  R                  U5      (       a+  [        R                  R                  U5      S-  nUS S3US'   O+U R                    S	U R"                   S
U R$                   3US'   ['        SSUS.5      $ ! [(         a&  n['        SS[+        U5       3S.5      S4s SnA$ SnAff = f)u   检查数据库状态r   Config)	   用户数	   题目数	   部署数u	   会话数u   数据库类型sqlite   .2f MBu   数据库大小z @ :	   数据库Tu   数据库状态正常successmessagedataF   错误: r   r     N)config.settingsr   r	   querycountr
   r   r   DATABASE_TYPEospathjoinINSTANCE_PATHSQLITE_DB_NAMEexistsgetsizePOSTGRES_DBPOSTGRES_HOSTPOSTGRES_PORTr   	Exceptionstr)r   statsdb_pathsize_mbes        D   /Users/yu22x/Desktop/ddd_副本128/ctf/app/routes/admin/tools_api.pyapi_db_checkr7      sS   P* ))+(..446)//557$**002%33
 8+ggll6#7#79N9NOGww~~g&&''//'2kB.5c]#+>'($*$6$6#7s6;O;O:PPQRXRfRfQg!hE+.
  	
  P5xAx5HIJCOOPs   EE 
F"F=FFz/api/db/backupc                      SSK Jn   U R                  S:w  a  [        SSS.5      S4$ [        R
                  R                  U R                  U R                  5      n[        R
                  R                  U5      (       d  [        SSS.5      S	4$ S
n[        R                  " USS9  [        R                  " 5       R                  S5      nU SU S3n[        R                  " X5        [        R
                  R!                  U5      S-  n[        SSU SUS S3S.5      $ ! ["         a&  n[        SS[%        U5       3S.5      S4s SnA$ SnAff = f)u   备份数据库r   r   r   Fu2   PostgreSQL 数据库备份请使用 pg_dump 命令r    i  u   数据库文件不存在i  backupsT)exist_okz%Y%m%d_%H%M%Sz/ctf_backup_z.dbr   u   数据库备份成功: z (r   z MB)u   备份失败: r!   N)r"   r   r%   r   r&   r'   r(   r)   r*   r+   makedirsr   nowstrftimeshutilcopy2r,   r0   r1   )r   r3   
backup_dir	timestampbackup_pathr4   r5   s          r6   api_db_backuprC   /   sI   V*8+ O   
 '',,v33V5J5JKww~~g&&u9STUWZZZ 

J. LLN++O<	#L3? 	W*''//+.+>0R}DQ
  	  V5~c!fX5NOPRUUUVs*   %D! A'D! BD! !
E+EEEz/api/docker/containersc            	          [         R                  " / SQSSSS9n U R                  S:w  a  [        SSU R                   3S.5      S	4$ / nU R
                  R                  5       R                  S
5       Ha  nU(       d  M  UR                  S5      n[        U5      S:  d  M.  UR                  US   US   US   [        U5      S:  a  US   OSS.5        Mc     [        SS[        U5       S3US.5      $ ! [         R                   a    [        SSS.5      S	4s $ [         a&  n[        SS[        U5       3S.5      S	4s SnA$ SnAff = f)u   列出所有容器)dockerps-az--formatz){{.ID}}	{{.Names}}	{{.Status}}	{{.Ports}}T
   capture_outputtexttimeoutr   Fu   Docker 命令失败: r    r!   
	   r      -)IDu   名称u   状态u   端口u   找到 u
    个容器r   u   Docker 命令超时r   N)
subprocessrun
returncoder   stderrstdoutstripsplitlenappendTimeoutExpiredr0   r1   )result
containerslinepartsr5   s        r6   api_docker_containersra   V   sZ   P^dB

 !u;PQWQ^Q^P_9`abdggg
MM'')//5Dt

4(u:?%%#Ah"'("'(.1%j1n%(#	' 	 6  Z 1<
  	
 $$ R55JKLcQQ P5xAx5HIJCOOPs7   AC4 3C4 ?C4 !AC4 4$E		E	#E>E	E	z/api/docker/clean-containersc                  ,    [         R                  " / SQSSSS9n U R                  S:w  a  [        SSU R                   3S.5      S	4$ [        SS
U R
                   3S.5      $ ! [         a&  n[        SS[        U5       3S.5      S	4s SnA$ SnAff = f)u   清理停止的容器)rE   	containerprune-fT   rI   r   F   清理失败: r    r!      清理完成
r   NrS   rT   rU   r   rV   rW   r0   r1   r]   r5   s     r6   api_docker_clean_containersrk   y   s    P2dB

 !u>&--9YZ[]```'7
  	  P5xAx5HIJCOOP$   AA# A# #
B-BBBz/api/docker/clean-imagesc                  ,    [         R                  " / SQSSSS9n U R                  S:w  a  [        SSU R                   3S.5      S	4$ [        SS
U R
                   3S.5      $ ! [         a&  n[        SS[        U5       3S.5      S	4s SnA$ SnAff = f)u   清理未使用的镜像)rE   imagerd   rG   re   T<   rI   r   Frg   r    r!   rh   r   Nri   rj   s     r6   api_docker_clean_imagesrp      s    P4dB

 !u>&--9YZ[]```'7
  	  P5xAx5HIJCOOPrl   z/api/files/disk-usagec                      S n 0 nSSSSS.nUR                  5        H  u  p4U " U5      nUS-  S S	3X'   M      [        R                  " / S
QSSSS9nUR                  S:X  a/  UR                  R                  5       R                  S5      S   US'   [        SSUS.5      $ !    N= f! [         a&  n[        SS[        U5       3S.5      S4s SnA$ SnAff = f)u   检查磁盘使用情况c                 t   [         R                  R                  U 5      (       d  gSn[         R                  " U 5       Hv  u  p#nU Hj  n[         R                  R	                  X%5      n[         R                  R                  U5      (       d  MH  U[         R                  R                  U5      -  nMl     Mx     U$ )u   获取目录大小r   )r&   r'   r+   walkr(   r,   )r'   totaldirpathdirnames	filenamesfilenamefilepaths          r6   get_dir_size*api_files_disk_usage.<locals>.get_dir_size   s    77>>$''E02,9 )H!ww||G>Hww~~h//!:: !* 1>
 L    u   输出目录u   日志目录u   数据库目录u   备份目录)ge10/outputloginstancer9   r   r   r   )dfz-h.T   rI   r   rM   u   系统磁盘u   磁盘使用情况r   Fr   r    r!   N)
itemsrS   rT   rU   rW   rX   rY   r   r0   r1   )rz   r2   dirsr'   namesizer]   r5   s           r6   api_files_disk_usager      s   )P
	  *!)%	
 **,JD%D![1#6c:EK '
	^^$5dQU_`aF  A%(.(;(;(=(C(CD(I"(Mn% +
  		  P5xAx5HIJCOOPs5   8B) AB" B) "B&$B) )
C3CCCz/api/files/clean-logsc                  X    Sn [         R                  R                  U 5      (       d  [        SSS.5      $ [        R
                  " 5       [        SS9-
  nSnSn[         R                  " U 5       H  u  pEnU H  n[         R                  R                  XG5      n [        R                  " [         R                  R                  U5      5      n	X:  a@  [         R                  R                  U5      n
[         R                  " U5        US-  nX:-  nM  M     M     [        SSU SUS-  S S3S.5      $ ! [         a9  n[        R                  R!                  S	U S
[#        U5       35         SnAM  SnAff = f! [         a&  n[        SS[#        U5       3S.5      S4s SnA$ SnAff = f)u   清理旧日志文件r~   Tu   日志目录不存在r    rf   daysr   r   u   无法删除文件 : N   清理完成：删除 u    个文件，释放 r   r   r   Fr   r!   )r&   r'   r+   r   r   r<   r   rs   r(   fromtimestampgetmtimer,   remover0   r   loggerwarningr1   )logs_dircutoff_datedeleted_countdeleted_sizerootr   filesrx   ry   mtimer   r5   s               r6   api_files_clean_logsr      s   Pww~~h''t8OPQQllnyb'99!#!2D!77<<7[$222773C3CH3MNE*!wwx8		(+%*$,	 +	 " "3 />RS_cnSopsRttwx
  	 ! [&&..1DXJbQTUVQWPX/YZZ[  P5xAx5HIJCOOPsN   3E9 A#E9 A6D3"E9 3
E6=.E1+E9 1E66E9 9
F)F$F)$F)z/api/files/clean-outputc            
      "    Sn [         R                  R                  U 5      (       d  [        SSS.5      $ [        R
                  " 5       [        SS9-
  nSnSn[         R                  " U 5       GH
  n[         R                  R                  X5      n[         R                  R                  U5      (       d  MI   [        R                  " [         R                  R                  U5      5      nXa:  a  [         R                  " U5       HP  u  pxn	U	 HD  n
[         R                  R                  Xz5      nU[         R                  R                  U5      -  nMF     MR     [        R                  " U5        US-  nGM
  GM     [        SSU SUS-  S S3S.5      $ ! [          a:  n["        R$                  R'                  S	U S
[)        U5       35         SnAGMg  SnAff = f! [          a&  n[        SS[)        U5       3S.5      S4s SnA$ SnAff = f)u   清理旧输出文件r}   Tu   输出目录不存在r    rf   r   r   r   u   无法删除目录 r   Nr   u    个目录，释放 r   r   r   Fr   r!   )r&   r'   r+   r   r   r<   r   listdirr(   isdirr   r   rs   r,   r>   rmtreer0   r   r   r   r1   )
output_dirr   r   r   item	item_pathr   r   r   r   rx   ry   r5   s                r6   api_files_clean_outputr      s    P"
ww~~j))t8OPQQllnyb'99JJz*DZ6Iww}}Y''\$222773C3CI3NOE*131C-D,1+-77<<+G ,0I I -2 2D i0%* + +$ />RS_cnSopsRttwx
  	 ! \&&..1DYKrRUVWRXQY/Z[[\  P5xAx5HIJCOOPsN   3G A>G 9B=F6 G 
G!.GG GG 
H(H	H	Hz/api/system/healthc                  b    0 n  [         R                  R                  [         R                  " S5      5        SU S'    [        R                  " SS/SS	S
9nUR                  S:X  a  SOSU S'   / SQnU H1  n[        R                  R                  U5      (       a  SOSU SU 3'   M3     [        R                  R                  5       U S'   [        R                  R                  5       U S'   [         R                  R                  5       U S'   [         R                  R#                  SS9R                  5       U S'   [%        SSU S.5      $ ! [         a  nS[        U5       3U S'    SnAGN,SnAff = f!   SU S'    GN= f! [         a&  n[%        SS[        U5       3S.5      S4s SnA$ SnAff = f)u   系统健康检查zSELECT 1u
   ✅ 正常r   u   ❌ 异常: NrE   infoTr   )rJ   rL   r   u
   ❌ 异常Dockeru   ❌ 未安装或无法访问)r}   r~   r   u
   ✅ 存在u   ❌ 不存在u   目录 r   r   r   running)statusu   运行中部署u   系统健康检查完成r   Fr   r    r!   )r   sessionexecuterK   r0   r1   rS   rT   rU   r&   r'   r+   r	   r#   r$   r
   r   	filter_byr   )healthr5   r]   r   ds        r6   api_system_healthr     s   "P	:JJrwwz23".F;
	>^^Xv$6tUVWF/5/@/@A/E|<F8
 2A46GGNN14E4EL?FWQC=!  #jj..0{-3399;{.44::<{$4$:$:$D$DI$D$V$\$\$^ !1
  	+  	:$0Q"9F;	:	>=F8$  P5xAx5HIJCOOPsX   E> 8E /E1 -CE> 
E.E)#E> )E..E> 1E;8E> >
F.F)#F.)F.z/api/system/clean-sessionsc                      [         R                  " 5       [        SS9-
  n [        R                  R                  [        R                  U :  5      R                  5       n[        R                  R                  5         [        SSU S3S.5      $ ! [         aD  n[        R                  R                  5         [        SS[        U5       3S.5      S	4s S
nA$ S
nAff = f)u   清理过期会话rf   r   Tr   u    个过期会话r    Fr   r!   N)r   r<   r   r   r#   filter
created_atdeleter   r   commitr   r0   rollbackr1   )r   deletedr5   s      r6   api_system_clean_sessionsr   C  s    Pllnyb'99##**;+A+AK+OPWWY


/y8HI
  	  P


5xAx5HIJCOOPs   BB 
C9CCCz/api/system/clean-deploymentsc            
      v    SSK Jn   [        R                  " 5       n[        R
                  R                  [        R                  U:  5      R                  5       nU " 5       nSnU H  n UR                  (       a_  [        R                  R                  UR                  5      (       a1  UR                  UR                  UR                  UR                  5        SUl        US-  nM     [,        R.                  R1                  5         [3        SS	U S
3S.5      $ ! ["         aC  n[$        R&                  R)                  SUR                   S[+        U5       35         SnAM  SnAff = f! ["         aD  n[,        R.                  R5                  5         [3        SS[+        U5       3S.5      S4s SnA$ SnAff = f)u   清理过期部署r   )DockerExecutionServicer   r   u   清理部署 u	    失败: NTu   清理完成：清理 u    个过期部署r    Fr   r!   ).app.services.deployment.core.execution_servicer   r   r<   r   r#   r   
expires_atallworking_directoryr&   r'   r+   delete_deploymentdeployment_uuidexternal_portr   r0   r   r   r   r1   r   r   r   r   r   )r   r<   expired_deploymentsdocker_servicecleaned_count
deploymentr5   s          r6   api_system_clean_deploymentsr   U  s   $PY lln.44;;''#-

#% 	 01-Jj//BGGNN:C_C_4`4`"44"22"44"00 %.
!" .  	

/>NO
  	  j""**]:;U;U:VV_`cde`f_g+hiij  P


5xAx5HIJCOOPsI   A'E* *A<D&3E* 
E'$8E"E* "E''E* *
F849F3-F83F8)__doc__flaskr   r    r   app.services.auth.decoratorsr   app.models.database.modelsr   r	   r
   r   r   rS   r&   r>   r   r   router7   rC   ra   rk   rp   r   r   r   r   r   r    r|   r6   <module>r      s   '  7 _ _  	  ( 
 P  !P< 
 !!V  "!VJ 
()P  *PB 
./P  0P$ 
*+P  ,P( 
'(+P  )+PZ 
'(P  )P> 
)*"P  +"PL 
$%$P  &$PL 
,-P  .P  
/0&P  1&Pr|   