From 891a332c5974bc294e899ec62551f2d8a7d66728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=90=E6=BD=87=E5=87=AF?= Date: Thu, 5 Jun 2025 11:00:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=BA=E5=99=A8=E8=BF=9E=E6=8E=A5=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MachineInfoController.java | 4 +- .../module/machine/dto/MachineInfoDto.java | 2 +- .../module/machine/entity/MachineInfo.java | 2 +- .../machine/handler/ConnectionSession.java | 51 ++++++++++++------- .../machine/service/MachineInfoService.java | 4 +- .../service/impl/MachineinfoServiceImpl.java | 31 +++++------ 6 files changed, 54 insertions(+), 40 deletions(-) diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineInfoController.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineInfoController.java index a77e1025..453526b4 100644 --- a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineInfoController.java +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineInfoController.java @@ -72,8 +72,8 @@ public class MachineInfoController { @PostMapping("/test") @Operation(summary = "测试机器连接") - public CommonResult testConnection(@RequestBody MachineInfo machineInfo) { - return success(machineInfoService.testConnection(machineInfo)); + public CommonResult testConnection(@RequestParam Long id) { + return success(machineInfoService.testConnection(id)); } @GetMapping("/status/{machineName}") diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dto/MachineInfoDto.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dto/MachineInfoDto.java index cd5648a1..9a2e2efc 100644 --- a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dto/MachineInfoDto.java +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dto/MachineInfoDto.java @@ -30,7 +30,7 @@ public class MachineInfoDto extends PageDto { private String status; - private String sshPort; + private Integer sshPort; private String password; diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/entity/MachineInfo.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/entity/MachineInfo.java index 8aa53f56..6564c264 100644 --- a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/entity/MachineInfo.java +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/entity/MachineInfo.java @@ -46,7 +46,7 @@ public class MachineInfo extends BaseEntity { private String username; //SSH端口号 - @TableField(value = "SSH_port") + @TableField(value = "ssh_port") private Integer sshPort; @TableField(value = "password") diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/handler/ConnectionSession.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/handler/ConnectionSession.java index 66766890..8936ab2a 100644 --- a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/handler/ConnectionSession.java +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/handler/ConnectionSession.java @@ -1,18 +1,15 @@ package cd.casic.module.machine.handler; - - import cd.casic.module.machine.utils.AliYunOssClient; import cd.casic.module.machine.entity.MachineInfo; import cd.casic.module.machine.entity.SecretKey; -import cd.casic.module.machine.enums.AuthenticationType; import cd.casic.module.machine.enums.ConnectionStatus; import cd.casic.module.machine.service.SecretKeyService; import com.jcraft.jsch.*; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils; - import java.io.*; import java.nio.charset.StandardCharsets; import java.util.Objects; @@ -23,6 +20,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * 优化后的SSH连接会话类 */ @Slf4j +@Component public class ConnectionSession implements AutoCloseable { @Resource SecretKeyService secretKeyService; @@ -30,21 +28,29 @@ public class ConnectionSession implements AutoCloseable { @Resource AliYunOssClient aliYunOssClient; - private final MachineInfo machineInfo; + private MachineInfo machineInfo; private Session sshSession; private ConnectionStatus status = ConnectionStatus.DISCONNECTED; private final AtomicBoolean isExecuting = new AtomicBoolean(false); - // 连接配置常量 + // todo连接配置常量 private static final int CONNECTION_TIMEOUT = 5000; // 连接超时时间(毫秒) private static final int COMMAND_TIMEOUT = 30000; // 命令执行超时时间(毫秒) private static final int RETRY_COUNT = 3; // 重试次数 private static final int RETRY_DELAY = 1000; // 重试间隔(毫秒) - public ConnectionSession(MachineInfo machineInfo) { - this.machineInfo = Objects.requireNonNull(machineInfo, "MachineInfo cannot be null"); + public ConnectionSession() { + } + // 使用setter注入MachineInfo + public void setMachineInfo(MachineInfo machineInfo) { + this.machineInfo = Objects.requireNonNull(machineInfo, "MachineInfo cannot be null"); + log.debug("MachineInfo 已注入: {}", machineInfo.getHostIp()); + } + + + /** * 建立SSH连接,支持重试机制 */ @@ -121,25 +127,32 @@ public class ConnectionSession implements AutoCloseable { * 配置认证方式(密码或密钥) */ private void configureAuthentication(JSch jsch) throws JSchException { - if (machineInfo.getAuthenticationType() == AuthenticationType.SECRET_KEY) { + if (machineInfo.getAuthenticationTypeCode() == 2) { // 密钥认证 if (machineInfo.getSecretKeyId() == null) { throw new JSchException("Secret key ID is required for key-based authentication"); } String privateKeyContent = getPrivateKeyContent(machineInfo.getSecretKeyId()); - if (StringUtils.isEmpty(privateKeyContent)) { - throw new JSchException("Private key content is empty or null for ID: " + machineInfo.getSecretKeyId()); + // 验证私钥格式 + if (!privateKeyContent.startsWith("-----BEGIN")) { + throw new JSchException("Invalid private key format. Expected OpenSSH format."); } - // 加载私钥(支持密码短语,可从配置中获取) - jsch.addIdentity( - machineInfo.getName(), - privateKeyContent.getBytes(StandardCharsets.UTF_8), - null, - null // 密码短语,可为null - ); - } else if (machineInfo.getAuthenticationType() == AuthenticationType.PASSWORD) { + try { + // 尝试加载私钥 + jsch.addIdentity( + machineInfo.getName(), + privateKeyContent.getBytes(StandardCharsets.UTF_8), + null, + null + ); + log.info("Private key loaded successfully for {}", machineInfo.getHostIp()); + } catch (JSchException e) { + log.error("Failed to load private key: {}", e.getMessage()); + throw e; + } + } else if (machineInfo.getAuthenticationTypeCode() == 1) { // 密码认证 if (StringUtils.isEmpty(machineInfo.getPassword())) { throw new JSchException("Password is required for password-based authentication"); diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineInfoService.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineInfoService.java index 6da0e94b..39ee38bf 100644 --- a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineInfoService.java +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineInfoService.java @@ -28,10 +28,10 @@ public interface MachineInfoService extends IService { /** * 测试机器连接 * - * @param machineInfo 机器信息 + * @param id 机器id * @return 连接是否成功 */ - boolean testConnection(MachineInfo machineInfo); + boolean testConnection(Long id); /** * 获取机器连接状态 diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineinfoServiceImpl.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineinfoServiceImpl.java index 10d61f6a..26916426 100644 --- a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineinfoServiceImpl.java +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineinfoServiceImpl.java @@ -42,7 +42,8 @@ public class MachineinfoServiceImpl extends ServiceImpl