diff --git a/pom.xml b/pom.xml index 170b0bc..6ba7993 100644 --- a/pom.xml +++ b/pom.xml @@ -29,8 +29,15 @@ 17 + + + com.jcraft + jsch + 0.1.55 + + commons-net commons-net diff --git a/src/main/java/com/mini/capi/biz/controller/DockerContainerInfoController.java b/src/main/java/com/mini/capi/biz/controller/DockerContainerInfoController.java new file mode 100644 index 0000000..5ca4421 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/controller/DockerContainerInfoController.java @@ -0,0 +1,18 @@ +package com.mini.capi.biz.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 容器信息采集表 前端控制器 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@RestController +@RequestMapping("/biz/dockerContainerInfo") +public class DockerContainerInfoController { + +} diff --git a/src/main/java/com/mini/capi/biz/controller/DockerHostController.java b/src/main/java/com/mini/capi/biz/controller/DockerHostController.java new file mode 100644 index 0000000..6010d7d --- /dev/null +++ b/src/main/java/com/mini/capi/biz/controller/DockerHostController.java @@ -0,0 +1,18 @@ +package com.mini.capi.biz.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 容器主机配置表 前端控制器 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@RestController +@RequestMapping("/biz/dockerHost") +public class DockerHostController { + +} diff --git a/src/main/java/com/mini/capi/biz/controller/SshInfoController.java b/src/main/java/com/mini/capi/biz/controller/SshInfoController.java new file mode 100644 index 0000000..d0bccb3 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/controller/SshInfoController.java @@ -0,0 +1,18 @@ +package com.mini.capi.biz.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * SSH 服务器信息表 前端控制器 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@RestController +@RequestMapping("/biz/sshInfo") +public class SshInfoController { + +} diff --git a/src/main/java/com/mini/capi/biz/controller/SshUserController.java b/src/main/java/com/mini/capi/biz/controller/SshUserController.java new file mode 100644 index 0000000..117b632 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/controller/SshUserController.java @@ -0,0 +1,18 @@ +package com.mini.capi.biz.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *

