增加服务器管理认证方式,增加测试连接接口

This commit is contained in:
dengqichen 2025-10-30 15:59:51 +08:00
parent 5186a5c43f
commit 1dbb411e08
4 changed files with 52 additions and 4 deletions

View File

@ -664,8 +664,7 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
*/ */
public List<JenkinsBuildResponse> listBuilds(ExternalSystem externalSystem, String jobName) { public List<JenkinsBuildResponse> listBuilds(ExternalSystem externalSystem, String jobName) {
// Jenkins API 默认只返回最近的若干个构建通过 {from,to} 可以指定范围 // Jenkins API 默认只返回最近的若干个构建通过 {from,to} 可以指定范围
// 这里获取最近200个构建记录 String treeQuery = "builds[number,url,result,timestamp,duration,building,actions[_class,parameters[_class,name,value]]]";
String treeQuery = "builds[number,url,result,timestamp,duration,building,actions[_class,parameters[_class,name,value]]]{0,200}";
List<JenkinsBuildResponse> builds = callJenkinsApi( List<JenkinsBuildResponse> builds = callJenkinsApi(
externalSystem, externalSystem,
"/job/" + jobName + "/api/json", "/job/" + jobName + "/api/json",

View File

@ -16,6 +16,7 @@ import lombok.extern.slf4j.Slf4j;
import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier; import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import net.schmizz.sshj.userauth.keyprovider.KeyProvider; import net.schmizz.sshj.userauth.keyprovider.KeyProvider;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -40,6 +41,22 @@ public class ServerServiceImpl
this.serverRepository = serverRepository; this.serverRepository = serverRepository;
} }
/**
* 校验服务器唯一约束
* 检查IP是否已存在
*/
@Override
protected void validateUniqueConstraints(ServerDTO dto) {
// 检查IP是否已存在排除已删除的记录
if (dto.getHostIp() != null) {
boolean exists = serverRepository.existsByHostIpAndDeletedFalse(dto.getHostIp());
if (exists) {
log.warn("服务器IP已存在: {}", dto.getHostIp());
throw new BusinessException(ResponseCode.SERVER_IP_EXISTS, new Object[]{dto.getHostIp()});
}
}
}
@Override @Override
@Transactional @Transactional
public ServerDTO initializeServerInfo(Long serverId, ServerInitializeDTO dto) { public ServerDTO initializeServerInfo(Long serverId, ServerInitializeDTO dto) {
@ -65,6 +82,7 @@ public class ServerServiceImpl
} }
@Override @Override
@Transactional
public boolean testConnection(Long serverId) { public boolean testConnection(Long serverId) {
// 1. 查询服务器信息 // 1. 查询服务器信息
Server server = serverRepository.findById(serverId) Server server = serverRepository.findById(serverId)
@ -130,18 +148,35 @@ public class ServerServiceImpl
if (cmd.getExitStatus() == 0) { if (cmd.getExitStatus() == 0) {
log.info("SSH连接测试成功: {}", server.getHostIp()); log.info("SSH连接测试成功: {}", server.getHostIp());
// 7. 更新服务器状态和最后连接时间
server.setStatus(ServerStatusEnum.ONLINE);
server.setLastConnectTime(LocalDateTime.now());
serverRepository.save(server);
log.info("已更新服务器状态为ONLINE: serverId={}", serverId);
return true; return true;
} else { } else {
log.warn("SSH连接测试失败命令执行异常: {}", server.getHostIp()); log.warn("SSH连接测试失败命令执行异常: {}", server.getHostIp());
// 8. 更新服务器状态为离线
server.setStatus(ServerStatusEnum.OFFLINE);
serverRepository.save(server);
return false; return false;
} }
} }
} catch (IOException e) { } catch (IOException e) {
log.error("SSH连接测试失败: {} - {}", server.getHostIp(), e.getMessage()); log.error("SSH连接测试失败: {} - {}", server.getHostIp(), e.getMessage());
// 9. 连接失败更新服务器状态为离线
server.setStatus(ServerStatusEnum.OFFLINE);
serverRepository.save(server);
throw new BusinessException(ResponseCode.ERROR, new Object[]{"SSH连接失败: " + e.getMessage()}); throw new BusinessException(ResponseCode.ERROR, new Object[]{"SSH连接失败: " + e.getMessage()});
} finally { } finally {
// 7. 关闭连接 // 10. 关闭连接
try { try {
if (ssh.isConnected()) { if (ssh.isConnected()) {
ssh.disconnect(); ssh.disconnect();

View File

@ -197,7 +197,14 @@ public enum ResponseCode {
TEAM_MEMBER_NOT_FOUND(2924, "team.member.not.found"), TEAM_MEMBER_NOT_FOUND(2924, "team.member.not.found"),
TEAM_MEMBER_ALREADY_EXISTS(2925, "team.member.already.exists"), TEAM_MEMBER_ALREADY_EXISTS(2925, "team.member.already.exists"),
TEAM_APPLICATION_NOT_FOUND(2926, "team.application.not.found"), TEAM_APPLICATION_NOT_FOUND(2926, "team.application.not.found"),
TEAM_APPLICATION_ALREADY_EXISTS(2927, "team.application.already.exists"); TEAM_APPLICATION_ALREADY_EXISTS(2927, "team.application.already.exists"),
// 服务器管理相关错误码 (2950-2969)
SERVER_NOT_FOUND(2950, "server.not.found"),
SERVER_IP_EXISTS(2951, "server.ip.exists"),
SERVER_CATEGORY_NOT_FOUND(2952, "server.category.not.found"),
SERVER_CATEGORY_CODE_EXISTS(2953, "server.category.code.exists"),
SERVER_CATEGORY_HAS_SERVERS(2954, "server.category.has.servers");
private final int code; private final int code;
private final String messageKey; // 国际化消息key private final String messageKey; // 国际化消息key

View File

@ -188,6 +188,13 @@ team.member.already.exists=该用户已是团队成员
team.application.not.found=团队应用关联不存在或已删除 team.application.not.found=团队应用关联不存在或已删除
team.application.already.exists=该应用已关联到此团队 team.application.already.exists=该应用已关联到此团队
# 服务器管理相关 (2950-2969)
server.not.found=服务器不存在或已删除
server.ip.exists=服务器IP {0} 已存在
server.category.not.found=服务器分类不存在或已删除
server.category.code.exists=服务器分类编码{0}已存在
server.category.has.servers=该分类下存在服务器,无法删除
# 定时任务相关 (2800-2899) # 定时任务相关 (2800-2899)
# 任务基础错误 (2800-2819) # 任务基础错误 (2800-2819)
schedule.job.not.found=定时任务不存在或已删除 schedule.job.not.found=定时任务不存在或已删除