机器连接修改
This commit is contained in:
parent
62b0caa3da
commit
891a332c59
@ -72,8 +72,8 @@ public class MachineInfoController {
|
|||||||
|
|
||||||
@PostMapping("/test")
|
@PostMapping("/test")
|
||||||
@Operation(summary = "测试机器连接")
|
@Operation(summary = "测试机器连接")
|
||||||
public CommonResult<Boolean> testConnection(@RequestBody MachineInfo machineInfo) {
|
public CommonResult<Boolean> testConnection(@RequestParam Long id) {
|
||||||
return success(machineInfoService.testConnection(machineInfo));
|
return success(machineInfoService.testConnection(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/status/{machineName}")
|
@GetMapping("/status/{machineName}")
|
||||||
|
@ -30,7 +30,7 @@ public class MachineInfoDto extends PageDto {
|
|||||||
|
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
private String sshPort;
|
private Integer sshPort;
|
||||||
|
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public class MachineInfo extends BaseEntity {
|
|||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
//SSH端口号
|
//SSH端口号
|
||||||
@TableField(value = "SSH_port")
|
@TableField(value = "ssh_port")
|
||||||
private Integer sshPort;
|
private Integer sshPort;
|
||||||
|
|
||||||
@TableField(value = "password")
|
@TableField(value = "password")
|
||||||
|
@ -1,18 +1,15 @@
|
|||||||
package cd.casic.module.machine.handler;
|
package cd.casic.module.machine.handler;
|
||||||
|
|
||||||
|
|
||||||
import cd.casic.module.machine.utils.AliYunOssClient;
|
import cd.casic.module.machine.utils.AliYunOssClient;
|
||||||
import cd.casic.module.machine.entity.MachineInfo;
|
import cd.casic.module.machine.entity.MachineInfo;
|
||||||
import cd.casic.module.machine.entity.SecretKey;
|
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.enums.ConnectionStatus;
|
||||||
import cd.casic.module.machine.service.SecretKeyService;
|
import cd.casic.module.machine.service.SecretKeyService;
|
||||||
import com.jcraft.jsch.*;
|
import com.jcraft.jsch.*;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.StreamUtils;
|
import org.springframework.util.StreamUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -23,6 +20,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
* 优化后的SSH连接会话类
|
* 优化后的SSH连接会话类
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class ConnectionSession implements AutoCloseable {
|
public class ConnectionSession implements AutoCloseable {
|
||||||
@Resource
|
@Resource
|
||||||
SecretKeyService secretKeyService;
|
SecretKeyService secretKeyService;
|
||||||
@ -30,21 +28,29 @@ public class ConnectionSession implements AutoCloseable {
|
|||||||
@Resource
|
@Resource
|
||||||
AliYunOssClient aliYunOssClient;
|
AliYunOssClient aliYunOssClient;
|
||||||
|
|
||||||
private final MachineInfo machineInfo;
|
private MachineInfo machineInfo;
|
||||||
private Session sshSession;
|
private Session sshSession;
|
||||||
private ConnectionStatus status = ConnectionStatus.DISCONNECTED;
|
private ConnectionStatus status = ConnectionStatus.DISCONNECTED;
|
||||||
private final AtomicBoolean isExecuting = new AtomicBoolean(false);
|
private final AtomicBoolean isExecuting = new AtomicBoolean(false);
|
||||||
|
|
||||||
// 连接配置常量
|
// todo连接配置常量
|
||||||
private static final int CONNECTION_TIMEOUT = 5000; // 连接超时时间(毫秒)
|
private static final int CONNECTION_TIMEOUT = 5000; // 连接超时时间(毫秒)
|
||||||
private static final int COMMAND_TIMEOUT = 30000; // 命令执行超时时间(毫秒)
|
private static final int COMMAND_TIMEOUT = 30000; // 命令执行超时时间(毫秒)
|
||||||
private static final int RETRY_COUNT = 3; // 重试次数
|
private static final int RETRY_COUNT = 3; // 重试次数
|
||||||
private static final int RETRY_DELAY = 1000; // 重试间隔(毫秒)
|
private static final int RETRY_DELAY = 1000; // 重试间隔(毫秒)
|
||||||
|
|
||||||
public ConnectionSession(MachineInfo machineInfo) {
|
public ConnectionSession() {
|
||||||
this.machineInfo = Objects.requireNonNull(machineInfo, "MachineInfo cannot be null");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 使用setter注入MachineInfo
|
||||||
|
public void setMachineInfo(MachineInfo machineInfo) {
|
||||||
|
this.machineInfo = Objects.requireNonNull(machineInfo, "MachineInfo cannot be null");
|
||||||
|
log.debug("MachineInfo 已注入: {}", machineInfo.getHostIp());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 建立SSH连接,支持重试机制
|
* 建立SSH连接,支持重试机制
|
||||||
*/
|
*/
|
||||||
@ -121,25 +127,32 @@ public class ConnectionSession implements AutoCloseable {
|
|||||||
* 配置认证方式(密码或密钥)
|
* 配置认证方式(密码或密钥)
|
||||||
*/
|
*/
|
||||||
private void configureAuthentication(JSch jsch) throws JSchException {
|
private void configureAuthentication(JSch jsch) throws JSchException {
|
||||||
if (machineInfo.getAuthenticationType() == AuthenticationType.SECRET_KEY) {
|
if (machineInfo.getAuthenticationTypeCode() == 2) {
|
||||||
// 密钥认证
|
// 密钥认证
|
||||||
if (machineInfo.getSecretKeyId() == null) {
|
if (machineInfo.getSecretKeyId() == null) {
|
||||||
throw new JSchException("Secret key ID is required for key-based authentication");
|
throw new JSchException("Secret key ID is required for key-based authentication");
|
||||||
}
|
}
|
||||||
|
|
||||||
String privateKeyContent = getPrivateKeyContent(machineInfo.getSecretKeyId());
|
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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载私钥(支持密码短语,可从配置中获取)
|
try {
|
||||||
jsch.addIdentity(
|
// 尝试加载私钥
|
||||||
machineInfo.getName(),
|
jsch.addIdentity(
|
||||||
privateKeyContent.getBytes(StandardCharsets.UTF_8),
|
machineInfo.getName(),
|
||||||
null,
|
privateKeyContent.getBytes(StandardCharsets.UTF_8),
|
||||||
null // 密码短语,可为null
|
null,
|
||||||
);
|
null
|
||||||
} else if (machineInfo.getAuthenticationType() == AuthenticationType.PASSWORD) {
|
);
|
||||||
|
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())) {
|
if (StringUtils.isEmpty(machineInfo.getPassword())) {
|
||||||
throw new JSchException("Password is required for password-based authentication");
|
throw new JSchException("Password is required for password-based authentication");
|
||||||
|
@ -28,10 +28,10 @@ public interface MachineInfoService extends IService<MachineInfo> {
|
|||||||
/**
|
/**
|
||||||
* 测试机器连接
|
* 测试机器连接
|
||||||
*
|
*
|
||||||
* @param machineInfo 机器信息
|
* @param id 机器id
|
||||||
* @return 连接是否成功
|
* @return 连接是否成功
|
||||||
*/
|
*/
|
||||||
boolean testConnection(MachineInfo machineInfo);
|
boolean testConnection(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取机器连接状态
|
* 获取机器连接状态
|
||||||
|
@ -42,7 +42,8 @@ public class MachineinfoServiceImpl extends ServiceImpl<MachineInfoMapper, Machi
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MachineInfoMapper machineInfoMapper;
|
private MachineInfoMapper machineInfoMapper;
|
||||||
|
@Resource
|
||||||
|
private ConnectionSession connectionSession;
|
||||||
/**
|
/**
|
||||||
* 会话ID生成器
|
* 会话ID生成器
|
||||||
*/
|
*/
|
||||||
@ -184,14 +185,19 @@ public class MachineinfoServiceImpl extends ServiceImpl<MachineInfoMapper, Machi
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean testConnection(MachineInfo machineInfo) {
|
public boolean testConnection(Long id) {
|
||||||
if (machineInfo.getStatus().getCode() == UN_ENABLE) {
|
//先查询机器是否存在,在判断机器可用性
|
||||||
|
MachineInfo machineInfo = this.getById(id);
|
||||||
|
if (machineInfo==null){
|
||||||
|
throw new RuntimeException("机器不存在");
|
||||||
|
}
|
||||||
|
if (machineInfo.getStatusCode() == 0) {
|
||||||
throw new RuntimeException("机器不可用");
|
throw new RuntimeException("机器不可用");
|
||||||
}
|
}
|
||||||
log.info("测试机器连接: {}", machineInfo.getHostIp());
|
log.info("测试机器连接: {}", machineInfo.getHostIp());
|
||||||
|
connectionSession.setMachineInfo(machineInfo);
|
||||||
try (ConnectionSession session = createSession(machineInfo)) {
|
try{
|
||||||
session.connect();
|
connectionSession.connect();
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("机器连接测试失败: {}", e.getMessage(), e);
|
log.error("机器连接测试失败: {}", e.getMessage(), e);
|
||||||
@ -240,14 +246,15 @@ public class MachineinfoServiceImpl extends ServiceImpl<MachineInfoMapper, Machi
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ConnectionSession session = createSession(machineInfo);
|
connectionSession.setMachineInfo(machineInfo);
|
||||||
session.connect();
|
|
||||||
|
connectionSession.connect();
|
||||||
|
|
||||||
// 生成会话ID
|
// 生成会话ID
|
||||||
String sessionId = generateSessionId();
|
String sessionId = generateSessionId();
|
||||||
|
|
||||||
// 保存会话
|
// 保存会话
|
||||||
sessions.put(sessionId, session);
|
sessions.put(sessionId, connectionSession);
|
||||||
machineSessionMapping.put(machineInfo.getName(), sessionId);
|
machineSessionMapping.put(machineInfo.getName(), sessionId);
|
||||||
|
|
||||||
log.info("机器连接成功: {}, 会话ID: {}", machineInfo.getHostIp(), sessionId);
|
log.info("机器连接成功: {}, 会话ID: {}", machineInfo.getHostIp(), sessionId);
|
||||||
@ -346,12 +353,6 @@ public class MachineinfoServiceImpl extends ServiceImpl<MachineInfoMapper, Machi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建连接会话
|
|
||||||
*/
|
|
||||||
private ConnectionSession createSession(MachineInfo machineInfo) {
|
|
||||||
return new ConnectionSession(machineInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成会话ID
|
* 生成会话ID
|
||||||
|
Loading…
x
Reference in New Issue
Block a user