from fastapi import APIRouter, HTTPException, status from app.core.device.manager import device_manager from app.core.dispatcher import dispatcher from app.schemas.ssh import SSHExecRequest, SSHExecResponse from app.utils.log import get_logger logger = get_logger(__name__) router = APIRouter() @router.post("/devices/{device_id}/exec", response_model=SSHExecResponse, summary="执行SSH命令") async def exec_ssh_command(device_id: str, exec_request: SSHExecRequest): """在指定设备上执行SSH命令""" try: # 检查设备是否存在 device = await device_manager.get_device(device_id) if not device: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"设备 {device_id} 不存在" ) # 检查协议是否为SSH if device.protocol_type != 'ssh': raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"设备 {device_id} 不是SSH协议,当前协议: {device.protocol_type}" ) # 执行SSH命令 result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="exec_command", command=exec_request.command, timeout=exec_request.timeout, working_directory=exec_request.working_directory ) return result except HTTPException: raise except Exception as e: logger.error(f"SSH命令执行失败: {device_id}, 错误: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"SSH命令执行失败: {str(e)}" ) @router.post("/devices/{device_id}/upload", summary="上传文件") async def upload_file(device_id: str, local_path: str, remote_path: str): """通过SSH上传文件""" try: # 检查设备是否存在 device = await device_manager.get_device(device_id) if not device: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"设备 {device_id} 不存在" ) # 检查协议是否为SSH if device.protocol_type != 'ssh': raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"设备 {device_id} 不是SSH协议,当前协议: {device.protocol_type}" ) # 执行文件上传 result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="upload_file", local_path=local_path, remote_path=remote_path ) return result except HTTPException: raise except Exception as e: logger.error(f"SSH文件上传失败: {device_id}, 错误: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"SSH文件上传失败: {str(e)}" ) @router.post("/devices/{device_id}/download", summary="下载文件") async def download_file(device_id: str, remote_path: str, local_path: str): """通过SSH下载文件""" try: # 检查设备是否存在 device = await device_manager.get_device(device_id) if not device: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"设备 {device_id} 不存在" ) # 检查协议是否为SSH if device.protocol_type != 'ssh': raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"设备 {device_id} 不是SSH协议,当前协议: {device.protocol_type}" ) # 执行文件下载 result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="download_file", remote_path=remote_path, local_path=local_path ) return result except HTTPException: raise except Exception as e: logger.error(f"SSH文件下载失败: {device_id}, 错误: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"SSH文件下载失败: {str(e)}" ) @router.get("/devices/{device_id}/test-connection", summary="测试SSH连接") async def test_ssh_connection(device_id: str): """测试SSH连接状态""" try: # 检查设备是否存在 device = await device_manager.get_device(device_id) if not device: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=f"设备 {device_id} 不存在" ) # 检查协议是否为SSH if device.protocol_type != 'ssh': raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"设备 {device_id} 不是SSH协议,当前协议: {device.protocol_type}" ) # 测试连接 result = await dispatcher.execute_operation( device_id=device_id, protocol_type=device.protocol_type, operation="test_connection" ) return { "device_id": device_id, "connected": result, "message": "连接正常" if result else "连接失败" } except HTTPException: raise except Exception as e: logger.error(f"SSH连接测试失败: {device_id}, 错误: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"SSH连接测试失败: {str(e)}" )