+ * 用户密码表 前端控制器 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@RestController +@RequestMapping("/biz/sshUser") +public class SshUserController { + +} diff --git a/src/main/java/com/mini/capi/biz/domain/DockerContainerInfo.java b/src/main/java/com/mini/capi/biz/domain/DockerContainerInfo.java new file mode 100644 index 0000000..a3a5e2a --- /dev/null +++ b/src/main/java/com/mini/capi/biz/domain/DockerContainerInfo.java @@ -0,0 +1,119 @@ +package com.mini.capi.biz.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 容器信息采集表 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@Getter +@Setter +@TableName("biz_docker_container_info") +public class DockerContainerInfo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 记录获取时间 + */ + @TableField("get_time") + private String getTime; + + /** + * 主键 + */ + @TableId(value = "id", type = IdType.AUTO) + private String id; + + /** + * 容器 ID + */ + @TableField("container_id") + private String containerId; + + /** + * 镜像名称 + */ + @TableField("image_name") + private String imageName; + + /** + * 启动命令 + */ + @TableField("command") + private String command; + + /** + * 容器创建时间 + */ + @TableField("created_at") + private String createdAt; + + /** + * 容器状态 + */ + @TableField("ustatus") + private String ustatus; + + /** + * 端口映射信息 + */ + @TableField("ports") + private String ports; + + /** + * 容器名称 + */ + @TableField("unames") + private String unames; + + /** + * 宿主机 IP + */ + @TableField("host_ip") + private String hostIp; + + /** + * 用户/租户 ID + */ + @TableField("doker_host_id") + private String dokerHostId; + + /** + * 租户id + */ + @TableField("f_tenant_id") + private String fTenantId; + + /** + * 流程id + */ + @TableField("f_flow_id") + private String fFlowId; + + /** + * 流程任务主键 + */ + @TableField("f_flow_task_id") + private String fFlowTaskId; + + /** + * 流程任务状态 + */ + @TableField("f_flow_state") + private Integer fFlowState; +} diff --git a/src/main/java/com/mini/capi/biz/domain/DockerHost.java b/src/main/java/com/mini/capi/biz/domain/DockerHost.java new file mode 100644 index 0000000..cd76ccf --- /dev/null +++ b/src/main/java/com/mini/capi/biz/domain/DockerHost.java @@ -0,0 +1,98 @@ +package com.mini.capi.biz.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 容器主机配置表 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@Getter +@Setter +@TableName("biz_docker_host") +public class DockerHost implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @TableField("create_time") + private LocalDateTime createTime; + + /** + * 主键 + */ + @TableId(value = "doker_host_id", type = IdType.AUTO) + private String dokerHostId; + + /** + * 账户编码 + */ + @TableField("user_id") + private String userId; + + /** + * 主机编码 + */ + @TableField("host_id") + private String hostId; + + /** + * 主机IP + */ + @TableField("host_ip") + private String hostIp; + + /** + * 容器总数量 + */ + @TableField("all_num") + private Long allNum; + + /** + * 运行总数量 + */ + @TableField("run_num") + private Long runNum; + + /** + * 描述 + */ + @TableField("remark") + private String remark; + + /** + * 租户id + */ + @TableField("f_tenant_id") + private String fTenantId; + + /** + * 流程id + */ + @TableField("f_flow_id") + private String fFlowId; + + /** + * 流程任务主键 + */ + @TableField("f_flow_task_id") + private String fFlowTaskId; + + /** + * 流程任务状态 + */ + @TableField("f_flow_state") + private Integer fFlowState; +} diff --git a/src/main/java/com/mini/capi/biz/domain/SshInfo.java b/src/main/java/com/mini/capi/biz/domain/SshInfo.java new file mode 100644 index 0000000..294d5ef --- /dev/null +++ b/src/main/java/com/mini/capi/biz/domain/SshInfo.java @@ -0,0 +1,80 @@ +package com.mini.capi.biz.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * SSH 服务器信息表 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@Getter +@Setter +@TableName("biz_ssh_info") +public class SshInfo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @TableField("create_time") + private LocalDateTime createTime; + + @TableId(value = "host_id", type = IdType.AUTO) + private String hostId; + + /** + * IP 或域名 + */ + @TableField("host_ip") + private String hostIp; + + /** + * SSH 端口 + */ + @TableField("host_port") + private String hostPort; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + @TableField("update_time") + private LocalDateTime updateTime; + + /** + * 租户id + */ + @TableField("f_tenant_id") + private String fTenantId; + + /** + * 流程id + */ + @TableField("f_flow_id") + private String fFlowId; + + /** + * 流程任务主键 + */ + @TableField("f_flow_task_id") + private String fFlowTaskId; + + /** + * 流程任务状态 + */ + @TableField("f_flow_state") + private Integer fFlowState; +} diff --git a/src/main/java/com/mini/capi/biz/domain/SshUser.java b/src/main/java/com/mini/capi/biz/domain/SshUser.java new file mode 100644 index 0000000..468fee1 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/domain/SshUser.java @@ -0,0 +1,80 @@ +package com.mini.capi.biz.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.Setter; + +/** + *

+ * 用户密码表 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@Getter +@Setter +@TableName("biz_ssh_user") +public class SshUser implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @TableField("create_time") + private LocalDateTime createTime; + + @TableId(value = "user_id", type = IdType.AUTO) + private String userId; + + /** + * 系统/应用/网站名称 + */ + @TableField("sys_name") + private String sysName; + + /** + * 登录账号 + */ + @TableField("c_username") + private String cUsername; + + /** + * 登录密码 + */ + @TableField("c_password") + private String cPassword; + + /** + * 访问地址 + */ + @TableField("c_url") + private String cUrl; + + /** + * 关联的主键 + */ + @TableField("host_id") + private String hostId; + + @TableField("update_time") + private LocalDateTime updateTime; + + /** + * 备注 + */ + @TableField("remark") + private String remark; + + /** + * 租户id + */ + @TableField("f_tenant_id") + private String fTenantId; +} diff --git a/src/main/java/com/mini/capi/biz/mapper/DockerContainerInfoMapper.java b/src/main/java/com/mini/capi/biz/mapper/DockerContainerInfoMapper.java new file mode 100644 index 0000000..0310858 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/mapper/DockerContainerInfoMapper.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.mapper; + +import com.mini.capi.biz.domain.DockerContainerInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 容器信息采集表 Mapper 接口 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +public interface DockerContainerInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/mini/capi/biz/mapper/DockerHostMapper.java b/src/main/java/com/mini/capi/biz/mapper/DockerHostMapper.java new file mode 100644 index 0000000..0067aca --- /dev/null +++ b/src/main/java/com/mini/capi/biz/mapper/DockerHostMapper.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.mapper; + +import com.mini.capi.biz.domain.DockerHost; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 容器主机配置表 Mapper 接口 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +public interface DockerHostMapper extends BaseMapper { + +} diff --git a/src/main/java/com/mini/capi/biz/mapper/SshInfoMapper.java b/src/main/java/com/mini/capi/biz/mapper/SshInfoMapper.java new file mode 100644 index 0000000..cbc54d4 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/mapper/SshInfoMapper.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.mapper; + +import com.mini.capi.biz.domain.SshInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * SSH 服务器信息表 Mapper 接口 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +public interface SshInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/mini/capi/biz/mapper/SshUserMapper.java b/src/main/java/com/mini/capi/biz/mapper/SshUserMapper.java new file mode 100644 index 0000000..952dab1 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/mapper/SshUserMapper.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.mapper; + +import com.mini.capi.biz.domain.SshUser; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + *

