diff --git a/modules/module-ci-machine/pom.xml b/modules/module-ci-machine/pom.xml new file mode 100644 index 00000000..e36adc39 --- /dev/null +++ b/modules/module-ci-machine/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + cd.casic.boot + modules + ${revision} + + + module-ci-machine + + jar + ${revision} + ${project.artifactId} + + + + cd.casic.boot + commons + + + + cd.casic.boot + spring-boot-starter-security + + + com.antherd + sm-crypto + 0.3.2.1-RELEASE + + + diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/contants/MachineErrorCodeConstants.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/contants/MachineErrorCodeConstants.java new file mode 100644 index 00000000..a526d9e5 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/contants/MachineErrorCodeConstants.java @@ -0,0 +1,37 @@ +package cd.casic.module.machine.contants; + +import cd.casic.framework.commons.exception.ErrorCode; + +/** + * 机器报错 + */ +public interface MachineErrorCodeConstants { + // ========== 机器基础信息模块 1-003-000-000 ========== + ErrorCode MACHINE_INFO_NULL = new ErrorCode(1_003_000_000, "机器信息为空"); + ErrorCode MACHINE_INFO_HOST_IP_NULL = new ErrorCode(1_003_000_001, "机器主机IP为空"); + ErrorCode MACHINE_INFO_USER_NAME_NULL = new ErrorCode(1_003_000_002, "机器用户名为空"); + ErrorCode MACHINE_INFO_TYPE_NULL = new ErrorCode(1_003_000_003, "机器类型为空"); + ErrorCode MACHINE_INFO_TYPE_NOT_EXISTS = new ErrorCode(1_003_000_004, "机器类型不存在"); + ErrorCode MACHINE_INFO_TAG_NULL = new ErrorCode(1_003_000_005, "机器唯一标识为空"); + ErrorCode MACHINE_INFO_TAG_EXISTS = new ErrorCode(1_003_000_006, "机器唯一标识已存在"); + ErrorCode MACHINE_INFO_AUTHENTICATION_TYPE_NULL = new ErrorCode(1_003_000_007, "机器认证类型为空"); + ErrorCode MACHINE_INFO_AUTHENTICATION_TYPE_NOT_EXISTS = new ErrorCode(1_003_000_008, "机器认证类型不存在"); + ErrorCode MACHINE_ENABLE = new ErrorCode(1_003_000_009, "机器启用中"); + + // ========== 机器环境变量模块 1-003-002-000 ========== + ErrorCode MACHINE_ENV_NULL = new ErrorCode(1_003_002_000, "机器环境变量为空"); + ErrorCode MACHINE_ENV_NOT_EXISTS = new ErrorCode(1_003_002_001, "机器不存在"); + ErrorCode MACHINE_ENV_KEY_ILLEGAL = new ErrorCode(1_003_002_002, "机器环境变量键不合法"); + + // ========== 机器代理模块 1-003-003-000 ========== + ErrorCode MACHINE_PROXY_HOST_IP_NULL = new ErrorCode(1_003_003_000, "机器代理主机地址为空"); + ErrorCode MACHINE_PROXY_USER_NAME_NULL = new ErrorCode(1_003_003_001, "机器代理用户名为空"); + ErrorCode MACHINE_PROXY_NOT_EXISTS = new ErrorCode(1_003_003_002, "机器代理不存在"); + ErrorCode MACHINE_PROXY_TYPE_NOT_EXISTS = new ErrorCode(1_003_003_003, "机器代理类型不存在"); + ErrorCode MACHINE_PROXY_IS_ONLINE = new ErrorCode(1_003_003_004, "机器代理在线,不能删除"); + + // ========== 密钥模块 1-003-004-000 ========== + ErrorCode SECRET_KEY_NULL = new ErrorCode(1_003_004_000, "密钥为空"); + ErrorCode SECRET_KEY_NOT_EXISTS = new ErrorCode(1_003_004_001, "密钥不存在"); + ErrorCode ENCRYPT_OR_DECRYPT_FAIL = new ErrorCode(1_003_004_002, "加密/解密失败"); +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineEnvController.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineEnvController.java new file mode 100644 index 00000000..d7ca1c20 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineEnvController.java @@ -0,0 +1,84 @@ +package cd.casic.module.machine.controller; + +import cd.casic.framework.commons.pojo.CommonResult; +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.commons.util.object.BeanUtils; +import cd.casic.module.machine.dal.dataobject.MachineEnvDO; +import cd.casic.module.machine.service.MachineEnvService; +import cd.casic.module.machine.controller.vo.MachineEnvVO; +import cn.hutool.core.collection.CollUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import static cd.casic.framework.commons.pojo.CommonResult.success; + +/** + * 环境变量控制器 + */ +@Tag(name = "环境变量管理") +@RestController +@RequestMapping("/ci/machineEnv") +@Validated +public class MachineEnvController { + + @Resource + private MachineEnvService machineEnvService; + + @PostMapping("/create") + @Operation(summary = "新增环境变量") + @PreAuthorize("@ss.hasPermission('ci:machineEnv:create')") + public CommonResult createEnv(@Valid @RequestBody MachineEnvVO machineEnvVO) { + Long id = machineEnvService.createEnv(machineEnvVO); + return success(id); + } + + @PutMapping("/update") + @Operation(summary = "修改环境变量") + @PreAuthorize("@ss.hasPermission('ci:machineEnv:update')") + public CommonResult updateEnv(@Valid @RequestBody MachineEnvVO machineEnvVO) { + machineEnvService.updateEnv(machineEnvVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除机器的环境变量") + @PreAuthorize("@ss.hasPermission('ci:machineEnv:delete')") + public CommonResult deleteEnv(@RequestParam("id") Long id) { + machineEnvService.deleteEnv(id); + return success(true); + } + + @DeleteMapping("/deleteList") + @Operation(summary = "批量删除机器环境变量") + @PreAuthorize("@ss.hasPermission('ci:machineEnv:delete')") + public CommonResult deleteEnvList(@RequestParam("ids") String ids) { + machineEnvService.deleteEnvList(ids); + return success(true); + } + + @GetMapping("/getEnv") + @Operation(summary = "获取机器的环境变量") + public CommonResult getEnv(@RequestParam("id") Long id) { + MachineEnvVO machineEnvVO = machineEnvService.getEnv(id); + return success(machineEnvVO); + } + + + @PostMapping("/list") + @Operation(summary = "获取环境变量列表") + public CommonResult> getEnvPage(@Valid @RequestBody MachineEnvVO machineEnvVO) { + PageResult pageResult = machineEnvService.getEnvPage(machineEnvVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(new PageResult<>(pageResult.getTotal())); + } + return success(BeanUtils.toBean(pageResult, MachineEnvVO.class)); + } +} + 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 new file mode 100644 index 00000000..e0abd893 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineInfoController.java @@ -0,0 +1,83 @@ +package cd.casic.module.machine.controller; + +import cd.casic.framework.commons.pojo.CommonResult; +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.commons.util.object.BeanUtils; +import cd.casic.module.machine.controller.vo.SecretKeyVO; +import cd.casic.module.machine.dal.dataobject.MachineInfoDO; +import cd.casic.module.machine.service.MachineInfoService; +import cd.casic.module.machine.controller.vo.MachineInfoVO; +import cn.hutool.core.collection.CollUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import static cd.casic.framework.commons.pojo.CommonResult.success; + +@RestController +@Tag(name = "机器信息管理") +@RequestMapping("/ci/machineInfo") +@Validated +public class MachineInfoController { + @Resource + private MachineInfoService machineInfoService; + + @PostMapping("/create") + @Operation(summary = "新增机器信息") +// @PreAuthorize("@ss.hasPermission('ci:machineInfo:create')") + public CommonResult createMachine(@Valid @RequestBody MachineInfoVO machineInfoVO) { + Long id = machineInfoService.createMachine(machineInfoVO); + return success(id); + } + + @PutMapping("/update") + @Operation(summary = "编辑机器信息") +// @PreAuthorize("@ss.hasPermission('ci:machineInfo:update')") + public CommonResult updateMachineInfo(@Valid @RequestBody MachineInfoVO machineInfoVO) { + machineInfoService.updateMachineInfo(machineInfoVO); + return success(true); + } + + @PutMapping("/updateStatus") + @Operation(summary = "机器启用/停用") +// @PreAuthorize("@ss.hasPermission('ci:machineInfo:status')") + public CommonResult updateStatus(@Valid @RequestBody MachineInfoVO machineInfoVO) { + Integer newStatus = machineInfoService.updateStatus(machineInfoVO); + return success(newStatus); + } + + @PostMapping("/list") + @Operation(summary = "获取机器信息列表") + public CommonResult> list(@Valid @RequestBody MachineInfoVO machineInfoVO) { + PageResult pageResult = machineInfoService.listMachineInfo(machineInfoVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(new PageResult<>(pageResult.getTotal())); + } + return success(BeanUtils.toBean(pageResult, MachineInfoVO.class)); + } + + @DeleteMapping("/delete") + @Operation(summary = "机器信息删除") +// @PreAuthorize("@ss.hasPermission('ci:machineInfo:delete')") + public CommonResult deleteMachineInfo(@RequestParam("machineInfoId") Long machineInfoId) { + machineInfoService.deleteMachineInfo(machineInfoId); + return success(true); + } + + @DeleteMapping("/deleteList") + @Operation(summary = "批量删除机器信息") +// @PreAuthorize("@ss.hasPermission('ci:machineInfo:delete')") + public CommonResult deleteMachineInfoList(@RequestParam("machineInfoIds") String ids) { + machineInfoService.deleteMachineInfoList(ids); + return success(true); + } + + @PutMapping("/bindingSecretKey") + @Operation(summary = "绑定/解绑密钥") + public void bindingSecretKey(@RequestBody SecretKeyVO secretKeyVO) { + machineInfoService.bindingSecretKey(secretKeyVO); + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineProxyController.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineProxyController.java new file mode 100644 index 00000000..83082ee5 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/MachineProxyController.java @@ -0,0 +1,81 @@ +package cd.casic.module.machine.controller; + +import cd.casic.framework.commons.pojo.CommonResult; +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.commons.util.object.BeanUtils; +import cd.casic.module.machine.controller.vo.MachineProxyVO; +import cd.casic.module.machine.dal.dataobject.MachineProxyDO; +import cd.casic.module.machine.service.MachineProxyService; +import cn.hutool.core.collection.CollUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +import static cd.casic.framework.commons.pojo.CommonResult.success; + +/** + * 机器代理控制器 + */ +@RestController +@RequestMapping("/ci/machineProxy") +@Tag(name = "机器代理管理") +@Validated +public class MachineProxyController { + + @Resource + private MachineProxyService machineProxyService; + + @PostMapping("/create") + @Operation(summary = "注册新的机器代理") +// @PreAuthorize("@ss.hasPermission('ci:machineProxy:create')") + public CommonResult createProxy(@Valid @RequestBody MachineProxyVO machineProxyVO) { + Long id = machineProxyService.createProxy(machineProxyVO); + return success(id); + } + + @PutMapping("/update") + @Operation(summary = "修改代理") +// @PreAuthorize("@ss.hasPermission('ci:machineProxy:update')") + public CommonResult updateProxy(@Valid @RequestBody MachineProxyVO machineProxyVO) { + machineProxyService.updateProxy(machineProxyVO); + return success(true); + } + + @PostMapping("/list") + @Operation(summary = "获取代理列表") + public CommonResult> getProxyPage(@Valid @RequestBody MachineProxyVO machineProxyVO) { + PageResult pageResult = machineProxyService.getProxyPage(machineProxyVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(new PageResult<>(pageResult.getTotal())); + } + return success(BeanUtils.toBean(pageResult, MachineProxyVO.class)); + } + + @GetMapping("/allStatus") + @Operation(summary = "获取所有代理的状态统计") + public CommonResult> getStatusStatistics() { + return success(machineProxyService.getAllProxyStatus()); + } + + @DeleteMapping("delete") + @Operation(summary = "删除代理") + public CommonResult delete(@RequestParam("id") Long id) { + machineProxyService.delete(id); + return success(true); + } + + @DeleteMapping("/deleteList") + @Operation(summary = "批量删除代理") +// @PreAuthorize("@ss.hasPermission('ci:machineProxy:delete')") + public CommonResult deleteProxyList(@RequestParam String ids) { + machineProxyService.deleteProxyList(ids); + return success(true); + } + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/SecretKeyController.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/SecretKeyController.java new file mode 100644 index 00000000..1624b1c2 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/SecretKeyController.java @@ -0,0 +1,76 @@ +package cd.casic.module.machine.controller; + +import cd.casic.framework.commons.pojo.CommonResult; +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.commons.util.object.BeanUtils; +import cd.casic.module.machine.dal.dataobject.MachineInfoDO; +import cd.casic.module.machine.dal.dataobject.SecretKeyDO; +import cd.casic.module.machine.service.SecretKeyService; +import cd.casic.module.machine.controller.vo.SecretKeyVO; +import cn.hutool.core.collection.CollUtil; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static cd.casic.framework.commons.pojo.CommonResult.success; + +@RestController +@RequestMapping("/ci/secretKey") +@Tag(name = "密钥管理") +@Validated +public class SecretKeyController { + @Resource + private SecretKeyService secretKeyService; + + @PostMapping(value = "/create") + @Operation(summary = "新增密钥") +// @PreAuthorize("@ss.hasPermission('ci:secretKey:create')") + public CommonResult createSecretKey(@Valid @RequestBody SecretKeyVO secretKeyVO) { + Long secretKeyId = secretKeyService.createSecretKey(secretKeyVO); + return success(secretKeyId); + } + + @PutMapping("/update") + @Operation(summary = "编辑密钥信息") +// @PreAuthorize("@ss.hasPermission('ci:secretKey:update')") + public CommonResult updateSecretKey(@Valid @RequestBody SecretKeyVO secretKeyVO) { + secretKeyService.updateSecretKey(secretKeyVO); + return success(true); + } + + @GetMapping("/getBindMachine") + @Operation(summary = "获取密钥绑定的机器列表") + public CommonResult> getBindMachine(@RequestParam Long secretKeyId) { + return success(secretKeyService.getBindMachine(secretKeyId)); + } + + @GetMapping("/getSecretKey") + @Operation(summary = "获取机器的密钥") + public CommonResult getSecretKey(@RequestParam("id") Long id) { + SecretKeyVO secretKeyVO = secretKeyService.getSecretKey(id); + return success(secretKeyVO); + } + + @DeleteMapping("/deleteList") + @Operation(summary = "批量删除密钥") +// @PreAuthorize("@ss.hasPermission('ci:secretKey:delete')") + public CommonResult deleteSecretKeyList(@RequestParam("ids") List ids) { + secretKeyService.deleteSecretKeyList(ids); + return success(true); + } + + @PostMapping("/list") + @Operation(summary = "获取密钥信息列表") + public CommonResult> getSecretKeyPage(@Valid @RequestBody SecretKeyVO secretKeyVO) { + PageResult pageResult = secretKeyService.getSecretKeyPage(secretKeyVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(new PageResult<>(pageResult.getTotal())); + } + return success(BeanUtils.toBean(pageResult, SecretKeyVO.class)); + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineEnvVO.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineEnvVO.java new file mode 100644 index 00000000..16ae6eef --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineEnvVO.java @@ -0,0 +1,38 @@ +package cd.casic.module.machine.controller.vo; + +import cd.casic.framework.commons.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +@EqualsAndHashCode(callSuper = true) +@Schema(description = "管理后台 - 机器环境变量信息 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) // 添加链式调用支持 +public class MachineEnvVO extends PageParam { + + @Schema(description = "环境变量ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "环境变量键", requiredMode = Schema.RequiredMode.REQUIRED, example = "JAVA_HOME") + private String envKey; + + @Schema(description = "环境变量值", requiredMode = Schema.RequiredMode.REQUIRED, example = "/usr/java/jdk1.8.0_271") + private String envValue; + + @Schema(description = "环境变量描述", example = "Java运行环境路径") + private String description; + + @Schema(description = "关联的机器ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long machineId; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-06-15T10:30:00") + private LocalDateTime createTime; + + @Schema(description = "更新时间", example = "2023-06-15T10:30:00") + private LocalDateTime updateTime; +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineInfoVO.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineInfoVO.java new file mode 100644 index 00000000..beb64176 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineInfoVO.java @@ -0,0 +1,64 @@ +package cd.casic.module.machine.controller.vo; + +import cd.casic.framework.commons.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import lombok.experimental.Accessors; + +import java.util.Date; + +@EqualsAndHashCode(callSuper = true) +@Schema(description = "管理后台 - 机器信息 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class MachineInfoVO extends PageParam { + + @Schema(description = "机器ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-06-15T10:30:00") + private Date createTime; + + @Schema(description = "更新时间", example = "2023-06-15T10:30:00") + private Date updateTime; + + @Schema(description = "机器名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "server-01") + private String name; + + @Schema(description = "机器标签,唯一标识", example = "production,web-server") + private String tag; + + @Schema(description = "主机IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.100") + private String hostIp; + + @Schema(description = "机器描述", example = "生产环境Web服务器") + private String description; + + @Schema(description = "登录用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin") + private String username; + + @Schema(description = "机器状态", example = "online,offline,maintenance") + private Integer status = -1; + + @Schema(description = "SSH端口", example = "22") + private Integer sshPort; + + @Schema(description = "登录密码", example = "******") + private String password; + + @Schema(description = "密钥ID", example = "5") + private Long secretKeyId; + + @Schema(description = "代理ID", example = "101") + private Long machineProxyId; + + @Schema(description = "认证类型", example = "password,key") + private Integer authenticationType ; + + @Schema(description = "机器信息类型", example = "Linux,Windows") + private Integer machineInfoType; + + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineProxyVO.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineProxyVO.java new file mode 100644 index 00000000..f8f75259 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/MachineProxyVO.java @@ -0,0 +1,52 @@ +package cd.casic.module.machine.controller.vo; + +import cd.casic.framework.commons.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 机器代理信息 Response VO") +@EqualsAndHashCode(callSuper = true) +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class MachineProxyVO extends PageParam { + + @Schema(description = "代理ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin") + private String username; + + @Schema(description = "代理类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "HTTP") + private Integer proxyType = -1; + + @Schema(description = "版本号", example = "1.0.0") + private String version; + + @Schema(description = "状态(ONLINE:在线,OFFLINE:离线)", requiredMode = Schema.RequiredMode.REQUIRED, example = "ONLINE") + private int status = -1; + + @Schema(description = "描述信息", example = "用于生产环境的代理服务器") + private String description; + + @Schema(description = "主机IP", requiredMode = Schema.RequiredMode.REQUIRED, example = "192.168.1.100") + private String hostIp; + + @Schema(description = "SSH端口", requiredMode = Schema.RequiredMode.REQUIRED, example = "22") + private String sshPort; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-06-15T10:30:00") + private LocalDateTime createTime; + + @Schema(description = "更新时间", example = "2023-06-15T10:30:00") + private LocalDateTime updateTime; + + @Schema(description = "密码", example = "******") + private String password; + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/SecretKeyVO.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/SecretKeyVO.java new file mode 100644 index 00000000..00f7171a --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/controller/vo/SecretKeyVO.java @@ -0,0 +1,48 @@ +package cd.casic.module.machine.controller.vo; + +import cd.casic.framework.commons.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; +import java.util.List; + +@EqualsAndHashCode(callSuper = true) +@Schema(description = "管理后台 - 密钥信息 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) // 添加链式调用支持 +public class SecretKeyVO extends PageParam { + + @Schema(description = "密钥ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long id; + + @Schema(description = "密钥名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "生产环境密钥") + private String name; + + @Schema(description = "密钥描述", example = "用于加密敏感数据的密钥") + private String description; + + @Schema(description = "密钥密码", example = "******") + private String password; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-06-15T10:30:00") + private LocalDateTime createTime; + + @Schema(description = "更新时间", example = "2023-06-15T10:30:00") + private LocalDateTime updateTime; + + @Schema(description = "关联的机器ID列表", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1024, 2048]") + private List machineInfoIds; + + @Schema(description = "私钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "******") + private String privateKey; + + @Schema(description = "公钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "******") + private String publicKey; + + @Schema(description = "绑定/解绑密钥",example = "true") + private Boolean enableBind; +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineEnvDO.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineEnvDO.java new file mode 100644 index 00000000..be0abc80 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineEnvDO.java @@ -0,0 +1,57 @@ +package cd.casic.module.machine.dal.dataobject; + + +import cd.casic.framework.commons.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.*; +import lombok.*; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * 环境变量实体类 + */ + +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("machine_env") +public class MachineEnvDO extends BaseDO { + + + /** + * 环境变量id + */ + @TableId + private Long id; + + /** + * 机器ID(唯一关联) + */ + private Long machineId; + + /** + * 环境变量键 + */ + private String envKey; + + /** + * 环境变量值 + */ + private String envValue; + + + /** + * 描述信息 + */ + private String description; + + +} + + + + diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineInfoDO.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineInfoDO.java new file mode 100644 index 00000000..3471d23f --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineInfoDO.java @@ -0,0 +1,71 @@ +package cd.casic.module.machine.dal.dataobject; + +import cd.casic.framework.commons.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + + +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +@TableName(value = "machine_info") +public class MachineInfoDO extends BaseDO { + + /** + * 机器id + */ + @TableId + private Long id; + + + @TableField(value = "name") + private String name; + + /** + * 机器唯一标识 + */ + @TableField(value = "tag") + private String tag; + + @TableField(value = "host_ip") + private String hostIp; + + @TableField(value = "description") + private String description; + + //1:Linux 2:Windows + @TableField(value = "machine_info_type") + private Integer machineInfoType; + + // 1:启用 0:停用 + @TableField(value = "status") + private Integer status; + + //用户名 + @TableField(value = "username") + private String username; + + //SSH端口号 + @TableField(value = "ssh_port") + private Integer sshPort; + + @TableField(value = "password") + private String password; + + @TableField(value = "secret_key_id") + private Long secretKeyId; + + @TableField(value = "machine_proxy_id") + private Long machineProxyId; + + //1:密码认证 2:密钥认证 + @TableField(value = "authentication_type") + private Integer authenticationType; + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineProxyDO.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineProxyDO.java new file mode 100644 index 00000000..44008bfa --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/MachineProxyDO.java @@ -0,0 +1,56 @@ +package cd.casic.module.machine.dal.dataobject; + +import cd.casic.framework.commons.dataobject.BaseDO; +import cd.casic.module.machine.enums.MachineProxyStatus; +import com.baomidou.mybatisplus.annotation.*; +import cd.casic.module.machine.enums.MachineProxyType; +import lombok.*; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + * 机器代理实体类 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TableName("machine_proxy") +public class MachineProxyDO extends BaseDO { + + /** + * 代理id + */ + @TableId + private Long id; + + @TableField(value = "host_ip") + private String hostIp; + + @TableField(value = "ssh_port") + private String sshPort; + + @TableField(value = "proxy_type") + private int proxyType; + + @TableField(value = "version") + private String version; + + @TableField(value = "status") + private int status; + + @TableField(value = "username") + private String username; + + @TableField(value = "password") + private String password; + + @TableField(value = "description") + private String description; + + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/SecretKeyDO.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/SecretKeyDO.java new file mode 100644 index 00000000..cc271b50 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/dataobject/SecretKeyDO.java @@ -0,0 +1,44 @@ +package cd.casic.module.machine.dal.dataobject; + +import cd.casic.framework.commons.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@EqualsAndHashCode(callSuper = true) +@Data +@AllArgsConstructor +@NoArgsConstructor +@TableName(value = "machine_secret_key") +public class SecretKeyDO extends BaseDO { + + /** + * 密钥id + */ + @TableId + private Long id; + + @TableField(value = "name") + private String name; + + @TableField(value = "description") + private String description; + + + //密钥密码 + @TableField(value = "password") + private String password; + +// @TableField(value = "public_key") + private String publicKey; + + +// @TableField(value = "private_key") + private String privateKey; + + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/model/Keypair.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/model/Keypair.java new file mode 100644 index 00000000..3a58737a --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/model/Keypair.java @@ -0,0 +1,26 @@ +package cd.casic.module.machine.dal.model; + +/** + * 基于SM2的秘钥对 + * (本项目中配置的,自己使用可根据自己的需求进行更换) + * + */ +public class Keypair { + + /** + * 公钥 + */ + public static String PUBLIC_KEY = "04298364ec840088475eae92a591e01284d1abefcda348b47eb324bb521bb03b0b2a5bc393f6b71dabb8f15c99a0050818b56b23f31743b93df9cf8948f15ddb54"; + + /** + * 私钥 + */ + public static String PRIVATE_KEY = "3037723d47292171677ec8bd7dc9af696c7472bc5f251b2cec07e65fdef22e25"; + + /** + * SM4的对称秘钥(生产环境需要改成自己使用的) + * 16 进制字符串,要求为 128 比特 + */ + public static String KEY = "0123456789abcdeffedcba9876543210"; + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineEnvMapper.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineEnvMapper.java new file mode 100644 index 00000000..b5060c25 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineEnvMapper.java @@ -0,0 +1,27 @@ +package cd.casic.module.machine.dal.mysql; + +import cd.casic.framework.mybatis.core.mapper.BaseMapperX; +import cd.casic.module.machine.controller.vo.MachineEnvVO; +import cd.casic.module.machine.dal.dataobject.MachineEnvDO; +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.mybatis.core.query.LambdaQueryWrapperX; +import org.apache.ibatis.annotations.Mapper; + +import java.time.LocalDateTime; + +/** + * 环境变量Mapper接口 + */ +@Mapper +public interface MachineEnvMapper extends BaseMapperX { + default PageResult selectPage(MachineEnvVO machineEnvVO) { + LambdaQueryWrapperX machineEnvDOLambdaQueryWrapperX = new LambdaQueryWrapperX() + .likeIfPresent(MachineEnvDO::getEnvKey, machineEnvVO.getEnvKey()) + .likeIfPresent(MachineEnvDO::getDescription, machineEnvVO.getDescription()); + if (machineEnvVO.getMachineId() != null && machineEnvVO.getMachineId() > 0) { + machineEnvDOLambdaQueryWrapperX.eqIfPresent(MachineEnvDO::getMachineId, machineEnvVO.getMachineId()); + } + return selectPage(machineEnvVO, machineEnvDOLambdaQueryWrapperX); + } + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineInfoMapper.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineInfoMapper.java new file mode 100644 index 00000000..1f3f2013 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineInfoMapper.java @@ -0,0 +1,56 @@ +package cd.casic.module.machine.dal.mysql; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.mybatis.core.mapper.BaseMapperX; +import cd.casic.framework.mybatis.core.query.LambdaQueryWrapperX; +import cd.casic.module.machine.controller.vo.MachineInfoVO; +import cd.casic.module.machine.dal.dataobject.MachineInfoDO; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface MachineInfoMapper extends BaseMapperX { + default Boolean existsByTag(String tag) { + return selectOne(new QueryWrapper().eq("tag", tag)) != null; + } + + default void updateStatus(Long machineInfoId, Integer status) { + UpdateWrapper set = new UpdateWrapper<>(); + set.eq("id", machineInfoId).set("status", status); + this.update(null, set); + } + + default void bindingSecretKey(List machineInfoIds, Long secretKeyId,Boolean enableBind) { + UpdateWrapper wrapper = new UpdateWrapper<>(); + wrapper.in("id", machineInfoIds); + if (enableBind){ + wrapper.set("secret_key_id", secretKeyId);// 匹配 ID 集合 + }else { + wrapper.set("secret_key_id", null); + } + this.update(null, wrapper); + } + + default PageResult selectPage(MachineInfoVO machineInfoVO) { + LambdaQueryWrapperX machineInfoDOLambdaQueryWrapperX = new LambdaQueryWrapperX() + .likeIfPresent(MachineInfoDO::getName, machineInfoVO.getName()) + .likeIfPresent(MachineInfoDO::getTag, machineInfoVO.getTag()) + .likeIfPresent(MachineInfoDO::getDescription, machineInfoVO.getDescription()) + .likeIfPresent(MachineInfoDO::getUsername, machineInfoVO.getUsername()) + .likeIfPresent(MachineInfoDO::getHostIp, machineInfoVO.getHostIp()); + if (machineInfoVO.getStatus() != -1) { + machineInfoDOLambdaQueryWrapperX.eqIfPresent(MachineInfoDO::getStatus, machineInfoVO.getStatus()); + } + return selectPage(machineInfoVO, machineInfoDOLambdaQueryWrapperX); + } + + default List selectBindMachineBySecretKey(Long secretKeyId) { + LambdaQueryWrapperX lambdaQueryWrapperX = new LambdaQueryWrapperX() + .eq(MachineInfoDO::getSecretKeyId, secretKeyId); + return selectList(lambdaQueryWrapperX); + } + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineProxyMapper.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineProxyMapper.java new file mode 100644 index 00000000..05e4df4a --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/MachineProxyMapper.java @@ -0,0 +1,29 @@ +package cd.casic.module.machine.dal.mysql; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.mybatis.core.mapper.BaseMapperX; +import cd.casic.framework.mybatis.core.query.LambdaQueryWrapperX; +import cd.casic.module.machine.controller.vo.MachineProxyVO; +import cd.casic.module.machine.dal.dataobject.MachineProxyDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 机器代理Mapper接口 + */ +@Mapper +public interface MachineProxyMapper extends BaseMapperX { + + default PageResult selectPage(MachineProxyVO machineProxyVO) { + LambdaQueryWrapperX machineProxyDOLambdaQueryWrapperX = new LambdaQueryWrapperX() + .eqIfPresent(MachineProxyDO::getHostIp, machineProxyVO.getHostIp()) + .likeIfPresent(MachineProxyDO::getDescription, machineProxyVO.getDescription()); + if (machineProxyVO.getStatus() != -1) { + machineProxyDOLambdaQueryWrapperX.eqIfPresent(MachineProxyDO::getStatus, machineProxyVO.getStatus()); + } + if (machineProxyVO.getProxyType() != -1) { + machineProxyDOLambdaQueryWrapperX.eqIfPresent(MachineProxyDO::getProxyType, machineProxyVO.getProxyType()); + } + return selectPage(machineProxyVO, machineProxyDOLambdaQueryWrapperX); + } + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/SecretKeyMapper.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/SecretKeyMapper.java new file mode 100644 index 00000000..bb530946 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/dal/mysql/SecretKeyMapper.java @@ -0,0 +1,18 @@ +package cd.casic.module.machine.dal.mysql; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.mybatis.core.mapper.BaseMapperX; +import cd.casic.framework.mybatis.core.query.LambdaQueryWrapperX; +import cd.casic.module.machine.controller.vo.SecretKeyVO; +import cd.casic.module.machine.dal.dataobject.SecretKeyDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SecretKeyMapper extends BaseMapperX { + //查询列表 + default PageResult selectPage(SecretKeyVO secretKeyVO) { + return selectPage(secretKeyVO, new LambdaQueryWrapperX() + .likeIfPresent(SecretKeyDO::getName, secretKeyVO.getName()) + .likeIfPresent(SecretKeyDO::getDescription, secretKeyVO.getDescription())); + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/AuthenticationType.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/AuthenticationType.java new file mode 100644 index 00000000..71f8314c --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/AuthenticationType.java @@ -0,0 +1,25 @@ +package cd.casic.module.machine.enums; + + +import cd.casic.framework.commons.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum AuthenticationType implements IntArrayValuable { + PASSWORD(1,"密码认证"), + SECRET_KEY(2,"密钥认证"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AuthenticationType::getCode).toArray(); + private final int code; + + private final String message; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineInfoStatus.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineInfoStatus.java new file mode 100644 index 00000000..d0ddd5b1 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineInfoStatus.java @@ -0,0 +1,24 @@ +package cd.casic.module.machine.enums; + + +import cd.casic.framework.commons.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum MachineInfoStatus implements IntArrayValuable { + ENABLE(1, "启用"), + UN_ENABLE(0, "停用"); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MachineInfoStatus::getCode).toArray(); + private final int code; + + private final String message; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineInfoType.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineInfoType.java new file mode 100644 index 00000000..2a168b31 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineInfoType.java @@ -0,0 +1,24 @@ +package cd.casic.module.machine.enums; + + +import cd.casic.framework.commons.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum MachineInfoType implements IntArrayValuable { + Linux(1,"Linux"), + WINDOWS(2,"Windows"); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MachineInfoType::getCode).toArray(); + private final int code; + + private final String message; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineProxyStatus.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineProxyStatus.java new file mode 100644 index 00000000..e162c82a --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineProxyStatus.java @@ -0,0 +1,33 @@ +package cd.casic.module.machine.enums; + + +import cd.casic.framework.commons.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; + +@Getter +@AllArgsConstructor +public enum MachineProxyStatus implements IntArrayValuable { + /** + * 代理状态 (online, offline, installing, updating, error) + */ + ONLINE(1, "online"), + OFFLINE(2, "offline"), + INSTALLING(3, "installing"), + UPDATING(4, "updating"), + ERROR(5, "error"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MachineProxyStatus::getCode).toArray(); + + private final int code; + + private final String message; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineProxyType.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineProxyType.java new file mode 100644 index 00000000..88171c5f --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/enums/MachineProxyType.java @@ -0,0 +1,31 @@ +package cd.casic.module.machine.enums; + +import cd.casic.framework.commons.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum MachineProxyType implements IntArrayValuable { + HTTP(1, "http"), + SOCKS4(2, "socks4"), + SOCKS5(3, "socks5"); + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MachineProxyType::getCode).toArray(); + + /** + * 状态值 + */ + private final Integer code; + /** + * 状态名 + */ + private final String message; + + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineEnvService.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineEnvService.java new file mode 100644 index 00000000..1222ff42 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineEnvService.java @@ -0,0 +1,45 @@ +package cd.casic.module.machine.service; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.module.machine.controller.vo.MachineEnvVO; +import cd.casic.module.machine.dal.dataobject.MachineEnvDO; +import jakarta.validation.Valid; + +/** + * 环境变量服务接口 + */ + +public interface MachineEnvService { + /** + * 创建或更新机器的环境变量(一对一关系) + */ + Long createEnv(@Valid MachineEnvVO machineEnvVO); + + /** + * 删除机器的环境变量 + */ + void deleteEnv(Long machineEvnId); + + /** + * 获取机器的环境变量 + * + * @param machineId 机器ID + * @return 环境变量DTO + */ + MachineEnvVO getEnv(Long machineId); + + /** + * @return 环境变量列表 + */ + PageResult getEnvPage(@Valid MachineEnvVO machineEnvVO); + + /** + * 批量删除 + */ + void deleteEnvList(String ids); + + /* + * 修改环境变量 + */ + void updateEnv(@Valid MachineEnvVO machineEnvVO); +} 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 new file mode 100644 index 00000000..23c1f5d0 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineInfoService.java @@ -0,0 +1,69 @@ +package cd.casic.module.machine.service; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.module.machine.controller.vo.MachineInfoVO; +import cd.casic.module.machine.controller.vo.SecretKeyVO; +import cd.casic.module.machine.dal.dataobject.MachineInfoDO; +import jakarta.validation.Valid; + +import java.util.List; + +public interface MachineInfoService { + /** + * 新增机器 + * + * @return 新增机器的id + */ + Long createMachine(MachineInfoVO MachineInfoVO); + + /** + * 查看机器列表 + * + * @return 机器列表 + */ + PageResult listMachineInfo(@Valid MachineInfoVO MachineInfoVO); + + /** + * 更新机器信息 + */ + void updateMachineInfo(@Valid MachineInfoVO machineInfoVO); + + /** + * 变更机器状态 + */ + Integer updateStatus(@Valid MachineInfoVO machineInfoVO); + + /** + * 绑定密钥 + */ + void bindingSecretKey(SecretKeyVO secretKeyVO); + + /** + * 批量删除机器 + * + * @param machineInfoIds 机器id列表 + */ + void deleteMachineInfoList(String machineInfoIds); + + /** + * 删除机器信息 + * + * @param machineInfoId 机器id + */ + void deleteMachineInfo(Long machineInfoId); + + /** + * 获取绑定的密钥 + * + * @param secretKeyId 密钥id + * @return 绑定的机器列表 + */ + List selectBindMachineBySecretKey(Long secretKeyId); + + /** + * 验证机器是否存在 + * + * @param id 机器id + */ + MachineInfoDO validateMachineInfoExists(Long id); +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineProxyService.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineProxyService.java new file mode 100644 index 00000000..9dd8beb5 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/MachineProxyService.java @@ -0,0 +1,49 @@ +package cd.casic.module.machine.service; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.module.machine.controller.vo.MachineProxyVO; +import cd.casic.module.machine.dal.dataobject.MachineProxyDO; +import jakarta.validation.Valid; + +import java.util.Map; + +/** + * 机器代理服务接口 + */ +public interface MachineProxyService { + /** + * 注册新的机器代理 + */ + Long createProxy(@Valid MachineProxyVO machineProxyVO); + + /** + * 更新代理状态 + */ + void updateProxy(@Valid MachineProxyVO machineProxyVO); + + /** + * 删除代理 + * + */ + void delete(Long id); + + /** + * 获取所有代理的状态统计 + * + * @return 状态统计Map + */ + Map getAllProxyStatus(); + + + /** + * 批量删除代理 + * + * @param proxyIds 代理ID列表 + */ + void deleteProxyList(String proxyIds); + + /** + * 获取代理列表(分页) + */ + PageResult getProxyPage(@Valid MachineProxyVO machineProxyVO); +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/SecretKeyService.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/SecretKeyService.java new file mode 100644 index 00000000..19326057 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/SecretKeyService.java @@ -0,0 +1,48 @@ +package cd.casic.module.machine.service; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.module.machine.dal.dataobject.MachineInfoDO; +import cd.casic.module.machine.dal.dataobject.SecretKeyDO; +import cd.casic.module.machine.controller.vo.SecretKeyVO; +import jakarta.validation.Valid; + +import java.util.List; + +public interface SecretKeyService { + /** + * 新增密钥 + */ + Long createSecretKey(@Valid SecretKeyVO secretKeyVO); + + /** + * 更新密钥 + */ + void updateSecretKey(@Valid SecretKeyVO secretKeyVO); + + /** + * 获取密钥列表(分页) + */ + PageResult getSecretKeyPage(@Valid SecretKeyVO secretKeyVO); + + /** + * 批量删除密钥 + * @param ids 密钥id集合 + */ + void deleteSecretKeyList(List ids); + + /** + * 根据id获取密钥对象 + */ + SecretKeyVO getSecretKey(Long id); + + /** + * 获取绑定的密钥的机器列表 + */ + List getBindMachine(Long secretKeyId); + + /** + * 获取公钥内容 + */ + String getPublicKeyContent(Long secretKeyId); +} + diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineEnvServiceImpl.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineEnvServiceImpl.java new file mode 100644 index 00000000..3363307e --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineEnvServiceImpl.java @@ -0,0 +1,105 @@ +package cd.casic.module.machine.service.impl; + +import cd.casic.module.machine.controller.vo.MachineEnvVO; +import cd.casic.module.machine.dal.dataobject.MachineEnvDO; +import cd.casic.module.machine.dal.mysql.MachineEnvMapper; +import cd.casic.module.machine.service.MachineEnvService; +import cd.casic.framework.commons.pojo.PageResult; +import com.google.common.annotations.VisibleForTesting; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import cd.casic.framework.commons.util.object.BeanUtils; + +import java.util.Arrays; +import java.util.List; + +import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception; +import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*; + +/** + * 环境变量服务实现类 + */ +@Service("machineEnvService") +public class MachineEnvServiceImpl implements MachineEnvService { + + @Resource + private MachineEnvMapper machineEnvMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createEnv(MachineEnvVO machineEnvVO) { + validateMachineEnvAdd(machineEnvVO); + // 检查键是否合法 + validateKey(machineEnvVO.getEnvKey()); + MachineEnvDO machineEnvDO = BeanUtils.toBean(machineEnvVO, MachineEnvDO.class); + machineEnvMapper.insert(machineEnvDO); + return machineEnvDO.getId(); + } + + @Override + public void deleteEnv(Long machineEvnId) { + machineEnvMapper.deleteById(machineEvnId); + } + + + @Override + public MachineEnvVO getEnv(Long machineId) { + MachineEnvDO machineEnvDO = validateMachineEnvExists(machineId); + return BeanUtils.toBean(machineEnvDO, MachineEnvVO.class); + } + + + @Override + public PageResult getEnvPage(MachineEnvVO machineEnvVO) { + return machineEnvMapper.selectPage(machineEnvVO); + } + + @Override + public void deleteEnvList(String ids) { + //ids转换为List,使用流 + List machineEnvIds = Arrays.stream(ids.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(Long::parseLong) + .toList(); + + machineEnvMapper.deleteBatchIds(machineEnvIds); + } + + @Override + public void updateEnv(MachineEnvVO machineEnvVO) { + MachineEnvDO machineEnvDO = validateMachineEnvExists(machineEnvVO.getId()); + BeanUtils.copyProperties(machineEnvVO, machineEnvDO); + machineEnvMapper.updateById(machineEnvDO); + } + + @VisibleForTesting + MachineEnvDO validateMachineEnvExists(Long id) { + if (id == null) { + return null; + } + MachineEnvDO machineEnvDO = machineEnvMapper.selectById(id); + if (machineEnvDO == null) { + throw exception(MACHINE_ENV_NOT_EXISTS); + } + return machineEnvDO; + } + + @VisibleForTesting + void validateMachineEnvAdd(MachineEnvVO machineEnvVO) { + if (machineEnvVO.getEnvKey() == null || machineEnvVO.getEnvValue() == null) { + throw exception(MACHINE_ENV_NULL); + } + } + + + // 检查环境变量键是否合法 + @VisibleForTesting + private void validateKey(String key) { + if (!key.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) { + throw exception(MACHINE_ENV_KEY_ILLEGAL); + } + } + +} 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 new file mode 100644 index 00000000..90428a99 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineInfoServiceImpl.java @@ -0,0 +1,176 @@ +package cd.casic.module.machine.service.impl; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.module.machine.controller.vo.SecretKeyVO; +import cd.casic.module.machine.enums.AuthenticationType; +import cd.casic.module.machine.enums.MachineInfoType; +import cd.casic.module.machine.dal.mysql.MachineInfoMapper; +import cd.casic.module.machine.controller.vo.MachineInfoVO; +import cd.casic.module.machine.dal.dataobject.MachineInfoDO; +import cd.casic.module.machine.enums.MachineInfoStatus; +import cd.casic.module.machine.service.MachineInfoService; +import cd.casic.module.machine.service.SecretKeyService; +import com.google.common.annotations.VisibleForTesting; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import cd.casic.framework.commons.util.object.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception; +import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*; + +/** + * 机器信息服务实现类 + */ +@Slf4j +@Service("machineInfoToService") +public class MachineInfoServiceImpl implements MachineInfoService { + + @Resource + private SecretKeyService secretKeyService; + + @Resource + private MachineInfoMapper machineInfoMapper; + + @Override + public Long createMachine(MachineInfoVO machineInfoVO) { + validateMachineEnvAdd(machineInfoVO); + validateMachineTagUnique(machineInfoVO.getTag()); + MachineInfoDO machineInfoDO = BeanUtils.toBean(machineInfoVO, MachineInfoDO.class); + if (machineInfoVO.getAuthenticationType() == 2) { + Long secretKeyId = machineInfoDO.getSecretKeyId(); + SecretKeyVO secretKey = secretKeyService.getSecretKey(secretKeyId); + if (secretKey == null) { + throw exception(SECRET_KEY_NOT_EXISTS); + } + } + machineInfoMapper.insert(machineInfoDO); + return machineInfoDO.getId(); + } + + @Override + public void updateMachineInfo(MachineInfoVO machineInfoVO) { + validateMachineEnvAdd(machineInfoVO); + String newTag = machineInfoVO.getTag(); + MachineInfoDO machineInfoDO = validateMachineInfoExists(machineInfoVO.getId()); + String oldTag = machineInfoDO.getTag(); + if (!newTag.equals(oldTag)) { + validateMachineTagUnique(newTag); + } + BeanUtils.copyProperties(machineInfoVO, machineInfoDO); + machineInfoMapper.updateById(machineInfoDO); + } + + @Override + public Integer updateStatus(MachineInfoVO machineInfoVO) { + machineInfoMapper.updateStatus(machineInfoVO.getId(), machineInfoVO.getStatus()); + return machineInfoVO.getStatus(); + } + + @Override + public PageResult listMachineInfo(MachineInfoVO machineInfoVO) { + return machineInfoMapper.selectPage(machineInfoVO); + } + + @Override + public void bindingSecretKey(SecretKeyVO secretKeyVO) { + machineInfoMapper.bindingSecretKey(secretKeyVO.getMachineInfoIds(), secretKeyVO.getId(), secretKeyVO.getEnableBind()); + } + + @Override + @Transactional//其中一个在线,那么就回滚 + public void deleteMachineInfoList(String machineInfoIds) { + List machineInfoIdList = Arrays.stream(machineInfoIds.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(Long::parseLong) + .toList(); + machineInfoIdList.forEach(this::deleteMachineInfo); + } + + @Override + public void deleteMachineInfo(Long machineInfoId) { + MachineInfoDO machineInfoDO = validateMachineInfoExists(machineInfoId); + validateMachineEnable(machineInfoDO); + machineInfoMapper.deleteById(machineInfoId); + } + + @Override + public List selectBindMachineBySecretKey(Long secretKeyId) { + return machineInfoMapper.selectBindMachineBySecretKey(secretKeyId); + } + + @VisibleForTesting + void validateMachineEnvAdd(MachineInfoVO machineInfoVO) { + if (machineInfoVO.getHostIp().isEmpty()) { + throw exception(MACHINE_INFO_HOST_IP_NULL); + } + if (machineInfoVO.getUsername().isEmpty()) { + throw exception(MACHINE_INFO_USER_NAME_NULL); + } + if (machineInfoVO.getTag().isEmpty()) { + throw exception(MACHINE_INFO_TAG_NULL); + } + + if (machineInfoVO.getAuthenticationType() != null) { + boolean flag = true; + for (int type : AuthenticationType.ARRAYS) { + if (type == machineInfoVO.getAuthenticationType()) { + flag = false; + break; + } + } + if (flag) { + throw exception(MACHINE_INFO_AUTHENTICATION_TYPE_NOT_EXISTS); + } + } else { + throw exception(MACHINE_INFO_AUTHENTICATION_TYPE_NULL); + } + + + if (machineInfoVO.getMachineInfoType() != null) { + boolean flag = true; + for (int type : MachineInfoType.ARRAYS) { + if (type == machineInfoVO.getMachineInfoType()) { + flag = false; + break; + } + } + if (flag) { + throw exception(MACHINE_INFO_TYPE_NOT_EXISTS); + } + } else { + throw exception(MACHINE_INFO_TYPE_NULL); + } + + } + + @VisibleForTesting + void validateMachineTagUnique(String tag) { + if (machineInfoMapper.existsByTag(tag)) { + throw exception(MACHINE_INFO_TAG_EXISTS); + } + } + + @Override + public MachineInfoDO validateMachineInfoExists(Long id) { + if (id == null) { + throw exception(MACHINE_INFO_NULL); + } + MachineInfoDO machineInfoDO = machineInfoMapper.selectById(id); + if (machineInfoDO == null) { + throw exception(MACHINE_INFO_NULL); + } + return machineInfoDO; + } + + @VisibleForTesting + void validateMachineEnable(MachineInfoDO machineInfoDO) { + if (machineInfoDO.getStatus() == MachineInfoStatus.ENABLE.getCode()) { + throw exception(MACHINE_ENABLE); + } + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineProxyServiceImpl.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineProxyServiceImpl.java new file mode 100644 index 00000000..84bd5e2e --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/MachineProxyServiceImpl.java @@ -0,0 +1,131 @@ +package cd.casic.module.machine.service.impl; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.module.machine.controller.vo.MachineProxyVO; +import cd.casic.module.machine.dal.dataobject.MachineProxyDO; +import cd.casic.module.machine.enums.MachineProxyStatus; +import cd.casic.module.machine.enums.MachineProxyType; +import cd.casic.module.machine.dal.mysql.MachineProxyMapper; +import cd.casic.module.machine.service.MachineProxyService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.google.common.annotations.VisibleForTesting; +import jakarta.annotation.Resource; +import cd.casic.framework.commons.util.object.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception; +import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*; +import static com.baomidou.mybatisplus.extension.toolkit.Db.save; + +/** + * 机器代理服务实现类 + */ +@Service("machineProxyService") +public class MachineProxyServiceImpl implements MachineProxyService { + @Resource + private MachineProxyMapper machineProxyMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createProxy(MachineProxyVO machineProxyVO) { + validateMachineProxyAdd(machineProxyVO); + // 创建代理记录 + MachineProxyDO machineProxyDO = BeanUtils.toBean(machineProxyVO, MachineProxyDO.class); + save(machineProxyDO); + return machineProxyDO.getId(); + } + + @Override + public void updateProxy(MachineProxyVO machineProxyVO) { + // 参数校验 + MachineProxyDO machineProxyDO = validateMachineProxyExists(machineProxyVO.getId()); + // 更新状态 + BeanUtils.copyProperties(machineProxyVO, machineProxyDO); + machineProxyMapper.updateById(machineProxyDO); + } + + @Override + public void delete(Long id) { + MachineProxyDO machineProxyDO = validateMachineProxyExists(id); + validateMachineProxyOnline(machineProxyDO); + machineProxyMapper.deleteById(id); + } + + @VisibleForTesting + void validateMachineProxyOnline(MachineProxyDO machineProxyDO) { + if (machineProxyDO.getStatus() == MachineProxyStatus.ONLINE.getCode()) { + throw exception(MACHINE_PROXY_IS_ONLINE); + } + } + + @Override + public Map getAllProxyStatus() { + List proxyList = machineProxyMapper.selectList(new QueryWrapper<>()); + if (CollectionUtils.isEmpty(proxyList)) { + return Collections.emptyMap(); + } + return proxyList.stream() + .map(MachineProxyDO::getStatus) + .collect(Collectors.groupingBy( + Function.identity(), + // 统计每个分组的元素数量 + Collectors.counting() + )); + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteProxyList(String ids) { + if (ids == null) { + return; + } + List machineProxyIds = Arrays.stream(ids.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(Long::parseLong) + .toList(); + // 批量逻辑删除 + machineProxyIds.forEach(this::delete); + } + + @Override + public PageResult getProxyPage(MachineProxyVO machineProxyVO) { + return machineProxyMapper.selectPage(machineProxyVO); + } + + @VisibleForTesting + MachineProxyDO validateMachineProxyExists(Long id) { + if (id == null) { + throw exception(MACHINE_PROXY_NOT_EXISTS); + } + MachineProxyDO machineProxyDO = machineProxyMapper.selectById(id); + if (machineProxyDO == null) { + throw exception(MACHINE_PROXY_NOT_EXISTS); + } + return machineProxyDO; + } + + @VisibleForTesting + void validateMachineProxyAdd(MachineProxyVO machineProxyVO) { + if (machineProxyVO.getHostIp() == null) { + throw exception(MACHINE_PROXY_HOST_IP_NULL); + } + if (machineProxyVO.getUsername() == null) { + throw exception(MACHINE_PROXY_USER_NAME_NULL); + } + + // 校验代理类型 + int[] arrays = MachineProxyType.ARRAYS; + if (Arrays.stream(arrays).filter(i -> i == machineProxyVO.getProxyType()).findAny().isEmpty()) { + throw exception(MACHINE_PROXY_TYPE_NOT_EXISTS); + } + } + +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/SecretKeyServiceImpl.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/SecretKeyServiceImpl.java new file mode 100644 index 00000000..b322a954 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/service/impl/SecretKeyServiceImpl.java @@ -0,0 +1,111 @@ +package cd.casic.module.machine.service.impl; + +import cd.casic.framework.commons.pojo.PageResult; +import cd.casic.framework.commons.util.object.BeanUtils; +import cd.casic.module.machine.controller.vo.SecretKeyVO; +import cd.casic.module.machine.dal.dataobject.MachineInfoDO; +import cd.casic.module.machine.dal.dataobject.SecretKeyDO; +import cd.casic.module.machine.dal.mysql.SecretKeyMapper; +import cd.casic.module.machine.service.MachineInfoService; +import cd.casic.module.machine.service.SecretKeyService; +import cd.casic.module.machine.utils.CryptogramUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.google.common.annotations.VisibleForTesting; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.script.ScriptException; +import java.util.List; +import java.util.Objects; + +import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception; +import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*; + +/** + * 密钥服务实现类 + */ +@Service("secretKeyService") +public class SecretKeyServiceImpl implements SecretKeyService { + + @Resource + private MachineInfoService machineInfoService; + + @Resource + private SecretKeyMapper secretKeyMapper; + + @Override + public SecretKeyVO getSecretKey(Long id) { + SecretKeyDO secretKeyDO = validateSecretKeyExists(id); + return BeanUtils.toBean(secretKeyDO, SecretKeyVO.class); + } + + @Override + public List getBindMachine(Long secretKeyId) { + return machineInfoService.selectBindMachineBySecretKey(secretKeyId); + } + + @Override + public String getPublicKeyContent(Long secretKeyId) { + return secretKeyMapper.selectById(secretKeyId).getPublicKey(); + } + + @Override + public Long createSecretKey(SecretKeyVO secretKeyVO) { + validateSecretKeyAdd(secretKeyVO); + SecretKeyDO secretKeyDO = BeanUtils.toBean(secretKeyVO, SecretKeyDO.class); + try { + //密码加密 + secretKeyDO.setPassword(CryptogramUtil.doEncrypt(secretKeyVO.getPassword())); + //公钥加密 + secretKeyDO.setPublicKey(CryptogramUtil.doEncrypt(secretKeyVO.getPublicKey())); + } catch (ScriptException e) { + throw exception(ENCRYPT_OR_DECRYPT_FAIL); + } + secretKeyMapper.insert(secretKeyDO); + return secretKeyDO.getId(); + } + + @Override + public void updateSecretKey(SecretKeyVO secretKeyVO) { + SecretKeyDO secretKeyDO = validateSecretKeyExists(secretKeyVO.getId()); + BeanUtils.copyProperties(secretKeyVO, secretKeyDO); + secretKeyMapper.updateById(secretKeyDO); + } + + @Override + @Transactional + public void deleteSecretKeyList(List ids) { + SecretKeyVO secretKeyVO = new SecretKeyVO() + .setMachineInfoIds(ids) + .setEnableBind(false); + machineInfoService.bindingSecretKey(secretKeyVO); + secretKeyMapper.deleteBatchIds(ids); + } + + @Override + public PageResult getSecretKeyPage(SecretKeyVO secretKeyVO) { + return secretKeyMapper.selectPage(secretKeyVO, new LambdaQueryWrapper() + .like(Objects.nonNull(secretKeyVO.getName()), SecretKeyDO::getName, secretKeyVO.getName()) + .like(Objects.nonNull(secretKeyVO.getDescription()), SecretKeyDO::getDescription, secretKeyVO.getDescription())); + } + + @VisibleForTesting + void validateSecretKeyAdd(SecretKeyVO secretKeyVO) { + if (secretKeyVO == null) { + throw exception(SECRET_KEY_NULL); + } + } + + @VisibleForTesting + SecretKeyDO validateSecretKeyExists(Long id) { + if (id == null) { + throw exception(SECRET_KEY_NOT_EXISTS); + } + SecretKeyDO secretKeyDO = secretKeyMapper.selectById(id); + if (secretKeyDO == null) { + throw exception(SECRET_KEY_NOT_EXISTS); + } + return secretKeyDO; + } +} diff --git a/modules/module-ci-machine/src/main/java/cd/casic/module/machine/utils/CryptogramUtil.java b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/utils/CryptogramUtil.java new file mode 100644 index 00000000..0a91bfd1 --- /dev/null +++ b/modules/module-ci-machine/src/main/java/cd/casic/module/machine/utils/CryptogramUtil.java @@ -0,0 +1,111 @@ +package cd.casic.module.machine.utils; + +import cd.casic.module.machine.dal.model.Keypair; +import cn.hutool.log.Log; +import com.antherd.smcrypto.sm2.Sm2; +import com.antherd.smcrypto.sm3.Sm3; +import com.antherd.smcrypto.sm4.Sm4; +import com.antherd.smcrypto.sm4.Sm4Options; + +import javax.script.ScriptException; + +public class CryptogramUtil { + + private static final Log log = Log.get(); + + /** + * 加密方法(Sm2 的专门针对前后端分离,非对称秘钥对的方式,暴露出去的公钥,对传输过程中的密码加个密) + * + * @param str 待加密数据 + * @return 加密后的密文 + * @author yubaoshan + */ + public static String doSm2Encrypt(String str) throws ScriptException { + return Sm2.doEncrypt(str, Keypair.PUBLIC_KEY); + } + + /** + * 解密方法 + * 如果采用加密机的方法,用try catch 捕捉异常,返回原文值即可 + * + * @param str 密文 + * @return 解密后的明文 + * @author yubaoshan + */ + public static String doSm2Decrypt(String str) throws ScriptException { + // 解密 + return Sm2.doDecrypt(str, Keypair.PRIVATE_KEY); + } + + /** + * 加密方法 + * + * @param str 待加密数据 + * @return 加密后的密文 + * @author yubaoshan + */ + public static String doEncrypt(String str) throws ScriptException { + // SM4 加密 cbc模式 + Sm4Options sm4Options4 = new Sm4Options(); + sm4Options4.setMode("cbc"); + sm4Options4.setIv("fedcba98765432100123456789abcdef"); + return Sm4.encrypt(str, Keypair.KEY, sm4Options4); + } + + /** + * 解密方法 + * 如果采用加密机的方法,用try catch 捕捉异常,返回原文值即可 + * + * @param str 密文 + * @return 解密后的明文 + * @author yubaoshan + */ + public static String doDecrypt(String str) throws ScriptException { + // 解密,cbc 模式,输出 utf8 字符串 + Sm4Options sm4Options8 = new Sm4Options(); + sm4Options8.setMode("cbc"); + sm4Options8.setIv("fedcba98765432100123456789abcdef"); + String docString = Sm4.decrypt(str, Keypair.KEY, sm4Options8); + if (docString.isEmpty()) { + log.warn(">>> 字段解密失败,返回原文值:{}", str); + return str; + } else { + return docString; + } + } + + /** + * 纯签名 + * + * @param str 待签名数据 + * @return 签名结果 + * @author yubaoshan + */ + public static String doSignature(String str) throws ScriptException { + return Sm2.doSignature(str, Keypair.PRIVATE_KEY); + } + + /** + * 验证签名结果 + * + * @param originalStr 签名原文数据 + * @param str 签名结果 + * @return 是否通过 + * @author yubaoshan + */ + public static boolean doVerifySignature(String originalStr, String str) throws ScriptException { + return Sm2.doVerifySignature(originalStr, str, Keypair.PUBLIC_KEY); + } + + /** + * 通过杂凑算法取得hash值,用于做数据完整性保护 + * + * @param str 字符串 + * @return hash 值 + * @author yubaoshan + */ + public static String doHashValue(String str) throws ScriptException { + return Sm3.sm3(str); + } + +} diff --git a/modules/pom.xml b/modules/pom.xml index 8452406c..8b1a31ba 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -19,6 +19,7 @@ module-ci-execute module-ci-process-api module-ci-process-biz + module-ci-machine modules