+ * 用户密码表 Mapper 接口 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +public interface SshUserMapper extends BaseMapper { + +} diff --git a/src/main/java/com/mini/capi/biz/service/DockerContainerInfoService.java b/src/main/java/com/mini/capi/biz/service/DockerContainerInfoService.java new file mode 100644 index 0000000..f1b0224 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/DockerContainerInfoService.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.service; + +import com.mini.capi.biz.domain.DockerContainerInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 容器信息采集表 服务类 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +public interface DockerContainerInfoService extends IService { + +} diff --git a/src/main/java/com/mini/capi/biz/service/DockerHostService.java b/src/main/java/com/mini/capi/biz/service/DockerHostService.java new file mode 100644 index 0000000..125efc4 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/DockerHostService.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.service; + +import com.mini.capi.biz.domain.DockerHost; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 容器主机配置表 服务类 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +public interface DockerHostService extends IService { + +} diff --git a/src/main/java/com/mini/capi/biz/service/SshInfoService.java b/src/main/java/com/mini/capi/biz/service/SshInfoService.java new file mode 100644 index 0000000..2af2aa2 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/SshInfoService.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.service; + +import com.mini.capi.biz.domain.SshInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * SSH 服务器信息表 服务类 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +public interface SshInfoService extends IService { + +} diff --git a/src/main/java/com/mini/capi/biz/service/SshUserService.java b/src/main/java/com/mini/capi/biz/service/SshUserService.java new file mode 100644 index 0000000..b6557e7 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/SshUserService.java @@ -0,0 +1,16 @@ +package com.mini.capi.biz.service; + +import com.mini.capi.biz.domain.SshUser; +import com.baomidou.mybatisplus.extension.service.IService; + +/** + *

+ * 用户密码表 服务类 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +public interface SshUserService extends IService { + +} diff --git a/src/main/java/com/mini/capi/biz/service/impl/DockerContainerInfoServiceImpl.java b/src/main/java/com/mini/capi/biz/service/impl/DockerContainerInfoServiceImpl.java new file mode 100644 index 0000000..14a5911 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/impl/DockerContainerInfoServiceImpl.java @@ -0,0 +1,20 @@ +package com.mini.capi.biz.service.impl; + +import com.mini.capi.biz.domain.DockerContainerInfo; +import com.mini.capi.biz.mapper.DockerContainerInfoMapper; +import com.mini.capi.biz.service.DockerContainerInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 容器信息采集表 服务实现类 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@Service +public class DockerContainerInfoServiceImpl extends ServiceImpl implements DockerContainerInfoService { + +} diff --git a/src/main/java/com/mini/capi/biz/service/impl/DockerHostServiceImpl.java b/src/main/java/com/mini/capi/biz/service/impl/DockerHostServiceImpl.java new file mode 100644 index 0000000..dde9b35 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/impl/DockerHostServiceImpl.java @@ -0,0 +1,20 @@ +package com.mini.capi.biz.service.impl; + +import com.mini.capi.biz.domain.DockerHost; +import com.mini.capi.biz.mapper.DockerHostMapper; +import com.mini.capi.biz.service.DockerHostService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 容器主机配置表 服务实现类 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@Service +public class DockerHostServiceImpl extends ServiceImpl implements DockerHostService { + +} diff --git a/src/main/java/com/mini/capi/biz/service/impl/SshInfoServiceImpl.java b/src/main/java/com/mini/capi/biz/service/impl/SshInfoServiceImpl.java new file mode 100644 index 0000000..aed8e2b --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/impl/SshInfoServiceImpl.java @@ -0,0 +1,20 @@ +package com.mini.capi.biz.service.impl; + +import com.mini.capi.biz.domain.SshInfo; +import com.mini.capi.biz.mapper.SshInfoMapper; +import com.mini.capi.biz.service.SshInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * SSH 服务器信息表 服务实现类 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@Service +public class SshInfoServiceImpl extends ServiceImpl implements SshInfoService { + +} diff --git a/src/main/java/com/mini/capi/biz/service/impl/SshUserServiceImpl.java b/src/main/java/com/mini/capi/biz/service/impl/SshUserServiceImpl.java new file mode 100644 index 0000000..9389e02 --- /dev/null +++ b/src/main/java/com/mini/capi/biz/service/impl/SshUserServiceImpl.java @@ -0,0 +1,20 @@ +package com.mini.capi.biz.service.impl; + +import com.mini.capi.biz.domain.SshUser; +import com.mini.capi.biz.mapper.SshUserMapper; +import com.mini.capi.biz.service.SshUserService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +/** + *

+ * 用户密码表 服务实现类 + *

+ * + * @author gaoxq + * @since 2025-08-23 + */ +@Service +public class SshUserServiceImpl extends ServiceImpl implements SshUserService { + +} diff --git a/src/main/java/com/mini/capi/mybatis/demo.java b/src/main/java/com/mini/capi/mybatis/demo.java index a9122a3..80129c8 100644 --- a/src/main/java/com/mini/capi/mybatis/demo.java +++ b/src/main/java/com/mini/capi/mybatis/demo.java @@ -29,7 +29,7 @@ public class demo { .pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "/src/main/resources/mapper")); }) .strategyConfig(builder -> { - builder.addInclude("biz_combined_summary") + builder.addInclude("biz_docker_container_info,biz_docker_host") .addTablePrefix("biz_") .entityBuilder() .enableLombok() diff --git a/src/main/java/com/mini/capi/sys/controller/sysController.java b/src/main/java/com/mini/capi/sys/controller/sysController.java index 5e45def..784297e 100644 --- a/src/main/java/com/mini/capi/sys/controller/sysController.java +++ b/src/main/java/com/mini/capi/sys/controller/sysController.java @@ -1,7 +1,18 @@ package com.mini.capi.sys.controller; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.mini.capi.biz.domain.DockerContainerInfo; +import com.mini.capi.biz.domain.DockerHost; +import com.mini.capi.biz.domain.SshInfo; +import com.mini.capi.biz.domain.SshUser; +import com.mini.capi.biz.service.DockerContainerInfoService; +import com.mini.capi.biz.service.DockerHostService; +import com.mini.capi.biz.service.SshInfoService; +import com.mini.capi.biz.service.SshUserService; import com.mini.capi.model.ApiResult; import com.mini.capi.utils.HostRuntime; +import com.mini.capi.utils.docker; +import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -19,6 +30,18 @@ import java.util.stream.Collectors; public class sysController { + @Resource + private SshInfoService sshInfoService; + + @Resource + private SshUserService sshUserService; + + @Resource + private DockerHostService dockerHostService; + @Resource + private DockerContainerInfoService dockerInfoService; + + public static class SnapshotDTO { public String hostName; public String timestamp; @@ -116,4 +139,90 @@ public class sysController { return ApiResult.success(Collections.singletonList(SnapshotDTO.from(snap))); } + + @GetMapping("/getApiDockerInfo") + public ApiResult getDockerInfo(String dockerHostId) { + DockerHost host = dockerHostService.getById(dockerHostId); + try { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("doker_host_id", dockerHostId); + dockerInfoService.remove(wrapper); + SshUser sshUser = sshUserService.getById(host.getUserId()); + SshInfo sshInfo = sshInfoService.getById(host.getHostId()); + List list = docker.getDockerInfo(sshInfo.getHostIp(), Long.valueOf(sshInfo.getHostPort()), sshUser.getCUsername(), sshUser.getCPassword()); + for (docker.DockerInfo dockerInfo : list) { + DockerContainerInfo info = docker.getDockerContainerInfo(dockerHostId, dockerInfo, sshInfo); + dockerInfoService.save(info); + } + long count = list.stream() + .filter(d -> "1".equals(d.getStatus())) + .count(); + host.setRunNum(count); + dockerHostService.updateById(host); + return ApiResult.success(); + } catch (Exception e) { + return ApiResult.error(500, e.getMessage()); + } + } + + + /** + * 启动容器 + */ + @GetMapping("/getApiStartDockerInfo") + public ApiResult startDockerInfo(String id) { + DockerContainerInfo dockerContainerInfo = dockerInfoService.getById(id); + DockerHost host = dockerHostService.getById(dockerContainerInfo.getDokerHostId()); + try { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("doker_host_id", dockerContainerInfo.getDokerHostId()); + dockerInfoService.remove(wrapper); + SshUser sshUser = sshUserService.getById(host.getUserId()); + SshInfo sshInfo = sshInfoService.getById(host.getHostId()); + docker.startDocker(sshInfo.getHostIp(), Long.valueOf(sshInfo.getHostPort()), sshUser.getCUsername(), sshUser.getCPassword(), dockerContainerInfo.getContainerId()); + List list = docker.getDockerInfo(sshInfo.getHostIp(), Long.valueOf(sshInfo.getHostPort()), sshUser.getCUsername(), sshUser.getCPassword()); + for (docker.DockerInfo dockerInfo : list) { + DockerContainerInfo info = docker.getDockerContainerInfo(dockerContainerInfo.getDokerHostId(), dockerInfo, sshInfo); + dockerInfoService.save(info); + } + long count = list.stream() + .filter(d -> "1".equals(d.getStatus())) + .count(); + host.setRunNum(count); + dockerHostService.updateById(host); + return ApiResult.success(); + } catch (Exception e) { + return ApiResult.error(500, e.getMessage()); + } + } + + + @GetMapping("/getApiStopDockerInfo") + public ApiResult stopDockerInfo(String id) { + DockerContainerInfo dockerContainerInfo = dockerInfoService.getById(id); + DockerHost host = dockerHostService.getById(dockerContainerInfo.getDokerHostId()); + try { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("doker_host_id", dockerContainerInfo.getDokerHostId()); + dockerInfoService.remove(wrapper); + SshUser sshUser = sshUserService.getById(host.getUserId()); + SshInfo sshInfo = sshInfoService.getById(host.getHostId()); + docker.stopDocker(sshInfo.getHostIp(), Long.valueOf(sshInfo.getHostPort()), sshUser.getCUsername(), sshUser.getCPassword(), dockerContainerInfo.getContainerId()); + List list = docker.getDockerInfo(sshInfo.getHostIp(), Long.valueOf(sshInfo.getHostPort()), sshUser.getCUsername(), sshUser.getCPassword()); + for (docker.DockerInfo dockerInfo : list) { + DockerContainerInfo info = docker.getDockerContainerInfo(dockerContainerInfo.getDokerHostId(), dockerInfo, sshInfo); + dockerInfoService.save(info); + } + long count = list.stream() + .filter(d -> "1".equals(d.getStatus())) + .count(); + host.setRunNum(count); + dockerHostService.updateById(host); + return ApiResult.success(); + } catch (Exception e) { + return ApiResult.error(500, e.getMessage()); + } + } + + } diff --git a/src/main/java/com/mini/capi/utils/docker.java b/src/main/java/com/mini/capi/utils/docker.java new file mode 100644 index 0000000..8a93153 --- /dev/null +++ b/src/main/java/com/mini/capi/utils/docker.java @@ -0,0 +1,168 @@ +package com.mini.capi.utils; + +import com.jcraft.jsch.*; +import com.mini.capi.biz.domain.DockerContainerInfo; +import com.mini.capi.biz.domain.SshInfo; +import lombok.Data; + +import java.io.*; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class docker { + + @Data + public static class DockerInfo implements Serializable { + private String containerId; + private String imageName; + private String command; + private String createdAt; + private String status; + private String ports; + private String names; + + @Override + public String toString() { + return "DockerContainerInfo{" + + "containerId='" + containerId + '\'' + + ", imageName='" + imageName + '\'' + + ", command='" + command + '\'' + + ", createdAt='" + createdAt + '\'' + + ", status='" + status + '\'' + + ", ports='" + ports + '\'' + + ", names='" + names + '\'' + + '}'; + } + } + + public static List getDockerInfo(String host, Long port, String username, String password) { + List containers = new ArrayList<>(); + JSch jsch = new JSch(); + Session session = null; + try { + // 1. 创建SSH会话 + session = jsch.getSession(username, host, Math.toIntExact(port)); + session.setPassword(password); + session.setConfig("StrictHostKeyChecking", "no"); + session.connect(); + + // 2. 执行docker ps命令获取所有容器信息 + String command = "docker ps -a --no-trunc --format \"{{.ID}}|{{.Image}}|{{.Command}}|{{.CreatedAt}}|{{.Status}}|{{.Ports}}|{{.Names}}\""; + ChannelExec channel = (ChannelExec) session.openChannel("exec"); + channel.setCommand(command); + channel.setInputStream(null); + + InputStream in = channel.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + + channel.connect(); + + // 3. 解析输出 + String line; + while ((line = reader.readLine()) != null) { + if (!line.trim().isEmpty()) { + DockerInfo container = parseContainerInfo(line); + if (container != null) { + containers.add(container); + } + } + } + + channel.disconnect(); + } catch (JSchException | IOException e) { + System.out.println(e.getMessage()); + } finally { + if (session != null && session.isConnected()) { + session.disconnect(); + } + } + + return containers; + } + + private static DockerInfo parseContainerInfo(String line) { + // 使用正则表达式分割管道分隔的字段 + Pattern pattern = Pattern.compile("([^|]*)\\|([^|]*)\\|([^|]*)\\|([^|]*)\\|([^|]*)\\|([^|]*)\\|([^|]*)"); + Matcher matcher = pattern.matcher(line); + if (matcher.find()) { + DockerInfo container = new DockerInfo(); + container.setContainerId(matcher.group(1).trim()); + container.setImageName(matcher.group(2).trim()); + container.setCommand(matcher.group(3).trim()); + container.setCreatedAt(matcher.group(4).trim()); + container.setStatus(getStatus(matcher.group(5).trim())); + container.setPorts(matcher.group(6).trim()); + container.setNames(matcher.group(7).trim()); + return container; + } + return null; + } + + private static String dockerCommand(String host, Long port, String username, String password, String command) { + JSch jsch = new JSch(); + Session session = null; + ChannelExec channel = null; + // 读取输出 + StringBuilder output = new StringBuilder(); + try { + // 创建SSH会话 + session = jsch.getSession(username, host, Math.toIntExact(port)); + session.setPassword(password); + session.setConfig("StrictHostKeyChecking", "no"); + session.connect(); + // 执行Docker命令 + channel = (ChannelExec) session.openChannel("exec"); + channel.setCommand(command); + channel.setInputStream(null); + InputStream in = channel.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + channel.connect(); + String line; + while ((line = reader.readLine()) != null) { + output.append(line).append("\n"); + } + channel.disconnect(); + } catch (JSchException | IOException e) { + System.out.println(e.getMessage()); + } finally { + if (session != null && session.isConnected()) { + session.disconnect(); + } + } + return output.toString(); + } + + public static DockerContainerInfo getDockerContainerInfo(String dockerHostId, docker.DockerInfo dockerInfo, SshInfo sshInfo) { + DockerContainerInfo info = new DockerContainerInfo(); + info.setContainerId(dockerInfo.getContainerId()); + info.setImageName(dockerInfo.getImageName()); + info.setCreatedAt(dockerInfo.getCreatedAt()); + info.setUstatus(dockerInfo.getStatus()); + info.setPorts(dockerInfo.getPorts()); + info.setUnames(dockerInfo.getNames()); + info.setHostIp(sshInfo.getHostIp()); + info.setDokerHostId(dockerHostId); + info.setGetTime(vDate.getNow()); + info.setFTenantId("0"); + return info; + } + + + public static String startDocker(String host, Long port, String username, String password, String containerId) { + return dockerCommand(host, port, username, password, "docker start " + containerId); + } + + public static String stopDocker(String host, Long port, String username, String password, String containerId) { + return dockerCommand(host, port, username, password, "docker stop " + containerId); + } + + private static String getStatus(String start) { + if (start.toUpperCase().startsWith("UP")) { + return "1"; + } + return "0"; + } +} diff --git a/src/main/java/com/mini/capi/utils/vDate.java b/src/main/java/com/mini/capi/utils/vDate.java new file mode 100644 index 0000000..16645b5 --- /dev/null +++ b/src/main/java/com/mini/capi/utils/vDate.java @@ -0,0 +1,35 @@ +package com.mini.capi.utils; + + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +public class vDate { + + + private static final DateTimeFormatter DEFAULT_FMT = + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + private static final SimpleDateFormat DEFAULT_SDF = + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public static String toStr(LocalDateTime dateTime) { + return dateTime.format(DEFAULT_FMT); + } + + /** + * LocalDateTime → String(自定义格式) + */ + public static String toStr(LocalDateTime dateTime, String pattern) { + return dateTime.format(DateTimeFormatter.ofPattern(pattern)); + } + + + public static String getNow() { + Date date = new Date(); + return DEFAULT_SDF.format(date); + } + +} diff --git a/src/main/resources/mapper/DockerContainerInfoMapper.xml b/src/main/resources/mapper/DockerContainerInfoMapper.xml new file mode 100644 index 0000000..54f35f2 --- /dev/null +++ b/src/main/resources/mapper/DockerContainerInfoMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + get_time, id, container_id, image_name, command, created_at, status, ports, names, host_ip, sys_name, user_id + + + diff --git a/src/main/resources/mapper/DockerHostMapper.xml b/src/main/resources/mapper/DockerHostMapper.xml new file mode 100644 index 0000000..2af6890 --- /dev/null +++ b/src/main/resources/mapper/DockerHostMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + create_time, doker_host_id, user_id, host_id, host_ip, all_num, run_num, remark, f_tenant_id, f_flow_id, f_flow_task_id, f_flow_state + + + diff --git a/src/main/resources/mapper/SshInfoMapper.xml b/src/main/resources/mapper/SshInfoMapper.xml new file mode 100644 index 0000000..d8f141a --- /dev/null +++ b/src/main/resources/mapper/SshInfoMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + create_time, host_id, host_ip, host_port, remark, update_time, f_tenant_id, f_flow_id, f_flow_task_id, f_flow_state + + + diff --git a/src/main/resources/mapper/SshUserMapper.xml b/src/main/resources/mapper/SshUserMapper.xml new file mode 100644 index 0000000..194806c --- /dev/null +++ b/src/main/resources/mapper/SshUserMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + create_time, user_id, sys_name, c_username, c_password, c_url, host_id, update_time, remark, f_tenant_id + + +