From 95c299eea41abdede73a7aa0d639de81dda5120c Mon Sep 17 00:00:00 2001 From: lijiahangmax Date: Fri, 12 Jul 2024 00:02:45 +0800 Subject: [PATCH 01/13] =?UTF-8?q?:lipstick:=20=E4=BF=AE=E6=94=B9=E4=B8=BB?= =?UTF-8?q?=E6=9C=BA=E7=BC=96=E8=BE=91=E6=A0=B7=E5=BC=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/connect-log-detail-drawer.vue | 23 ++++++- .../components/ssh-config-form.vue | 67 +++++++++++-------- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/orion-visor-ui/src/views/asset-audit/connect-log/components/connect-log-detail-drawer.vue b/orion-visor-ui/src/views/asset-audit/connect-log/components/connect-log-detail-drawer.vue index 44f1f090..57c69d92 100644 --- a/orion-visor-ui/src/views/asset-audit/connect-log/components/connect-log-detail-drawer.vue +++ b/orion-visor-ui/src/views/asset-audit/connect-log/components/connect-log-detail-drawer.vue @@ -31,11 +31,15 @@ - {{ getDictValue(connectTypeKey, record.type) }} + + {{ getDictValue(connectTypeKey, record.type) }} + - {{ getDictValue(connectStatusKey, record.status) }} + + {{ getDictValue(connectStatusKey, record.status) }} + @@ -53,7 +57,9 @@ - {{ record.extra?.errorMessage }} + + {{ record.extra?.errorMessage }} + @@ -141,4 +147,15 @@ display: inline-block; color: rgb(var(--arcoblue-6)); } + + + :deep(.arco-collapse-item-content) { + background: unset; + padding: 0; + } + + :deep(.arco-collapse-item-header) { + border: none; + } + diff --git a/orion-visor-ui/src/views/asset/host-config/components/ssh-config-form.vue b/orion-visor-ui/src/views/asset/host-config/components/ssh-config-form.vue index 55411ce6..ee953980 100644 --- a/orion-visor-ui/src/views/asset/host-config/components/ssh-config-form.vue +++ b/orion-visor-ui/src/views/asset/host-config/components/ssh-config-form.vue @@ -84,36 +84,45 @@ :hide-asterisk="true"> - - - - + + + + + + + + @@ -93,15 +94,17 @@ - - 修改 + + 修改 + - - 删除 + + 删除 + diff --git a/orion-visor-framework/orion-visor-spring-boot-starter-mybatis/src/main/resources/templates/orion-vue-views-types-table.columns.ts.vm b/orion-visor-framework/orion-visor-spring-boot-starter-mybatis/src/main/resources/templates/orion-vue-views-types-table.columns.ts.vm index 737e4bd3..52974f69 100644 --- a/orion-visor-framework/orion-visor-spring-boot-starter-mybatis/src/main/resources/templates/orion-vue-views-types-table.columns.ts.vm +++ b/orion-visor-framework/orion-visor-spring-boot-starter-mybatis/src/main/resources/templates/orion-vue-views-types-table.columns.ts.vm @@ -6,7 +6,7 @@ const columns = [ title: 'id', dataIndex: 'id', slotName: 'id', - width: 80, + width: 68, align: 'left', fixed: 'left', }, #foreach($field in ${table.fields})#if("$!field.propertyName" != "id"){ diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/controller/HostConfigController.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/controller/HostConfigController.java deleted file mode 100644 index 67ed427b..00000000 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/controller/HostConfigController.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.orion.visor.module.asset.controller; - -import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog; -import com.orion.visor.framework.log.core.annotation.IgnoreLog; -import com.orion.visor.framework.log.core.enums.IgnoreLogMode; -import com.orion.visor.framework.web.core.annotation.DemoDisableApi; -import com.orion.visor.framework.web.core.annotation.RestWrapper; -import com.orion.visor.module.asset.define.operator.HostOperatorType; -import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateRequest; -import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateStatusRequest; -import com.orion.visor.module.asset.entity.vo.HostConfigVO; -import com.orion.visor.module.asset.service.HostConfigService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import java.util.List; - -/** - * 主机配置 api - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023-9-11 14:16 - */ -@Tag(name = "asset - 主机配置服务") -@Slf4j -@Validated -@RestWrapper -@RestController -@RequestMapping("/asset/host-config") -public class HostConfigController { - - @Resource - private HostConfigService hostConfigService; - - @IgnoreLog(IgnoreLogMode.RET) - @GetMapping("/get") - @Operation(summary = "查询主机配置") - @Parameter(name = "hostId", description = "hostId", required = true) - @Parameter(name = "type", description = "配置类型", required = true) - @PreAuthorize("@ss.hasPermission('asset:host:query')") - public HostConfigVO getHostConfig(@RequestParam("hostId") Long hostId, - @RequestParam(name = "type") String type) { - return hostConfigService.getHostConfig(hostId, type); - } - - @IgnoreLog(IgnoreLogMode.RET) - @GetMapping("/list") - @Operation(summary = "查询全部主机配置") - @Parameter(name = "hostId", description = "hostId", required = true) - @PreAuthorize("@ss.hasPermission('asset:host:query')") - public List getHostConfigList(@RequestParam("hostId") Long hostId) { - return hostConfigService.getHostConfigList(hostId); - } - - @DemoDisableApi - @OperatorLog(HostOperatorType.UPDATE_CONFIG) - @PutMapping("/update") - @Operation(summary = "更新主机配置") - @PreAuthorize("@ss.hasPermission('asset:host:update-config')") - public Integer updateHostConfig(@Validated @RequestBody HostConfigUpdateRequest request) { - return hostConfigService.updateHostConfig(request); - } - - @DemoDisableApi - @OperatorLog(HostOperatorType.UPDATE_CONFIG_STATUS) - @PutMapping("/update-status") - @Operation(summary = "更新主机配置状态/动态初始化配置") - @PreAuthorize("@ss.hasPermission('asset:host:update-config')") - public Integer updateHostConfigStatus(@Validated @RequestBody HostConfigUpdateStatusRequest request) { - return hostConfigService.updateHostConfigStatus(request); - } - -} - diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/controller/HostController.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/controller/HostController.java index aff0760b..c6057562 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/controller/HostController.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/controller/HostController.java @@ -8,9 +8,8 @@ import com.orion.visor.framework.log.core.enums.IgnoreLogMode; import com.orion.visor.framework.web.core.annotation.DemoDisableApi; import com.orion.visor.framework.web.core.annotation.RestWrapper; import com.orion.visor.module.asset.define.operator.HostOperatorType; -import com.orion.visor.module.asset.entity.request.host.HostCreateRequest; -import com.orion.visor.module.asset.entity.request.host.HostQueryRequest; -import com.orion.visor.module.asset.entity.request.host.HostUpdateRequest; +import com.orion.visor.module.asset.entity.request.host.*; +import com.orion.visor.module.asset.entity.vo.HostConfigVO; import com.orion.visor.module.asset.entity.vo.HostVO; import com.orion.visor.module.asset.service.HostService; import io.swagger.v3.oas.annotations.Operation; @@ -60,6 +59,24 @@ public class HostController { return hostService.updateHostById(request); } + @DemoDisableApi + @OperatorLog(HostOperatorType.UPDATE_STATUS) + @PutMapping("/update-status") + @Operation(summary = "更新主机状态") + @PreAuthorize("@ss.hasPermission('asset:host:update-status')") + public Integer updateHostStatus(@Validated @RequestBody HostUpdateStatusRequest request) { + return hostService.updateHostStatus(request); + } + + @DemoDisableApi + @OperatorLog(HostOperatorType.UPDATE_CONFIG) + @PutMapping("/update-config") + @Operation(summary = "更新主机配置") + @PreAuthorize("@ss.hasPermission('asset:host:update-config')") + public Integer updateHostConfig(@Validated @RequestBody HostUpdateConfigRequest request) { + return hostService.updateHostConfig(request); + } + @IgnoreLog(IgnoreLogMode.RET) @GetMapping("/get") @Operation(summary = "通过 id 查询主机") @@ -69,12 +86,22 @@ public class HostController { return hostService.getHostById(id); } + @IgnoreLog(IgnoreLogMode.RET) + @GetMapping("/get-config") + @Operation(summary = "查询主机配置") + @Parameter(name = "id", description = "id", required = true) + @PreAuthorize("@ss.hasPermission('asset:host:query')") + public HostConfigVO getHostConfig(@RequestParam("id") Long id) { + return hostService.getHostConfig(id); + } + @IgnoreLog(IgnoreLogMode.RET) @GetMapping("/list") @Operation(summary = "查询主机") + @Parameter(name = "type", description = "type", required = false) @PreAuthorize("@ss.hasPermission('asset:host:query')") - public List getHostList() { - return hostService.getHostListByCache(); + public List getHostList(@RequestParam(value = "type", required = false) String type) { + return hostService.getHostList(type); } @IgnoreLog(IgnoreLogMode.RET) diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/convert/HostConfigConvert.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/convert/HostConfigConvert.java deleted file mode 100644 index 6772aaeb..00000000 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/convert/HostConfigConvert.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.orion.visor.module.asset.convert; - -import com.orion.visor.module.asset.entity.domain.HostConfigDO; -import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateRequest; -import com.orion.visor.module.asset.entity.vo.HostConfigVO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -/** - * 主机配置 内部对象转换器 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023-9-11 14:16 - */ -@Mapper -public interface HostConfigConvert { - - HostConfigConvert MAPPER = Mappers.getMapper(HostConfigConvert.class); - - @Mapping(target = "config", ignore = true) - HostConfigVO to(HostConfigDO domain); - - HostConfigDO to(HostConfigUpdateRequest request); - -} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/dao/HostConfigDAO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/dao/HostConfigDAO.java deleted file mode 100644 index d1094da3..00000000 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/dao/HostConfigDAO.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.orion.visor.module.asset.dao; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.orion.visor.framework.mybatis.core.mapper.IMapper; -import com.orion.visor.module.asset.entity.domain.HostConfigDO; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; - -import java.util.List; - -/** - * 主机配置 Mapper 接口 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023-9-11 14:16 - */ -@Mapper -public interface HostConfigDAO extends IMapper { - - /** - * 通过 hostId 查询主机配置 - * - * @param hostId hostId - * @param type type - * @return row - */ - default HostConfigDO getHostConfigByHostId(Long hostId, String type) { - // 条件 - LambdaQueryWrapper wrapper = this.lambda() - .eq(HostConfigDO::getHostId, hostId) - .eq(HostConfigDO::getType, type); - // 查询 - return this.of(wrapper).getOne(); - } - - /** - * 通过 hostId 查询主机配置 - * - * @param hostId hostId - * @return rows - */ - default List getHostConfigByHostId(Long hostId) { - // 条件 - LambdaQueryWrapper wrapper = this.lambda() - .eq(HostConfigDO::getHostId, hostId); - // 查询 - return this.of(wrapper).list(); - } - - /** - * 通过 hostId 批量查询主机配置 - * - * @param hostIdList hostIdList - * @param type type - * @return rows - */ - default List getHostConfigByHostIdList(List hostIdList, String type) { - // 条件 - LambdaQueryWrapper wrapper = this.wrapper() - .eq(HostConfigDO::getType, type) - .in(HostConfigDO::getHostId, hostIdList); - // 查询 - return this.of(wrapper).list(); - } - - /** - * 通过 hostId 删除主机配置 - * - * @param hostId hostId - * @return effect - */ - default Integer deleteByHostId(Long hostId) { - // 条件 - LambdaQueryWrapper wrapper = this.lambda() - .eq(HostConfigDO::getHostId, hostId); - // 删除 - return this.delete(wrapper); - } - - /** - * 通过 hostId 批量删除主机配置 - * - * @param hostIdList hostIdList - * @return effect - */ - default Integer deleteByHostIdList(List hostIdList) { - // 条件 - LambdaQueryWrapper wrapper = this.lambda() - .in(HostConfigDO::getHostId, hostIdList); - // 删除 - return this.delete(wrapper); - } - - /** - * 设置 keyId 为 NULL - * - * @param keyIdList keyIdList - * @return effect - */ - int setKeyIdWithNull(@Param("keyIdList") List keyIdList); - - /** - * 设置 identityId 为 NULL - * - * @param identityIdList identityIdList - * @return effect - */ - int setIdentityIdWithNull(@Param("identityIdList") List identityIdList); - -} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/dao/HostDAO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/dao/HostDAO.java index abf7dc1a..c4ebd651 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/dao/HostDAO.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/dao/HostDAO.java @@ -1,8 +1,13 @@ package com.orion.visor.module.asset.dao; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.orion.visor.framework.mybatis.core.mapper.IMapper; import com.orion.visor.module.asset.entity.domain.HostDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.Arrays; +import java.util.List; /** * 主机 Mapper 接口 @@ -14,4 +19,83 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface HostDAO extends IMapper { + List> BASE_COLUMN = Arrays.asList( + HostDO::getId, + HostDO::getType, + HostDO::getName, + HostDO::getCode, + HostDO::getAddress, + HostDO::getPort, + HostDO::getStatus, + HostDO::getCreateTime, + HostDO::getUpdateTime, + HostDO::getCreator, + HostDO::getUpdater + ); + + /** + * 通过 id 查询基本信息 + * + * @param id id + * @return id + */ + default HostDO selectBaseById(Long id) { + return this.of() + .createWrapper() + .select(BASE_COLUMN) + .eq(HostDO::getId, id) + .then() + .getOne(); + } + + /** + * 通过 id 查询基本信息 + * + * @param idList idList + * @return id + */ + default List selectBaseByIdList(List idList) { + return this.of() + .createWrapper() + .select(BASE_COLUMN) + .in(HostDO::getId, idList) + .then() + .list(); + } + + /** + * 获取的 hostId + * + * @param hostIdList hostIdList + * @param type type + * @param status status + * @return hostId + */ + default List getHostIdList(List hostIdList, String type, String status) { + return this.of() + .createWrapper(true) + .select(HostDO::getId) + .in(HostDO::getId, hostIdList) + .eq(HostDO::getType, type) + .eq(HostDO::getStatus, status) + .then() + .list(HostDO::getId); + } + + /** + * 设置 keyId 为 NULL + * + * @param keyIdList keyIdList + * @return effect + */ + int setKeyIdWithNull(@Param("keyIdList") List keyIdList); + + /** + * 设置 identityId 为 NULL + * + * @param identityIdList identityIdList + * @return effect + */ + int setIdentityIdWithNull(@Param("identityIdList") List identityIdList); + } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/define/cache/HostCacheKeyDefine.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/define/cache/HostCacheKeyDefine.java index 17213613..5e53798f 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/define/cache/HostCacheKeyDefine.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/define/cache/HostCacheKeyDefine.java @@ -19,8 +19,8 @@ import java.util.concurrent.TimeUnit; public interface HostCacheKeyDefine { CacheKeyDefine HOST_INFO = new CacheKeyBuilder() - .key("host:info:list") - .desc("主机列表") + .key("host:info:list:{}") + .desc("主机列表 ${type}") .type(HostCacheDTO.class) .struct(RedisCacheStruct.HASH) .timeout(8, TimeUnit.HOURS) diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/define/operator/HostOperatorType.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/define/operator/HostOperatorType.java index a8a1fdcb..45cf88a4 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/define/operator/HostOperatorType.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/define/operator/HostOperatorType.java @@ -22,9 +22,9 @@ public class HostOperatorType extends InitializingOperatorTypes { public static final String DELETE = "host:delete"; - public static final String UPDATE_CONFIG = "host:update-config"; + public static final String UPDATE_STATUS = "host:update-status"; - public static final String UPDATE_CONFIG_STATUS = "host:update-config-status"; + public static final String UPDATE_CONFIG = "host:update-config"; @Override public OperatorType[] types() { @@ -32,8 +32,8 @@ public class HostOperatorType extends InitializingOperatorTypes { new OperatorType(L, CREATE, "创建主机 ${name}"), new OperatorType(L, UPDATE, "修改主机 ${name}"), new OperatorType(H, DELETE, "删除主机 ${name}"), - new OperatorType(M, UPDATE_CONFIG, "修改主机配置 ${name} | ${type}"), - new OperatorType(M, UPDATE_CONFIG_STATUS, "修改主机配置状态 ${name} | ${type} - ${statusName}"), + new OperatorType(M, UPDATE_STATUS, "修改主机状态 ${name} - ${status}"), + new OperatorType(M, UPDATE_CONFIG, "修改主机配置 ${name}"), }; } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/domain/HostConfigDO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/domain/HostConfigDO.java deleted file mode 100644 index bb63f982..00000000 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/domain/HostConfigDO.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.orion.visor.module.asset.entity.domain; - -import com.baomidou.mybatisplus.annotation.*; -import com.orion.visor.framework.mybatis.core.domain.BaseDO; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -/** - * 主机配置 实体对象 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023-9-11 14:16 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = true) -@TableName(value = "host_config", autoResultMap = true) -@Schema(name = "HostConfigDO", description = "主机配置 实体对象") -public class HostConfigDO extends BaseDO { - - private static final long serialVersionUID = 1L; - - @Schema(description = "id") - @TableId(value = "id", type = IdType.AUTO) - private Long id; - - @Schema(description = "主机id") - @TableField("host_id") - private Long hostId; - - @Schema(description = "配置类型") - @TableField("type") - private String type; - - @Schema(description = "状态 0停用 1启用") - @TableField("status") - private Integer status; - - @Schema(description = "配置详情") - @TableField("config") - private String config; - - @Schema(description = "配置版本号") - @TableField("version") - @Version - private Integer version; - -} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/domain/HostDO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/domain/HostDO.java index 1760d212..25c609ea 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/domain/HostDO.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/domain/HostDO.java @@ -30,6 +30,10 @@ public class HostDO extends BaseDO { @TableId(value = "id", type = IdType.AUTO) private Long id; + @Schema(description = "主机类型") + @TableField("type") + private String type; + @Schema(description = "主机名称") @TableField("name") private String name; @@ -42,4 +46,16 @@ public class HostDO extends BaseDO { @TableField("address") private String address; + @Schema(description = "主机端口") + @TableField("port") + private Integer port; + + @Schema(description = "主机状态") + @TableField("status") + private String status; + + @Schema(description = "主机配置") + @TableField("config") + private String config; + } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/dto/HostCacheDTO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/dto/HostCacheDTO.java index 7e7c22d0..d1dc4eec 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/dto/HostCacheDTO.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/dto/HostCacheDTO.java @@ -26,6 +26,9 @@ public class HostCacheDTO implements LongCacheIdModel, Serializable { @Schema(description = "id") private Long id; + @Schema(description = "主机类型") + private String type; + @Schema(description = "主机名称") private String name; @@ -35,4 +38,10 @@ public class HostCacheDTO implements LongCacheIdModel, Serializable { @Schema(description = "主机地址") private String address; + @Schema(description = "主机端口") + private Integer port; + + @Schema(description = "主机状态") + private String status; + } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/dto/HostTerminalConnectDTO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/dto/HostTerminalConnectDTO.java index df261acf..27adc933 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/dto/HostTerminalConnectDTO.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/dto/HostTerminalConnectDTO.java @@ -38,12 +38,12 @@ public class HostTerminalConnectDTO { @Schema(description = "主机地址") private String hostAddress; + @Schema(description = "主机端口") + private Integer hostPort; + @Schema(description = "系统类型") private String osType; - @Schema(description = "端口") - private Integer port; - @Schema(description = "超时时间") private Integer timeout; diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigQueryRequest.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigQueryRequest.java deleted file mode 100644 index b7329182..00000000 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigQueryRequest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.orion.visor.module.asset.entity.request.host; - -import com.orion.visor.framework.common.entity.PageRequest; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -import javax.validation.constraints.Size; - -/** - * 主机配置 查询请求对象 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023-9-13 14:31 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = true) -@Schema(name = "HostConfigQueryRequest", description = "主机配置 查询请求对象") -public class HostConfigQueryRequest extends PageRequest { - - @Schema(description = "主机id") - private Long hostId; - - @Size(max = 32) - @Schema(description = "配置类型") - private String type; - -} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigUpdateStatusRequest.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigUpdateStatusRequest.java deleted file mode 100644 index 69719684..00000000 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigUpdateStatusRequest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.orion.visor.module.asset.entity.request.host; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; -import java.io.Serializable; - -/** - * 主机配置 更新请求对象 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023-9-13 14:31 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Schema(name = "HostConfigUpdateRequest", description = "主机配置 更新请求对象") -public class HostConfigUpdateStatusRequest implements Serializable { - - @NotNull - @Schema(description = "主机id") - private Long hostId; - - @NotNull - @Size(max = 32) - @Schema(description = "配置类型") - private String type; - - @NotNull - @Schema(description = "状态 0停用 1启用") - private Integer status; - - @Schema(description = "配置版本号") - private Integer version; - -} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostCreateRequest.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostCreateRequest.java index f501e717..15527c51 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostCreateRequest.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostCreateRequest.java @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Range; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; @@ -25,6 +26,10 @@ import java.util.List; @Schema(name = "HostCreateRequest", description = "主机 创建请求对象") public class HostCreateRequest implements Serializable { + @NotBlank + @Schema(description = "主机类型") + private String type; + @NotBlank @Size(max = 64) @Schema(description = "主机名称") @@ -40,6 +45,10 @@ public class HostCreateRequest implements Serializable { @Schema(description = "主机地址") private String address; + @Range(min = 1, max = 65535) + @Schema(description = "主机端口") + private Integer port; + @Schema(description = "主机分组") private List groupIdList; diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostQueryRequest.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostQueryRequest.java index fa3caf17..c42e36f9 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostQueryRequest.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostQueryRequest.java @@ -40,13 +40,18 @@ public class HostQueryRequest extends PageRequest { @Schema(description = "主机地址") private String address; + @Size(max = 8) + @Schema(description = "主机类型") + private String type; + + @Size(max = 8) + @Schema(description = "主机状态") + private String status; + @Schema(description = "tag") private List tags; @Schema(description = "是否查询 tag 信息") private Boolean queryTag; - @Schema(description = "是否查询配置信息") - private Boolean queryConfig; - } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigUpdateRequest.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateConfigRequest.java similarity index 54% rename from orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigUpdateRequest.java rename to orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateConfigRequest.java index d5b3dcd3..609fb36e 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostConfigUpdateRequest.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateConfigRequest.java @@ -8,11 +8,10 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.io.Serializable; /** - * 主机配置 更新请求对象 + * 主机 更新配置请求对象 * * @author Jiahang Li * @version 1.0.0 @@ -22,24 +21,15 @@ import java.io.Serializable; @Builder @NoArgsConstructor @AllArgsConstructor -@Schema(name = "HostConfigUpdateRequest", description = "主机配置 更新请求对象") -public class HostConfigUpdateRequest implements Serializable { +@Schema(name = "HostUpdateConfigRequest", description = "主机 更新配置请求对象") +public class HostUpdateConfigRequest implements Serializable { @NotNull - @Schema(description = "主机id") - private Long hostId; - - @NotNull - @Size(max = 32) - @Schema(description = "配置类型") - private String type; + @Schema(description = "id") + private Long id; @NotBlank @Schema(description = "配置详情") private String config; - @NotNull - @Schema(description = "配置版本号") - private Integer version; - } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateRequest.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateRequest.java index cc422965..7b7e3b35 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateRequest.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateRequest.java @@ -5,6 +5,7 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.hibernate.validator.constraints.Range; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -45,6 +46,10 @@ public class HostUpdateRequest implements Serializable { @Schema(description = "主机地址") private String address; + @Range(min = 1, max = 65535) + @Schema(description = "主机端口") + private Integer port; + @Schema(description = "主机分组") private List groupIdList; diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateStatusRequest.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateStatusRequest.java new file mode 100644 index 00000000..60a9c2fe --- /dev/null +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/request/host/HostUpdateStatusRequest.java @@ -0,0 +1,34 @@ +package com.orion.visor.module.asset.entity.request.host; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +/** + * 主机 更新状态请求对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-13 14:31 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostUpdateStatusRequest", description = "主机 更新状态请求对象") +public class HostUpdateStatusRequest implements Serializable { + + @NotNull + @Schema(description = "id") + private Long id; + + @NotNull + @Schema(description = "状态") + private String status; + +} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/ExecJobVO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/ExecJobVO.java index c3230fb6..cae4bcea 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/ExecJobVO.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/ExecJobVO.java @@ -69,6 +69,6 @@ public class ExecJobVO implements Serializable { private List hostIdList; @Schema(description = "执行主机") - private List hostList; + private List hostList; } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostBaseVO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostBaseVO.java index 36323808..8afde82a 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostBaseVO.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostBaseVO.java @@ -27,6 +27,9 @@ public class HostBaseVO implements Serializable { @Schema(description = "id") private Long id; + @Schema(description = "主机类型") + private String type; + @Schema(description = "主机名称") private String name; @@ -36,4 +39,7 @@ public class HostBaseVO implements Serializable { @Schema(description = "主机地址") private String address; + @Schema(description = "主机端口") + private Integer port; + } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostConfigVO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostConfigVO.java index fa9afe9c..79cd1e31 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostConfigVO.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostConfigVO.java @@ -25,18 +25,9 @@ public class HostConfigVO { @Schema(description = "id") private Long id; - @Schema(description = "hostId") - private Long hostId; - - @Schema(description = "version") - private Integer version; - - @Schema(description = "配置类型") + @Schema(description = "type") private String type; - @Schema(description = "状态 0停用 1启用") - private Integer status; - @Schema(description = "config") private Map config; diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostVO.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostVO.java index b1a1214d..3b842bf5 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostVO.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/entity/vo/HostVO.java @@ -31,6 +31,9 @@ public class HostVO implements Serializable { @Schema(description = "id") private Long id; + @Schema(description = "主机类型") + private String type; + @Schema(description = "主机名称") private String name; @@ -40,6 +43,12 @@ public class HostVO implements Serializable { @Schema(description = "主机地址") private String address; + @Schema(description = "主机端口") + private Integer port; + + @Schema(description = "主机状态") + private String status; + @Schema(description = "创建时间") private Date createTime; diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostExtraItemEnum.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostExtraItemEnum.java index f0f78510..6f97b04f 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostExtraItemEnum.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostExtraItemEnum.java @@ -22,25 +22,23 @@ public enum HostExtraItemEnum implements GenericsDataDefinition { /** * SSH 额外配置 */ - SSH("ssh", HostSshExtraStrategy.class), + SSH(HostSshExtraStrategy.class), /** * 标签额外配置 */ - LABEL("label", HostLabelExtraStrategy.class), + LABEL(HostLabelExtraStrategy.class), ; - private final String item; - private final Class> strategyClass; - public static HostExtraItemEnum of(String type) { - if (type == null) { + public static HostExtraItemEnum of(String item) { + if (item == null) { return null; } for (HostExtraItemEnum value : values()) { - if (value.item.equals(type)) { + if (value.name().equals(item)) { return value; } } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostStatusEnum.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostStatusEnum.java new file mode 100644 index 00000000..3eb0cd4e --- /dev/null +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostStatusEnum.java @@ -0,0 +1,36 @@ +package com.orion.visor.module.asset.enums; + +/** + * 主机状态 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/7/17 16:07 + */ +public enum HostStatusEnum { + + /** + * 停用 + */ + DISABLED, + + /** + * 启用 + */ + ENABLED, + + ; + + public static HostStatusEnum of(String name) { + if (name == null) { + return null; + } + for (HostStatusEnum value : values()) { + if (value.name().equals(name)) { + return value; + } + } + return null; + } + +} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostConfigTypeEnum.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostTypeEnum.java similarity index 63% rename from orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostConfigTypeEnum.java rename to orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostTypeEnum.java index 996bf15f..f85cea55 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostConfigTypeEnum.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/enums/HostTypeEnum.java @@ -1,6 +1,5 @@ package com.orion.visor.module.asset.enums; -import com.orion.visor.framework.common.enums.EnableStatus; import com.orion.visor.framework.common.handler.data.GenericsDataDefinition; import com.orion.visor.framework.common.handler.data.model.GenericsDataModel; import com.orion.visor.framework.common.handler.data.strategy.GenericsDataStrategy; @@ -17,29 +16,23 @@ import lombok.Getter; */ @Getter @AllArgsConstructor -public enum HostConfigTypeEnum implements GenericsDataDefinition { +public enum HostTypeEnum implements GenericsDataDefinition { /** - * SSH 配置 + * SSH */ - SSH("ssh", - HostSshConfigStrategy.class, - EnableStatus.ENABLED.getValue()), + SSH(HostSshConfigStrategy.class), ; - private final String type; - private final Class> strategyClass; - private final Integer defaultStatus; - - public static HostConfigTypeEnum of(String type) { + public static HostTypeEnum of(String type) { if (type == null) { return null; } - for (HostConfigTypeEnum value : values()) { - if (value.type.equalsIgnoreCase(type)) { + for (HostTypeEnum value : values()) { + if (value.name().equals(type)) { return value; } } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/config/model/HostSshConfigModel.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/config/model/HostSshConfigModel.java index 3fd8ca3c..485c8cb3 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/config/model/HostSshConfigModel.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/config/model/HostSshConfigModel.java @@ -25,13 +25,6 @@ import javax.validation.constraints.Size; @AllArgsConstructor public class HostSshConfigModel implements GenericsDataModel, UpdatePasswordAction { - /** - * ssh 端口 - */ - @NotNull - @Range(min = 1, max = 65535) - private Integer port; - /** * 用户名 */ diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/config/strategy/HostSshConfigStrategy.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/config/strategy/HostSshConfigStrategy.java index d0775b68..92e4c1f2 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/config/strategy/HostSshConfigStrategy.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/config/strategy/HostSshConfigStrategy.java @@ -34,8 +34,6 @@ public class HostSshConfigStrategy extends AbstractGenericsDataStrategy CURRENT_ADDRESS = new ThreadLocal<>(); + + /** + * 打开 sessionStore + * + * @param conn conn + * @return sessionStore + */ + public static SessionStore openSessionStore(HostTerminalConnectDTO conn) { + Long hostId = conn.getHostId(); + String address = conn.getHostAddress(); + String username = conn.getUsername(); + log.info("SessionStores-open-start hostId: {}, address: {}, username: {}", hostId, address, username); + try { + CURRENT_ADDRESS.set(address); + // 创建会话 + SessionHolder sessionHolder = SessionHolder.create(); + SessionStore session = createSessionStore(conn, sessionHolder); + // 连接 + session.connect(); + log.info("SessionStores-open-success hostId: {}, address: {}, username: {}", hostId, address, username); + return session; + } catch (Exception e) { + String message = e.getMessage(); + log.error("SessionStores-open-error hostId: {}, address: {}, username: {}, message: {}", hostId, address, username, message, e); + throw Exceptions.runtime(getErrorMessage(e), e); + } finally { + CURRENT_ADDRESS.remove(); + } + } + + /** + * 创建 sessionStore + * + * @param conn conn + * @param sessionHolder sessionHolder + * @return sessionStore + */ + private static SessionStore createSessionStore(HostTerminalConnectDTO conn, SessionHolder sessionHolder) { + final boolean useKey = conn.getKeyId() != null; + // 使用密钥认证 + if (useKey) { + // 加载密钥 + String publicKey = Optional.ofNullable(conn.getPublicKey()) + .map(CryptoUtils::decryptAsString) + .orElse(null); + String privateKey = Optional.ofNullable(conn.getPrivateKey()) + .map(CryptoUtils::decryptAsString) + .orElse(null); + String password = Optional.ofNullable(conn.getPrivateKeyPassword()) + .map(CryptoUtils::decryptAsString) + .orElse(null); + sessionHolder.addIdentityValue(String.valueOf(conn.getKeyId()), + privateKey, + publicKey, + password); + } + // 获取会话 + SessionStore session = sessionHolder.getSession(conn.getHostAddress(), conn.getHostPort(), conn.getUsername()); + // 使用密码认证 + if (!useKey) { + session.password(CryptoUtils.decryptAsString(conn.getPassword())); + } + // 超时时间 + session.timeout(conn.getTimeout()); + return session; + } + + /** + * 获取错误信息 + * + * @param e e + * @return errorMessage + */ + private static String getErrorMessage(Exception e) { + if (e == null) { + return null; + } + String host = CURRENT_ADDRESS.get(); + String message = e.getMessage(); + if (Strings.contains(message, Const.TIMEOUT)) { + // 连接超时 + return Strings.format(SessionMessage.CONNECTION_TIMEOUT, host); + } else if (Exceptions.isCausedBy(e, AuthenticationException.class)) { + // 认证失败 + return Strings.format(SessionMessage.AUTHENTICATION_FAILURE, host); + } else if (Exceptions.isCausedBy(e, InvalidArgumentException.class)) { + // 参数错误 + if (Strings.isBlank(message)) { + return Strings.format(SessionMessage.SERVER_UNREACHABLE, host); + } else { + return message; + } + } else { + // 其他错误 + return Strings.format(SessionMessage.SERVER_UNREACHABLE, host); + } + } + +} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java index 538de44c..0ceb98fa 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java @@ -14,6 +14,7 @@ import com.orion.visor.framework.websocket.core.utils.WebSockets; import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO; import com.orion.visor.module.asset.enums.HostConnectStatusEnum; import com.orion.visor.module.asset.enums.HostConnectTypeEnum; +import com.orion.visor.module.asset.handler.host.jsch.SessionStores; import com.orion.visor.module.asset.handler.host.terminal.constant.TerminalMessage; import com.orion.visor.module.asset.handler.host.terminal.enums.OutputTypeEnum; import com.orion.visor.module.asset.handler.host.terminal.model.TerminalConfig; @@ -23,7 +24,6 @@ import com.orion.visor.module.asset.handler.host.terminal.session.ITerminalSessi import com.orion.visor.module.asset.handler.host.terminal.session.SftpSession; import com.orion.visor.module.asset.handler.host.terminal.session.SshSession; import com.orion.visor.module.asset.service.HostConnectLogService; -import com.orion.visor.module.asset.service.HostTerminalService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketSession; @@ -42,9 +42,6 @@ import java.util.Map; @Component public class TerminalConnectHandler extends AbstractTerminalHandler { - @Resource - private HostTerminalService hostTerminalService; - @Resource private HostConnectLogService hostConnectLogService; @@ -117,7 +114,7 @@ public class TerminalConnectHandler extends AbstractTerminalHandler sessions; + private final ConcurrentHashMap hostConnections; + public TransferHandler(WebSocketSession channel) { this.channel = channel; this.sessions = new ConcurrentHashMap<>(); + this.hostConnections = new ConcurrentHashMap<>(); } @Override @@ -54,7 +59,7 @@ public class TransferHandler implements ITransferHandler { } // 处理消息 if (TransferOperator.START.equals(operator)) { - // 开始 + // 开始传输 currentSession.setToken(UUIds.random32()); currentSession.onStart(payload); } else if (TransferOperator.FINISH.equals(operator)) { @@ -85,19 +90,26 @@ public class TransferHandler implements ITransferHandler { TransferType type = TransferType.of(payload.getType()); String sessionKey = hostId + "_" + type.getType(); try { - // 获取会话 - ITransferSession session = sessions.get(sessionKey); - if (session == null) { + // 获取主机连接信息 + HostConnection hostConnection = hostConnections.get(hostId); + if (hostConnection == null) { // 获取主机连接信息 Long userId = WebSockets.getAttr(channel, ExtraFieldConst.USER_ID); HostTerminalConnectDTO connectInfo = hostTerminalService.getTerminalConnectInfo(userId, hostId); - SessionStore sessionStore = hostTerminalService.openSessionStore(connectInfo); + hostConnection = new HostConnection(connectInfo, SessionStores.openSessionStore(connectInfo)); + hostConnections.put(hostId, hostConnection); + } + SessionStore sessionStore = hostConnection.getSessionStore(); + HostTerminalConnectDTO connectInfo = hostConnection.getConnectInfo(); + // 获取会话 + ITransferSession session = sessions.get(sessionKey); + if (session == null) { // 打开会话并初始化 if (TransferType.UPLOAD.equals(type)) { - // 上传操作 + // 上传会话 session = new UploadSession(connectInfo, sessionStore, this.channel); } else if (TransferType.DOWNLOAD.equals(type)) { - // 下载操作 + // 下载会话 session = new DownloadSession(connectInfo, sessionStore, this.channel); } session.init(); diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/HostConnection.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/HostConnection.java new file mode 100644 index 00000000..4a301ed3 --- /dev/null +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/HostConnection.java @@ -0,0 +1,33 @@ +package com.orion.visor.module.asset.handler.host.transfer.model; + +import com.orion.net.host.SessionStore; +import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 主机连接信息 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/7/12 23:52 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class HostConnection { + + /** + * connectInfo + */ + private HostTerminalConnectDTO connectInfo; + + /** + * sessionStore + */ + private SessionStore sessionStore; + +} diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/TransferOperatorRequest.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/TransferOperatorRequest.java index c305bfc6..8a88b551 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/TransferOperatorRequest.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/TransferOperatorRequest.java @@ -38,4 +38,9 @@ public class TransferOperatorRequest { */ private Long hostId; + /** + * 错误信息 后端赋值 + */ + private String errorMessage; + } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/TransferOperatorResponse.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/TransferOperatorResponse.java index 5022e12a..e2b20d64 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/TransferOperatorResponse.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/model/TransferOperatorResponse.java @@ -41,7 +41,12 @@ public class TransferOperatorResponse { /** * 传输的大小 */ - private Integer currentSize; + private Long currentSize; + + /** + * 文件总大小 + */ + private Long totalSize; /** * transferToken diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/DownloadSession.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/DownloadSession.java index 0a9c5bda..9572fd9a 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/DownloadSession.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/DownloadSession.java @@ -18,7 +18,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody; import org.springframework.web.socket.WebSocketSession; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -36,7 +35,7 @@ public class DownloadSession extends TransferSession implements StreamingRespons private static final int FLUSH_COUNT = Const.BUFFER_KB_1 * Const.BUFFER_KB_1 / Const.BUFFER_KB_32; - private InputStream inputStream; + protected InputStream inputStream; public DownloadSession(HostTerminalConnectDTO connectInfo, SessionStore sessionStore, WebSocketSession channel) { super(connectInfo, sessionStore, channel); @@ -90,7 +89,7 @@ public class DownloadSession extends TransferSession implements StreamingRespons byte[] buffer = new byte[BUFFER_SIZE]; int len; int i = 0; - int size = 0; + long size = 0; // 响应文件内容 while (this.inputStream != null && (len = this.inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, len); @@ -101,47 +100,55 @@ public class DownloadSession extends TransferSession implements StreamingRespons } // 首次触发 if (i == 0) { - this.flushAndSendProgress(outputStream, size); + outputStream.flush(); + this.sendProgress(size, null); } i++; } // 最后一次也要 flush if (i != 0) { - this.flushAndSendProgress(outputStream, size); + outputStream.flush(); + this.sendProgress(size, null); } log.info("DownloadSession.download finish channelId: {}, path: {}", channelId, path); } catch (Exception e) { log.error("DownloadSession.download error channelId: {}, path: {}", channelId, path, e); ex.set(e); } - // 异步关闭 - AssetThreadPools.TERMINAL_OPERATOR.execute(() -> { - // 关闭等待 jsch 内部处理 - Threads.sleep(100); - this.closeStream(); - Threads.sleep(100); - // 响应结果 - Exception e = ex.getValue(); - if (e == null) { - TransferUtils.sendMessage(channel, TransferReceiver.FINISH, null); - } else { - TransferUtils.sendMessage(channel, TransferReceiver.ERROR, e); - } + // 传输结束 异步处理 + AssetThreadPools.TERMINAL_OPERATOR.execute(() -> this.onTransferFinish(ex.getValue())); + } + + /** + * 发送进度 + * + * @param currentSize currentSize + * @param totalSize totalSize + */ + protected void sendProgress(Long currentSize, Long totalSize) { + // send + TransferUtils.sendMessage(channel, TransferReceiver.PROGRESS, null, e -> { + e.setCurrentSize(currentSize); + e.setTotalSize(totalSize); }); } /** - * 刷流 & 发送进度 + * 传输完成时候触发 * - * @param outputStream outputStream - * @param size size - * @throws IOException IOException + * @param e e */ - private void flushAndSendProgress(OutputStream outputStream, int size) throws IOException { - // flush - outputStream.flush(); - // send - TransferUtils.sendMessage(channel, TransferReceiver.PROGRESS, null, e -> e.setCurrentSize(size)); + protected void onTransferFinish(Exception e) { + // 关闭等待 jsch 内部处理 + Threads.sleep(100); + this.closeStream(); + Threads.sleep(100); + // 发送消息 + if (e == null) { + TransferUtils.sendMessage(channel, TransferReceiver.FINISH, null); + } else { + TransferUtils.sendMessage(channel, TransferReceiver.ERROR, e); + } } @Override diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/ITransferSession.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/ITransferSession.java index 13a83205..fa6f29d8 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/ITransferSession.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/ITransferSession.java @@ -73,4 +73,11 @@ public interface ITransferSession extends SafeCloseable { */ void setToken(String token); + /** + * 获取 hostId + * + * @return hostId + */ + Long getHostId(); + } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/TransferSession.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/TransferSession.java index 2028afb6..ca9b1925 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/TransferSession.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/TransferSession.java @@ -94,7 +94,7 @@ public abstract class TransferSession implements ITransferSession { log.error("TransferSession.uploadError channelId: {}", channelId); this.closeStream(); // 响应结果 - TransferUtils.sendMessage(channel, TransferReceiver.ERROR, new InvalidArgumentException((String) null)); + TransferUtils.sendMessage(channel, TransferReceiver.ERROR, new InvalidArgumentException(request.getErrorMessage())); } @Override @@ -118,6 +118,11 @@ public abstract class TransferSession implements ITransferSession { Streams.close(sessionStore); } + @Override + public Long getHostId() { + return connectInfo.getHostId(); + } + /** * 保存操作日志 * diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/UploadSession.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/UploadSession.java index 10452f91..458bd22a 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/UploadSession.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/transfer/session/UploadSession.java @@ -24,7 +24,7 @@ import java.io.OutputStream; @Slf4j public class UploadSession extends TransferSession { - private OutputStream outputStream; + protected OutputStream outputStream; public UploadSession(HostTerminalConnectDTO connectInfo, SessionStore sessionStore, WebSocketSession channel) { super(connectInfo, sessionStore, channel); diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/upload/uploader/FileUploader.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/upload/uploader/FileUploader.java index d7b668ea..c6a1f26e 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/upload/uploader/FileUploader.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/handler/host/upload/uploader/FileUploader.java @@ -17,6 +17,7 @@ import com.orion.visor.module.asset.entity.domain.UploadTaskFileDO; import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO; import com.orion.visor.module.asset.enums.HostSshOsTypeEnum; import com.orion.visor.module.asset.enums.UploadTaskFileStatusEnum; +import com.orion.visor.module.asset.handler.host.jsch.SessionStores; import com.orion.visor.module.asset.handler.host.upload.model.FileUploadFileItemDTO; import com.orion.visor.module.asset.service.HostTerminalService; import com.orion.visor.module.asset.utils.SftpUtils; @@ -109,7 +110,7 @@ public class FileUploader implements IFileUploader { HostTerminalConnectDTO connectInfo = hostTerminalService.getTerminalConnectInfo(hostId); this.replaceRemotePathVariable(connectInfo.getOsType(), connectInfo.getUsername()); // 打开会话 - this.sessionStore = hostTerminalService.openSessionStore(connectInfo); + this.sessionStore = SessionStores.openSessionStore(connectInfo); this.executor = sessionStore.getSftpExecutor(connectInfo.getFileNameCharset()); executor.connect(); log.info("HostFileUploader.initSession success taskId: {}, hostId: {}", taskId, hostId); diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/AssetAuthorizedDataService.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/AssetAuthorizedDataService.java index 45baa517..71a29d3a 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/AssetAuthorizedDataService.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/AssetAuthorizedDataService.java @@ -4,7 +4,7 @@ import com.orion.visor.module.asset.entity.request.asset.AssetAuthorizedDataQuer import com.orion.visor.module.asset.entity.vo.AuthorizedHostWrapperVO; import com.orion.visor.module.asset.entity.vo.HostIdentityVO; import com.orion.visor.module.asset.entity.vo.HostKeyVO; -import com.orion.visor.module.asset.enums.HostConfigTypeEnum; +import com.orion.visor.module.asset.enums.HostTypeEnum; import com.orion.visor.module.infra.enums.DataPermissionTypeEnum; import java.util.List; @@ -42,7 +42,7 @@ public interface AssetAuthorizedDataService { * @param type type * @return hostId */ - List getUserAuthorizedHostIdWithEnabledConfig(Long userId, HostConfigTypeEnum type); + List getUserAuthorizedEnabledHostId(Long userId, HostTypeEnum type); /** * 查询用户已授权的主机 diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostConfigService.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostConfigService.java index 5d0505d2..49b6c3e6 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostConfigService.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostConfigService.java @@ -1,10 +1,8 @@ package com.orion.visor.module.asset.service; import com.orion.visor.framework.common.handler.data.model.GenericsDataModel; -import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateRequest; -import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateStatusRequest; -import com.orion.visor.module.asset.entity.vo.HostConfigVO; -import com.orion.visor.module.asset.enums.HostConfigTypeEnum; +import com.orion.visor.module.asset.entity.domain.HostDO; +import com.orion.visor.module.asset.enums.HostTypeEnum; import java.util.List; import java.util.Map; @@ -19,81 +17,43 @@ import java.util.Map; public interface HostConfigService { /** - * 获取配置 + * 获取主机配置 * - * @param hostId hostId - * @param type type - * @return config + * @param id id + * @param type type + * @param T + * @return host */ - HostConfigVO getHostConfig(Long hostId, String type); + T getHostConfig(Long id, HostTypeEnum type); /** - * 获取配置 配置未启用会报错 + * 构建主机配置 * - * @param hostId hostId + * @param host host + * @param type type + * @param T + * @return host + */ + T buildHostConfig(HostDO host, HostTypeEnum type); + + /** + * 获取主机配置 + * + * @param idList idList * @param type type * @param T * @return config */ - T getHostConfig(Long hostId, HostConfigTypeEnum type); + Map getHostConfigMap(List idList, HostTypeEnum type); /** - * 获取配置 + * 构建主机配置 * - * @param hostId hostId + * @param hostList hostList + * @param type type + * @param T * @return config */ - List getHostConfigList(Long hostId); - - /** - * 获取配置 - * - * @param hostIdList hostIdList - * @param type type - * @return config - */ - List getHostConfigList(List hostIdList, String type); - - /** - * 获取配置 - * - * @param hostIdList hostIdList - * @param type type - * @param T - * @return config - */ - Map getHostConfigMap(List hostIdList, HostConfigTypeEnum type); - - /** - * 更新配置 - * - * @param request request - * @return version - */ - Integer updateHostConfig(HostConfigUpdateRequest request); - - /** - * 更新配置状态 - * - * @param request request - * @return version - */ - Integer updateHostConfigStatus(HostConfigUpdateStatusRequest request); - - /** - * 初始化主机配置 - * - * @param hostId hostId - */ - void initHostConfig(Long hostId); - - /** - * 获取启用配置的 hostId - * - * @param type type - * @param hostIdList hostIdList - * @return hostId - */ - List getEnabledConfigHostId(String type, List hostIdList); + Map buildHostConfigMap(List hostList, HostTypeEnum type); } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostService.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostService.java index e94e05a6..cfb7c4bf 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostService.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostService.java @@ -1,9 +1,8 @@ package com.orion.visor.module.asset.service; import com.orion.lang.define.wrapper.DataGrid; -import com.orion.visor.module.asset.entity.request.host.HostCreateRequest; -import com.orion.visor.module.asset.entity.request.host.HostQueryRequest; -import com.orion.visor.module.asset.entity.request.host.HostUpdateRequest; +import com.orion.visor.module.asset.entity.request.host.*; +import com.orion.visor.module.asset.entity.vo.HostConfigVO; import com.orion.visor.module.asset.entity.vo.HostVO; import java.util.List; @@ -33,6 +32,22 @@ public interface HostService { */ Integer updateHostById(HostUpdateRequest request); + /** + * 更新主机状态 + * + * @param request request + * @return effect + */ + Integer updateHostStatus(HostUpdateStatusRequest request); + + /** + * 更新主机配置 + * + * @param request request + * @return effect + */ + Integer updateHostConfig(HostUpdateConfigRequest request); + /** * 通过 id 查询主机 * @@ -41,12 +56,21 @@ public interface HostService { */ HostVO getHostById(Long id); + /** + * 查询主机配置 + * + * @param id id + * @return config + */ + HostConfigVO getHostConfig(Long id); + /** * 查询主机 * + * @param type type * @return rows */ - List getHostListByCache(); + List getHostList(String type); /** * 分页查询主机 @@ -79,4 +103,11 @@ public interface HostService { */ void deleteHostRelByIdListAsync(List idList); + /** + * 获取当前更新配置的 hostId + * + * @return hostId + */ + Long getCurrentUpdateConfigHostId(); + } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostTerminalService.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostTerminalService.java index 9fd134cb..2caf57f1 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostTerminalService.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/HostTerminalService.java @@ -1,6 +1,5 @@ package com.orion.visor.module.asset.service; -import com.orion.net.host.SessionStore; import com.orion.visor.module.asset.entity.domain.HostDO; import com.orion.visor.module.asset.entity.dto.HostTerminalAccessDTO; import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO; @@ -65,20 +64,4 @@ public interface HostTerminalService { */ HostTerminalConnectDTO getTerminalConnectInfo(Long userId, HostDO host); - /** - * 使用默认配置打开主机会话 - * - * @param hostId hostId - * @return session - */ - SessionStore openSessionStore(Long hostId); - - /** - * 打开主机会话 - * - * @param conn conn - * @return session - */ - SessionStore openSessionStore(HostTerminalConnectDTO conn); - } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java index af4dcc8e..5b5953cd 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java @@ -8,11 +8,13 @@ import com.orion.visor.framework.common.constant.Const; import com.orion.visor.framework.common.utils.TreeUtils; import com.orion.visor.framework.common.utils.Valid; import com.orion.visor.module.asset.convert.HostGroupConvert; +import com.orion.visor.module.asset.dao.HostDAO; import com.orion.visor.module.asset.entity.request.asset.AssetAuthorizedDataQueryRequest; import com.orion.visor.module.asset.entity.vo.*; -import com.orion.visor.module.asset.enums.HostConfigTypeEnum; import com.orion.visor.module.asset.enums.HostConnectTypeEnum; import com.orion.visor.module.asset.enums.HostExtraItemEnum; +import com.orion.visor.module.asset.enums.HostStatusEnum; +import com.orion.visor.module.asset.enums.HostTypeEnum; import com.orion.visor.module.asset.handler.host.extra.model.HostLabelExtraModel; import com.orion.visor.module.asset.service.*; import com.orion.visor.module.infra.api.*; @@ -40,6 +42,9 @@ import java.util.stream.Collectors; @Service public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataService { + @Resource + private HostDAO hostDAO; + @Resource private DataGroupApi dataGroupApi; @@ -52,9 +57,6 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic @Resource private HostService hostService; - @Resource - private HostConfigService hostConfigService; - @Resource private HostKeyService hostKeyService; @@ -106,14 +108,14 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic } @Override - public List getUserAuthorizedHostIdWithEnabledConfig(Long userId, HostConfigTypeEnum type) { - // 获取启用的主机 + public List getUserAuthorizedEnabledHostId(Long userId, HostTypeEnum type) { + // 获取有权限的的主机 List hostIdList = this.getUserAuthorizedHostId(userId); if (hostIdList.isEmpty()) { return hostIdList; } - // 获取启用配置的主机 - return hostConfigService.getEnabledConfigHostId(type.name(), hostIdList); + // 获取启用的主机 + return hostDAO.getHostIdList(hostIdList, type.name(), HostStatusEnum.ENABLED.name()); } @SneakyThrows @@ -138,17 +140,17 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic // 查询主机拓展信息 Future> labelExtraResult = dataExtraApi.getExtraItemValuesByCacheAsync(userId, DataExtraTypeEnum.HOST, - HostExtraItemEnum.LABEL.getItem()); + HostExtraItemEnum.LABEL.name()); // 查询分组 List dataGroup = dataGroupApi.getDataGroupList(DataGroupTypeEnum.HOST); // 查询分组引用 Map> dataGroupRel = dataGroupRelApi.getGroupRelList(DataGroupTypeEnum.HOST); - // 过滤掉无分组权限以及未启用配置的主机 + // 过滤掉无分组权限以及未启用的主机 this.filterEnabledAuthorizedHost(dataGroup, dataGroupRel, authorizedGroupIdList, type); // 设置主机分组树 wrapper.setGroupTree(this.getAuthorizedHostGroupTree(dataGroup)); // 设置主机列表 - wrapper.setHostList(this.getAuthorizedHostList(dataGroupRel)); + wrapper.setHostList(this.getAuthorizedHostList(type, dataGroupRel)); // 设置主机分组节点映射 wrapper.setTreeNodes(Maps.map(dataGroupRel, String::valueOf, Function.identity())); // 设置主机拓展信息 @@ -190,7 +192,7 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic /** * 过滤掉未授权的 dataGroupRel 和 dataGroupRel - * 过滤掉未启用配置的 dataGroupRel + * 过滤掉未启用的 dataGroupRel * * @param dataGroup dataGroup * @param dataGroupRel dataGroupRel @@ -208,15 +210,18 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic dataGroup.addAll(new HashSet<>(authorizedDataGroup)); // 移除未授权的分组引用 dataGroupRel.keySet().removeIf(s -> !authorizedGroupIdList.contains(s)); - // 查询配置已启用的主机 - List hostIdList = dataGroupRel.values() + // 查询已启用的主机 + List allHostId = dataGroupRel.values() .stream() .flatMap(Collection::stream) .distinct() .collect(Collectors.toList()); - List enabledConfigHostId = hostConfigService.getEnabledConfigHostId(type, hostIdList); + if (allHostId.isEmpty()) { + return; + } + List hostIdList = hostDAO.getHostIdList(allHostId, type, HostStatusEnum.ENABLED.name()); // 从分组引用中移除未启用的主机 - dataGroupRel.forEach((k, v) -> v.removeIf(s -> !enabledConfigHostId.contains(s))); + dataGroupRel.forEach((k, v) -> v.removeIf(s -> !hostIdList.contains(s))); } /** @@ -238,12 +243,13 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic /** * 查询已授权的主机列表 * + * @param type type * @param dataGroupRel dataGroupRel * @return hosts */ - private List getAuthorizedHostList(Map> dataGroupRel) { + private List getAuthorizedHostList(String type, Map> dataGroupRel) { // 查询主机列表 - Map hostMap = hostService.getHostListByCache() + Map hostMap = hostService.getHostList(type) .stream() .collect(Collectors.toMap(HostVO::getId, Function.identity(), Functions.right())); // 设置已授权的数据 diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecCommandServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecCommandServiceImpl.java index 02474051..296613d8 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecCommandServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecCommandServiceImpl.java @@ -97,7 +97,7 @@ public class ExecCommandServiceImpl implements ExecCommandService { Long userId = user.getId(); List hostIdList = request.getHostIdList(); // 检查主机权限 - List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(userId, HostConfigTypeEnum.SSH); + List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedEnabledHostId(userId, HostTypeEnum.SSH); hostIdList.removeIf(s -> !authorizedHostIdList.contains(s)); log.info("ExecService.startExecCommand host hostList: {}", hostIdList); Valid.notEmpty(hostIdList, ErrorMessage.CHECK_AUTHORIZED_HOST); @@ -117,7 +117,7 @@ public class ExecCommandServiceImpl implements ExecCommandService { // 查询主机信息 List hosts = hostDAO.selectBatchIds(hostIdList); // 查询主机配置 - Map hostConfigMap = hostConfigService.getHostConfigMap(hostIdList, HostConfigTypeEnum.SSH); + Map hostConfigMap = hostConfigService.buildHostConfigMap(hosts, HostTypeEnum.SSH); // 插入日志 ExecLogDO execLog = ExecLogDO.builder() .userId(request.getUserId()) @@ -309,11 +309,11 @@ public class ExecCommandServiceImpl implements ExecCommandService { params.put("hostName", host.getName()); params.put("hostCode", host.getCode()); params.put("hostAddress", host.getAddress()); + params.put("hostPort", host.getPort()); params.put("hostUuid", uuid); params.put("hostUuidShort", uuid.replace("-", Strings.EMPTY)); params.put("hostUsername", config.getUsername()); params.put("osType", config.getOsType()); - params.put("port", config.getPort()); params.put("charset", config.getCharset()); params.put("scriptPath", scriptPath); return params; diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecJobServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecJobServiceImpl.java index 21c902c8..9b44912d 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecJobServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecJobServiceImpl.java @@ -20,14 +20,14 @@ import com.orion.visor.module.asset.dao.ExecLogDAO; import com.orion.visor.module.asset.dao.HostDAO; import com.orion.visor.module.asset.entity.domain.ExecJobDO; import com.orion.visor.module.asset.entity.domain.ExecLogDO; -import com.orion.visor.module.asset.entity.domain.HostDO; import com.orion.visor.module.asset.entity.dto.ExecCommandExecDTO; import com.orion.visor.module.asset.entity.request.exec.*; import com.orion.visor.module.asset.entity.vo.ExecJobVO; import com.orion.visor.module.asset.entity.vo.ExecLogVO; +import com.orion.visor.module.asset.entity.vo.HostBaseVO; import com.orion.visor.module.asset.enums.ExecJobStatusEnum; import com.orion.visor.module.asset.enums.ExecSourceEnum; -import com.orion.visor.module.asset.enums.HostConfigTypeEnum; +import com.orion.visor.module.asset.enums.HostTypeEnum; import com.orion.visor.module.asset.enums.ScriptExecEnum; import com.orion.visor.module.asset.handler.host.exec.job.ExecCommandJob; import com.orion.visor.module.asset.service.AssetAuthorizedDataService; @@ -166,8 +166,11 @@ public class ExecJobServiceImpl implements ExecJobService { vo.setHostIdList(hostIdList); // 查询主机列表 if (!Lists.isEmpty(hostIdList)) { - List hostList = hostDAO.selectBatchIds(hostIdList); - vo.setHostList(HostConvert.MAPPER.toList(hostList)); + List hosts = hostDAO.selectBaseByIdList(hostIdList) + .stream() + .map(HostConvert.MAPPER::toBase) + .collect(Collectors.toList()); + vo.setHostList(hosts); } else { vo.setHostList(Lists.empty()); } @@ -378,7 +381,7 @@ public class ExecJobServiceImpl implements ExecJobService { */ private void checkHostPermission(List hostIdList) { // 查询有权限的主机 - List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(SecurityUtils.getLoginUserId(), HostConfigTypeEnum.SSH); + List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedEnabledHostId(SecurityUtils.getLoginUserId(), HostTypeEnum.SSH); for (Long hostId : hostIdList) { Valid.isTrue(authorizedHostIdList.contains(hostId), Strings.format(ErrorMessage.PLEASE_CHECK_HOST_SSH, hostId)); } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecLogServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecLogServiceImpl.java index 0f0503d6..e015d31f 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecLogServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecLogServiceImpl.java @@ -38,7 +38,7 @@ import com.orion.visor.module.asset.entity.vo.ExecLogStatusVO; import com.orion.visor.module.asset.entity.vo.ExecLogVO; import com.orion.visor.module.asset.enums.ExecHostStatusEnum; import com.orion.visor.module.asset.enums.ExecStatusEnum; -import com.orion.visor.module.asset.enums.HostConfigTypeEnum; +import com.orion.visor.module.asset.enums.HostTypeEnum; import com.orion.visor.module.asset.handler.host.config.model.HostSshConfigModel; import com.orion.visor.module.asset.handler.host.exec.command.handler.IExecCommandHandler; import com.orion.visor.module.asset.handler.host.exec.command.handler.IExecTaskHandler; @@ -360,7 +360,7 @@ public class ExecLogServiceImpl implements ExecLogService { List hostIdList = hostLogs.stream() .map(ExecHostLogDO::getHostId) .collect(Collectors.toList()); - Map configMap = hostConfigService.getHostConfigMap(hostIdList, HostConfigTypeEnum.SSH); + Map configMap = hostConfigService.getHostConfigMap(hostIdList, HostTypeEnum.SSH); // 生成缓存 String token = UUIds.random19(); String cacheKey = ExecCacheKeyDefine.EXEC_TAIL.format(token); diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecTemplateServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecTemplateServiceImpl.java index b3a696a1..482d18c4 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecTemplateServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/ExecTemplateServiceImpl.java @@ -16,7 +16,7 @@ import com.orion.visor.module.asset.entity.request.exec.ExecTemplateCreateReques import com.orion.visor.module.asset.entity.request.exec.ExecTemplateQueryRequest; import com.orion.visor.module.asset.entity.request.exec.ExecTemplateUpdateRequest; import com.orion.visor.module.asset.entity.vo.ExecTemplateVO; -import com.orion.visor.module.asset.enums.HostConfigTypeEnum; +import com.orion.visor.module.asset.enums.HostTypeEnum; import com.orion.visor.module.asset.enums.ScriptExecEnum; import com.orion.visor.module.asset.service.AssetAuthorizedDataService; import com.orion.visor.module.asset.service.ExecTemplateHostService; @@ -113,7 +113,7 @@ public class ExecTemplateServiceImpl implements ExecTemplateService { return template; } // 过滤认证的主机 - List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(SecurityUtils.getLoginUserId(), HostConfigTypeEnum.SSH); + List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedEnabledHostId(SecurityUtils.getLoginUserId(), HostTypeEnum.SSH); hostIdList.removeIf(s -> !authorizedHostIdList.contains(s)); template.setHostIdList(hostIdList); return template; diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostConfigServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostConfigServiceImpl.java index a108fa76..c7f0a55b 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostConfigServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostConfigServiceImpl.java @@ -1,30 +1,23 @@ package com.orion.visor.module.asset.service.impl; import com.orion.lang.function.Functions; -import com.orion.lang.utils.Exceptions; -import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs; -import com.orion.visor.framework.common.constant.Const; import com.orion.visor.framework.common.constant.ErrorMessage; -import com.orion.visor.framework.common.enums.BooleanBit; -import com.orion.visor.framework.common.enums.EnableStatus; import com.orion.visor.framework.common.handler.data.model.GenericsDataModel; -import com.orion.visor.framework.common.handler.data.strategy.GenericsDataStrategy; import com.orion.visor.framework.common.utils.Valid; -import com.orion.visor.module.asset.convert.HostConfigConvert; -import com.orion.visor.module.asset.dao.HostConfigDAO; import com.orion.visor.module.asset.dao.HostDAO; -import com.orion.visor.module.asset.entity.domain.HostConfigDO; import com.orion.visor.module.asset.entity.domain.HostDO; -import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateRequest; -import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateStatusRequest; -import com.orion.visor.module.asset.entity.vo.HostConfigVO; -import com.orion.visor.module.asset.enums.HostConfigTypeEnum; +import com.orion.visor.module.asset.enums.HostStatusEnum; +import com.orion.visor.module.asset.enums.HostTypeEnum; +import com.orion.visor.module.asset.handler.host.config.model.HostSshConfigModel; import com.orion.visor.module.asset.service.HostConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -41,212 +34,49 @@ public class HostConfigServiceImpl implements HostConfigService { @Resource private HostDAO hostDAO; - @Resource - private HostConfigDAO hostConfigDAO; - @Override - public HostConfigVO getHostConfig(Long hostId, String type) { - HostConfigTypeEnum configType = Valid.valid(HostConfigTypeEnum::of, type); - // 查询配置 - HostConfigDO config = hostConfigDAO.getHostConfigByHostId(hostId, type); - Valid.notNull(config, ErrorMessage.CONFIG_ABSENT); - // 转换 - HostConfigVO vo = HostConfigConvert.MAPPER.to(config); - // 获取配置 - Map configMap = configType.toView(config.getConfig()).toMap(); - vo.setConfig(configMap); - return vo; - } - - @Override - public T getHostConfig(Long hostId, HostConfigTypeEnum type) { - // 查询配置 - HostConfigDO config = hostConfigDAO.getHostConfigByHostId(hostId, type.getType()); - if (config == null) { - return null; - } - // 检查配置状态 - if (!BooleanBit.toBoolean(config.getStatus())) { - throw Exceptions.disabled(); - } - return type.parse(config.getConfig()); - } - - @Override - public List getHostConfigList(Long hostId) { - // 查询 - List configs = hostConfigDAO.getHostConfigByHostId(hostId); - return configs.stream() - .map(this::convertHostConfig) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - } - - @Override - public List getHostConfigList(List hostIdList, String type) { - // 查询 - List configs = hostConfigDAO.getHostConfigByHostIdList(hostIdList, type); - // 返回 - return configs.stream() - .map(this::convertHostConfig) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - } - - @Override - public Map getHostConfigMap(List hostIdList, HostConfigTypeEnum type) { - // 查询 - List configs = hostConfigDAO.getHostConfigByHostIdList(hostIdList, type.getType()); - // 返回 - return configs.stream() - .collect(Collectors.toMap( - HostConfigDO::getHostId, - s -> type.parse(s.getConfig()), - Functions.right())); - } - - @Override - public Integer updateHostConfig(HostConfigUpdateRequest request) { - // 查询原配置 - HostConfigDO record = this.getHostConfigByType(request.getHostId(), request.getType()); - Valid.notNull(record, ErrorMessage.CONFIG_ABSENT); - HostConfigTypeEnum type = Valid.valid(HostConfigTypeEnum::of, record.getType()); - GenericsDataModel newConfig = type.parse(request.getConfig()); + public T getHostConfig(Long id, HostTypeEnum type) { // 查询主机 - HostDO host = hostDAO.selectById(record.getHostId()); - Valid.notNull(host, ErrorMessage.HOST_ABSENT); - // 添加日志参数 - OperatorLogs.add(OperatorLogs.REL_ID, host.getId()); - OperatorLogs.add(OperatorLogs.NAME, host.getName()); - OperatorLogs.add(OperatorLogs.TYPE, type.getType()); - // 检查版本 - Valid.eq(record.getVersion(), request.getVersion(), ErrorMessage.DATA_MODIFIED); - GenericsDataStrategy strategy = type.getStrategy(); - GenericsDataModel beforeConfig = type.parse(record.getConfig()); - // 更新前校验 - strategy.doValid(beforeConfig, newConfig); - // 修改配置 - HostConfigDO update = new HostConfigDO(); - update.setId(record.getId()); - update.setVersion(request.getVersion()); - update.setConfig(newConfig.serial()); - int effect = hostConfigDAO.updateById(update); - Valid.version(effect); - return update.getVersion(); + HostDO host = hostDAO.selectById(id); + // 转换为配置 + return this.buildHostConfig(host, type); } @Override - public Integer updateHostConfigStatus(HostConfigUpdateStatusRequest request) { - Long hostId = request.getHostId(); - String type = request.getType(); - Integer status = request.getStatus(); - EnableStatus statusEnum = Valid.valid(EnableStatus::of, status); - HostConfigTypeEnum configType = Valid.valid(HostConfigTypeEnum::of, type); + @SuppressWarnings("unchecked") + public T buildHostConfig(HostDO host, HostTypeEnum type) { + Valid.notNull(host, ErrorMessage.HOST_ABSENT); + // 检查主机类型 + Valid.isTrue(type.name().equals(host.getType()), ErrorMessage.HOST_TYPE_ERROR); + // 检查主机状态 + Valid.isTrue(HostStatusEnum.ENABLED.name().equals(host.getStatus()), ErrorMessage.HOST_NOT_ENABLED); + // 查询主机配置 + HostSshConfigModel model = type.parse(host.getConfig()); + Valid.notNull(model, ErrorMessage.CONFIG_ABSENT); + return (T) model; + } + + @Override + public Map getHostConfigMap(List idList, HostTypeEnum type) { // 查询主机 - HostDO host = hostDAO.selectById(hostId); - Valid.notNull(host, ErrorMessage.HOST_ABSENT); - HostConfigDO config = this.getHostConfigByType(hostId, type); - // 添加日志参数 - OperatorLogs.add(OperatorLogs.REL_ID, host.getId()); - OperatorLogs.add(OperatorLogs.NAME, host.getName()); - OperatorLogs.add(OperatorLogs.STATUS_NAME, statusEnum.name()); - if (config != null) { - // 修改 查询配置 - Integer version = request.getVersion(); - Valid.notNull(version); - // 修改状态 - HostConfigDO update = new HostConfigDO(); - update.setId(config.getId()); - update.setStatus(status); - update.setVersion(version); - update.setUpdateTime(new Date()); - int effect = hostConfigDAO.updateById(update); - Valid.version(effect); - return update.getVersion(); - } else { - // 新增 初始化 - HostConfigDO defaultConfig = this.getDefaultConfig(hostId, configType); - defaultConfig.setStatus(status); - // 插入数据 - hostConfigDAO.insert(defaultConfig); - return defaultConfig.getVersion(); - } - } - - - @Override - public void initHostConfig(Long hostId) { - List configs = Arrays.stream(HostConfigTypeEnum.values()) - .map(s -> this.getDefaultConfig(hostId, s)) - .collect(Collectors.toList()); - hostConfigDAO.insertBatch(configs); - } - - @Override - public List getEnabledConfigHostId(String type, List hostIdList) { - return hostConfigDAO.of() - .createValidateWrapper() - .select(HostConfigDO::getHostId) - .eq(HostConfigDO::getType, type) - .eq(HostConfigDO::getStatus, BooleanBit.TRUE.getValue()) - .in(HostConfigDO::getHostId, hostIdList) - .then() + Map hostMap = hostDAO.selectBatchIds(idList) .stream() - .map(HostConfigDO::getHostId) - .collect(Collectors.toList()); - } - - /** - * 通过类型获取配置 - * - * @param hostId hostId - * @param type type - * @return config - */ - private HostConfigDO getHostConfigByType(Long hostId, String type) { - // 查询配置 - return hostConfigDAO.of() - .createWrapper() - .eq(HostConfigDO::getHostId, hostId) - .eq(HostConfigDO::getType, type) - .then() - .getOne(); - } - - /** - * 获取默认配置 - * - * @param hostId hostId - * @param type type - * @return config - */ - private HostConfigDO getDefaultConfig(Long hostId, HostConfigTypeEnum type) { - HostConfigDO insert = new HostConfigDO(); - insert.setHostId(hostId); - insert.setType(type.getType()); - insert.setStatus(type.getDefaultStatus()); - insert.setConfig(type.getStrategy().getDefault().serial()); - insert.setVersion(Const.DEFAULT_VERSION); - return insert; - } - - /** - * 转化配置 - * - * @param row row - * @return config - */ - private HostConfigVO convertHostConfig(HostConfigDO row) { - // 获取配置 - HostConfigTypeEnum type = HostConfigTypeEnum.of(row.getType()); - if (type == null) { - return null; + .collect(Collectors.toMap(HostDO::getId, Function.identity(), Functions.right())); + // 转换为配置 + Map result = new HashMap<>(); + for (Long id : idList) { + result.put(id, this.buildHostConfig(hostMap.get(id), type)); } - // 转为视图 - HostConfigVO vo = HostConfigConvert.MAPPER.to(row); - Map config = type.toView(row.getConfig()).toMap(); - vo.setConfig(config); - return vo; + return result; + } + + @Override + public Map buildHostConfigMap(List hostList, HostTypeEnum type) { + Map result = new HashMap<>(); + for (HostDO host : hostList) { + result.put(host.getId(), this.buildHostConfig(host, type)); + } + return result; } } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostExtraServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostExtraServiceImpl.java index f825edd4..106105be 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostExtraServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostExtraServiceImpl.java @@ -55,7 +55,7 @@ public class HostExtraServiceImpl implements HostExtraService { DataExtraQueryDTO query = DataExtraQueryDTO.builder() .userId(userId) .relId(hostId) - .item(item.getItem()) + .item(item.name()) .build(); String extraValue = dataExtraApi.getExtraValue(query, DataExtraTypeEnum.HOST); return item.parse(extraValue); @@ -85,7 +85,7 @@ public class HostExtraServiceImpl implements HostExtraService { // 检查初始化 Map> result = Maps.newMap(); for (HostExtraItemEnum extraItem : extraItems) { - String item = extraItem.getItem(); + String item = extraItem.name(); // 检查初始化并转为视图 Map extraValue = this.checkItemAndToView(extraItem, extraValues.get(item), userId, hostId); result.put(item, extraValue); @@ -103,7 +103,7 @@ public class HostExtraServiceImpl implements HostExtraService { DataExtraQueryDTO query = DataExtraQueryDTO.builder() .userId(userId) .relId(hostId) - .item(item.getItem()) + .item(item.name()) .build(); DataExtraDTO beforeExtraItem = dataExtraApi.getExtraItem(query, DataExtraTypeEnum.HOST); if (beforeExtraItem == null) { @@ -152,7 +152,7 @@ public class HostExtraServiceImpl implements HostExtraService { DataExtraSetDTO set = DataExtraSetDTO.builder() .userId(userId) .relId(hostId) - .item(item.getItem()) + .item(item.name()) .value(extraValue) .build(); dataExtraApi.addExtraItem(set, DataExtraTypeEnum.HOST); diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostIdentityServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostIdentityServiceImpl.java index c42b0bdf..4cb1caa2 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostIdentityServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostIdentityServiceImpl.java @@ -17,7 +17,7 @@ import com.orion.visor.framework.redis.core.utils.RedisMaps; import com.orion.visor.framework.redis.core.utils.RedisUtils; import com.orion.visor.framework.redis.core.utils.barrier.CacheBarriers; import com.orion.visor.module.asset.convert.HostIdentityConvert; -import com.orion.visor.module.asset.dao.HostConfigDAO; +import com.orion.visor.module.asset.dao.HostDAO; import com.orion.visor.module.asset.dao.HostIdentityDAO; import com.orion.visor.module.asset.dao.HostKeyDAO; import com.orion.visor.module.asset.define.cache.HostCacheKeyDefine; @@ -62,7 +62,7 @@ public class HostIdentityServiceImpl implements HostIdentityService { private HostKeyDAO hostKeyDAO; @Resource - private HostConfigDAO hostConfigDAO; + private HostDAO hostDAO; @Resource private DataExtraApi dataExtraApi; @@ -209,7 +209,7 @@ public class HostIdentityServiceImpl implements HostIdentityService { // 删除数据库 int effect = hostIdentityDAO.deleteBatchIds(idList); // 删除主机配置 - hostConfigDAO.setIdentityIdWithNull(idList); + hostDAO.setIdentityIdWithNull(idList); // 删除主机身份额外配置 dataExtraApi.deleteHostIdentityExtra(idList); // 删除数据权限 diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostKeyServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostKeyServiceImpl.java index 43cb45ca..9563a51c 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostKeyServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostKeyServiceImpl.java @@ -15,7 +15,7 @@ import com.orion.visor.framework.redis.core.utils.RedisMaps; import com.orion.visor.framework.redis.core.utils.RedisUtils; import com.orion.visor.framework.redis.core.utils.barrier.CacheBarriers; import com.orion.visor.module.asset.convert.HostKeyConvert; -import com.orion.visor.module.asset.dao.HostConfigDAO; +import com.orion.visor.module.asset.dao.HostDAO; import com.orion.visor.module.asset.dao.HostIdentityDAO; import com.orion.visor.module.asset.dao.HostKeyDAO; import com.orion.visor.module.asset.define.cache.HostCacheKeyDefine; @@ -56,7 +56,7 @@ public class HostKeyServiceImpl implements HostKeyService { private HostIdentityDAO hostIdentityDAO; @Resource - private HostConfigDAO hostConfigDAO; + private HostDAO hostDAO; @Resource private DataExtraApi dataExtraApi; @@ -193,7 +193,7 @@ public class HostKeyServiceImpl implements HostKeyService { // 删除关联 hostIdentityDAO.setKeyWithNull(idList); // 删除主机配置 - hostConfigDAO.setKeyIdWithNull(idList); + hostDAO.setKeyIdWithNull(idList); // 删除主机密钥额外配置 dataExtraApi.deleteHostKeyExtra(idList); // 删除数据权限 diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostServiceImpl.java index 3470675e..3d826428 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostServiceImpl.java @@ -10,23 +10,22 @@ import com.orion.spring.SpringHolder; import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs; import com.orion.visor.framework.common.constant.Const; import com.orion.visor.framework.common.constant.ErrorMessage; +import com.orion.visor.framework.common.handler.data.model.GenericsDataModel; import com.orion.visor.framework.common.utils.Valid; import com.orion.visor.framework.redis.core.utils.RedisMaps; -import com.orion.visor.framework.redis.core.utils.RedisUtils; import com.orion.visor.framework.redis.core.utils.barrier.CacheBarriers; import com.orion.visor.module.asset.convert.HostConvert; -import com.orion.visor.module.asset.dao.HostConfigDAO; import com.orion.visor.module.asset.dao.HostDAO; import com.orion.visor.module.asset.define.cache.HostCacheKeyDefine; import com.orion.visor.module.asset.entity.domain.HostDO; import com.orion.visor.module.asset.entity.dto.HostCacheDTO; -import com.orion.visor.module.asset.entity.request.host.HostCreateRequest; -import com.orion.visor.module.asset.entity.request.host.HostQueryRequest; -import com.orion.visor.module.asset.entity.request.host.HostUpdateRequest; +import com.orion.visor.module.asset.entity.request.host.*; +import com.orion.visor.module.asset.entity.vo.HostConfigVO; import com.orion.visor.module.asset.entity.vo.HostVO; +import com.orion.visor.module.asset.enums.HostStatusEnum; +import com.orion.visor.module.asset.enums.HostTypeEnum; import com.orion.visor.module.asset.service.ExecJobHostService; import com.orion.visor.module.asset.service.ExecTemplateHostService; -import com.orion.visor.module.asset.service.HostConfigService; import com.orion.visor.module.asset.service.HostService; import com.orion.visor.module.infra.api.DataExtraApi; import com.orion.visor.module.infra.api.DataGroupRelApi; @@ -45,6 +44,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.Future; import java.util.stream.Collectors; @@ -60,15 +60,11 @@ import java.util.stream.Collectors; @Service public class HostServiceImpl implements HostService { + private static final ThreadLocal CURRENT_UPDATE_CONFIG_ID = new ThreadLocal<>(); + @Resource private HostDAO hostDAO; - @Resource - private HostConfigDAO hostConfigDAO; - - @Resource - private HostConfigService hostConfigService; - @Resource private ExecJobHostService execJobHostService; @@ -89,12 +85,16 @@ public class HostServiceImpl implements HostService { @Override public Long createHost(HostCreateRequest request) { + HostTypeEnum type = Valid.valid(HostTypeEnum::of, request.getType()); log.info("HostService-createHost request: {}", JSON.toJSONString(request)); // 转换 HostDO record = HostConvert.MAPPER.to(request); + record.setStatus(HostStatusEnum.ENABLED.name()); // 查询数据是否冲突 this.checkHostNamePresent(record); this.checkHostCodePresent(record); + // 设置主机配置 + record.setConfig(type.getStrategy().getDefault().serial()); // 插入主机 int effect = hostDAO.insert(record); log.info("HostService-createHost effect: {}", effect); @@ -106,10 +106,8 @@ public class HostServiceImpl implements HostService { if (!Lists.isEmpty(groupIdList)) { dataGroupRelApi.updateRelGroup(DataGroupTypeEnum.HOST, request.getGroupIdList(), id); } - // 创建配置 - hostConfigService.initHostConfig(id); // 删除缓存 - RedisMaps.delete(HostCacheKeyDefine.HOST_INFO); + this.clearCache(); return id; } @@ -118,7 +116,7 @@ public class HostServiceImpl implements HostService { log.info("HostService-updateHostById request: {}", JSON.toJSONString(request)); // 查询 Long id = Valid.notNull(request.getId(), ErrorMessage.ID_MISSING); - HostDO record = hostDAO.selectById(id); + HostDO record = hostDAO.selectBaseById(id); Valid.notNull(record, ErrorMessage.HOST_ABSENT); // 转换 HostDO updateRecord = HostConvert.MAPPER.to(request); @@ -133,10 +131,60 @@ public class HostServiceImpl implements HostService { // 更新 tag tagRelApi.setTagRel(TagTypeEnum.HOST, id, request.getTags()); // 删除缓存 - RedisMaps.delete(HostCacheKeyDefine.HOST_INFO); + this.clearCache(); return effect; } + @Override + public Integer updateHostStatus(HostUpdateStatusRequest request) { + log.info("HostService-updateHostStatus request: {}", JSON.toJSONString(request)); + Long id = request.getId(); + HostStatusEnum status = Valid.valid(HostStatusEnum::of, request.getStatus()); + // 查询主机 + HostDO record = hostDAO.selectBaseById(id); + Valid.notNull(record, ErrorMessage.HOST_ABSENT); + // 更新 + HostDO update = HostDO.builder() + .id(id) + .status(status.name()) + .build(); + int effect = hostDAO.updateById(update); + log.info("HostService-updateHostStatus effect: {}", effect); + // 删除缓存 + this.clearCache(); + return effect; + } + + @Override + public Integer updateHostConfig(HostUpdateConfigRequest request) { + log.info("HostService-updateHostConfig request: {}", JSON.toJSONString(request)); + Long id = request.getId(); + try { + CURRENT_UPDATE_CONFIG_ID.set(id); + // 查询主机信息 + HostDO host = hostDAO.selectById(id); + Valid.notNull(host, ErrorMessage.HOST_ABSENT); + HostTypeEnum type = Valid.valid(HostTypeEnum::of, host.getType()); + GenericsDataModel beforeConfig = type.parse(host.getConfig()); + GenericsDataModel newConfig = type.parse(request.getConfig()); + // 添加日志参数 + OperatorLogs.add(OperatorLogs.ID, id); + OperatorLogs.add(OperatorLogs.NAME, host.getName()); + // 更新前校验 + type.getStrategy().doValid(beforeConfig, newConfig); + // 修改配置 + HostDO updateHost = HostDO.builder() + .id(id) + .config(newConfig.serial()) + .build(); + int effect = hostDAO.updateById(updateHost); + log.info("HostService-updateHostConfig effect: {}", effect); + return effect; + } finally { + CURRENT_UPDATE_CONFIG_ID.remove(); + } + } + @Override @SneakyThrows public HostVO getHostById(Long id) { @@ -145,7 +193,7 @@ public class HostServiceImpl implements HostService { // 查询分组信息 Future> groupIdFuture = dataGroupRelApi.getGroupIdByRelIdAsync(DataGroupTypeEnum.HOST, id); // 查询主机 - HostDO record = hostDAO.selectById(id); + HostDO record = hostDAO.selectBaseById(id); Valid.notNull(record, ErrorMessage.HOST_ABSENT); // 转换 HostVO vo = HostConvert.MAPPER.to(record); @@ -155,16 +203,45 @@ public class HostServiceImpl implements HostService { } @Override - public List getHostListByCache() { + public HostConfigVO getHostConfig(Long id) { + // 查询主机 + HostDO host = hostDAO.selectById(id); + Valid.notNull(host, ErrorMessage.HOST_ABSENT); + // 获取主机类型 + String type = host.getType(); + HostTypeEnum hostType = HostTypeEnum.of(type); + // 获取主机配置 + Map config = hostType.toView(host.getConfig()).toMap(); + // 返回 + return HostConfigVO.builder() + .id(id) + .type(type) + .config(config) + .build(); + } + + @Override + public List getHostList(String type) { // 查询缓存 - List list = RedisMaps.valuesJson(HostCacheKeyDefine.HOST_INFO); + String cacheKey; + if (Strings.isBlank(type)) { + cacheKey = HostCacheKeyDefine.HOST_INFO.format(Const.ALL); + } else { + cacheKey = HostCacheKeyDefine.HOST_INFO.format(type); + } + List list = RedisMaps.valuesJson(cacheKey, HostCacheKeyDefine.HOST_INFO); if (list.isEmpty()) { // 查询数据库 - list = hostDAO.of().list(HostConvert.MAPPER::toCache); + list = hostDAO.of() + .createWrapper(true) + .select(HostDAO.BASE_COLUMN) + .eq(HostDO::getType, type) + .then() + .list(HostConvert.MAPPER::toCache); // 设置屏障 防止穿透 CacheBarriers.checkBarrier(list, HostCacheDTO::new); // 设置缓存 - RedisMaps.putAllJson(HostCacheKeyDefine.HOST_INFO, s -> s.getId().toString(), list); + RedisMaps.putAllJson(cacheKey, HostCacheKeyDefine.HOST_INFO, s -> s.getId().toString(), list); } // 删除屏障 CacheBarriers.removeBarrier(list); @@ -182,10 +259,13 @@ public class HostServiceImpl implements HostService { if (wrapper == null) { return DataGrid.of(Lists.empty()); } + // 数量条件 + LambdaQueryWrapper countWrapper = wrapper.clone(); + wrapper.select(HostDAO.BASE_COLUMN); // 查询 DataGrid hosts = hostDAO.of(wrapper) .page(request) - .dataGrid(HostConvert.MAPPER::to); + .dataGrid(countWrapper, HostConvert.MAPPER::to); // 查询拓展信息 this.setExtraInfo(request, hosts.getRows()); return hosts; @@ -200,18 +280,19 @@ public class HostServiceImpl implements HostService { public Integer deleteHostByIdList(List idList) { log.info("HostService-deleteHostByIdList idList: {}", idList); // 查询 - List hosts = hostDAO.selectBatchIds(idList); + List hosts = hostDAO.selectBaseByIdList(idList); Valid.notEmpty(hosts, ErrorMessage.HOST_ABSENT); // 添加日志参数 String name = hosts.stream() .map(HostDO::getName) .collect(Collectors.joining(Const.COMMA)); OperatorLogs.add(OperatorLogs.NAME, name); + OperatorLogs.add(OperatorLogs.COUNT, hosts.size()); // 删除 int effect = hostDAO.deleteBatchIds(hosts); log.info("HostService-deleteHostByIdList effect: {}", effect); // 删除缓存 - RedisUtils.delete(HostCacheKeyDefine.HOST_INFO); + this.clearCache(); // 删除主机引用 SpringHolder.getBean(HostService.class) .deleteHostRelByIdListAsync(idList); @@ -222,8 +303,6 @@ public class HostServiceImpl implements HostService { @Async("asyncExecutor") public void deleteHostRelByIdListAsync(List idList) { log.info("HostService-deleteHostRelByIdListAsync idList: {}", idList); - // 删除主机配置 - hostConfigDAO.deleteByHostIdList(idList); // 删除计划任务主机 execJobHostService.deleteByHostIdList(idList); // 删除执行模板主机 @@ -238,6 +317,18 @@ public class HostServiceImpl implements HostService { dataExtraApi.deleteByRelIdList(DataExtraTypeEnum.HOST, idList); } + @Override + public Long getCurrentUpdateConfigHostId() { + return CURRENT_UPDATE_CONFIG_ID.get(); + } + + /** + * 清除缓存 + */ + private void clearCache() { + RedisMaps.scanKeysDelete(HostCacheKeyDefine.HOST_INFO.format("*")); + } + /** * 检查 name 是否存在 * @@ -292,6 +383,8 @@ public class HostServiceImpl implements HostService { .like(HostDO::getName, request.getName()) .like(HostDO::getCode, request.getCode()) .like(HostDO::getAddress, request.getAddress()) + .eq(HostDO::getStatus, request.getStatus()) + .eq(HostDO::getType, request.getType()) .and(Strings.isNotEmpty(searchValue), c -> c .eq(HostDO::getId, searchValue).or() .like(HostDO::getName, searchValue).or() diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostTerminalServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostTerminalServiceImpl.java index 3a279328..74b6b051 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostTerminalServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/HostTerminalServiceImpl.java @@ -1,17 +1,10 @@ package com.orion.visor.module.asset.service.impl; import com.alibaba.fastjson.JSONObject; -import com.orion.lang.exception.AuthenticationException; import com.orion.lang.id.UUIds; -import com.orion.lang.utils.Exceptions; -import com.orion.lang.utils.Strings; -import com.orion.net.host.SessionHolder; -import com.orion.net.host.SessionStore; -import com.orion.visor.framework.common.constant.Const; import com.orion.visor.framework.common.constant.ErrorMessage; import com.orion.visor.framework.common.constant.ExtraFieldConst; import com.orion.visor.framework.common.security.LoginUser; -import com.orion.visor.framework.common.utils.CryptoUtils; import com.orion.visor.framework.common.utils.Valid; import com.orion.visor.framework.redis.core.utils.RedisStrings; import com.orion.visor.framework.security.core.utils.SecurityUtils; @@ -123,12 +116,10 @@ public class HostTerminalServiceImpl implements HostTerminalService { log.info("HostConnectService.getTerminalConnectInfo-withHost hostId: {}", hostId); // 查询主机 HostDO host = hostDAO.selectById(hostId); - Valid.notNull(host, ErrorMessage.HOST_ABSENT); // 查询主机配置 - HostSshConfigModel model = hostConfigService.getHostConfig(hostId, HostConfigTypeEnum.SSH); - Valid.notNull(model, ErrorMessage.CONFIG_ABSENT); + HostSshConfigModel config = hostConfigService.buildHostConfig(host, HostTypeEnum.SSH); // 获取配置 - return this.getHostConnectInfo(host, model, null); + return this.getHostConnectInfo(host, config, null); } @Override @@ -136,6 +127,7 @@ public class HostTerminalServiceImpl implements HostTerminalService { // 查询主机 HostDO host = hostDAO.selectById(hostId); Valid.notNull(host, ErrorMessage.HOST_ABSENT); + // 获取配置 return this.getTerminalConnectInfo(userId, host); } @@ -148,8 +140,8 @@ public class HostTerminalServiceImpl implements HostTerminalService { Valid.isTrue(hostIdList.contains(hostId), ErrorMessage.ANY_NO_PERMISSION, DataPermissionTypeEnum.HOST_GROUP.getPermissionName()); - // 查询主机配置 - HostSshConfigModel config = hostConfigService.getHostConfig(hostId, HostConfigTypeEnum.SSH); + // 获取主机配置 + HostSshConfigModel config = hostConfigService.buildHostConfig(host, HostTypeEnum.SSH); Valid.notNull(config, ErrorMessage.CONFIG_ABSENT); // 查询主机额外配置 HostSshExtraModel extra = hostExtraService.getHostExtra(userId, hostId, HostExtraItemEnum.SSH); @@ -173,66 +165,6 @@ public class HostTerminalServiceImpl implements HostTerminalService { return this.getHostConnectInfo(host, config, extra); } - @Override - public SessionStore openSessionStore(Long hostId) { - log.info("HostConnectService.openSessionStore-withHost hostId: {}", hostId); - // 获取配置 - HostTerminalConnectDTO connect = this.getTerminalConnectInfo(hostId); - // 打开连接 - return this.openSessionStore(connect); - } - - @Override - public SessionStore openSessionStore(HostTerminalConnectDTO conn) { - Long hostId = conn.getHostId(); - String address = conn.getHostAddress(); - String username = conn.getUsername(); - log.info("HostConnectService-openSessionStore-start hostId: {}, address: {}, username: {}", hostId, address, username); - try { - SessionHolder sessionHolder = new SessionHolder(); - final boolean useKey = conn.getKeyId() != null; - // 使用密钥认证 - if (useKey) { - // 加载密钥 - String publicKey = Optional.ofNullable(conn.getPublicKey()) - .map(CryptoUtils::decryptAsString) - .orElse(null); - String privateKey = Optional.ofNullable(conn.getPrivateKey()) - .map(CryptoUtils::decryptAsString) - .orElse(null); - String password = Optional.ofNullable(conn.getPrivateKeyPassword()) - .map(CryptoUtils::decryptAsString) - .orElse(null); - sessionHolder.addIdentityValue(String.valueOf(conn.getKeyId()), - privateKey, - publicKey, - password); - } - // 获取会话 - SessionStore session = sessionHolder.getSession(address, conn.getPort(), username); - // 使用密码认证 - if (!useKey) { - session.password(CryptoUtils.decryptAsString(conn.getPassword())); - } - // 连接 - session.connect(conn.getTimeout()); - log.info("HostConnectService-openSessionStore-success hostId: {}, address: {}, username: {}", hostId, address, username); - return session; - } catch (Exception e) { - String message = e.getMessage(); - log.error("HostConnectService-openSessionStore-error hostId: {}, address: {}, username: {}, message: {}", hostId, address, username, message, e); - if (Strings.contains(message, Const.TIMEOUT)) { - // 连接超时 - throw Exceptions.timeout(message, e); - } else if (e instanceof AuthenticationException) { - // 认证失败 - throw Exceptions.authentication(message, e); - } else { - throw e; - } - } - } - /** * 获取主机会话连接配置 * @@ -249,8 +181,8 @@ public class HostTerminalServiceImpl implements HostTerminalService { conn.setHostId(host.getId()); conn.setHostName(host.getName()); conn.setHostAddress(host.getAddress()); + conn.setHostPort(host.getPort()); conn.setOsType(config.getOsType()); - conn.setPort(config.getPort()); conn.setTimeout(config.getConnectTimeout()); conn.setCharset(config.getCharset()); conn.setFileNameCharset(config.getFileNameCharset()); diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/UploadTaskServiceImpl.java b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/UploadTaskServiceImpl.java index 4ad005ab..c9cb2353 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/UploadTaskServiceImpl.java +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/com/orion/visor/module/asset/service/impl/UploadTaskServiceImpl.java @@ -35,7 +35,7 @@ import com.orion.visor.module.asset.entity.request.upload.UploadTaskFileRequest; import com.orion.visor.module.asset.entity.request.upload.UploadTaskQueryRequest; import com.orion.visor.module.asset.entity.request.upload.UploadTaskRequest; import com.orion.visor.module.asset.entity.vo.*; -import com.orion.visor.module.asset.enums.HostConfigTypeEnum; +import com.orion.visor.module.asset.enums.HostTypeEnum; import com.orion.visor.module.asset.enums.UploadTaskFileStatusEnum; import com.orion.visor.module.asset.enums.UploadTaskStatusEnum; import com.orion.visor.module.asset.handler.host.upload.FileUploadTasks; @@ -105,7 +105,7 @@ public class UploadTaskServiceImpl implements UploadTaskService { // 检查主机是否有权限 this.checkHostPermission(hostIdList); // 查询主机信息 - List hosts = hostDAO.selectBatchIds(hostIdList) + List hosts = hostDAO.selectBaseByIdList(hostIdList) .stream() .map(HostConvert.MAPPER::toBase) .collect(Collectors.toList()); @@ -330,7 +330,7 @@ public class UploadTaskServiceImpl implements UploadTaskService { */ private void checkHostPermission(List hostIdList) { // 查询有权限的主机 - List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(SecurityUtils.getLoginUserId(), HostConfigTypeEnum.SSH); + List authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedEnabledHostId(SecurityUtils.getLoginUserId(), HostTypeEnum.SSH); for (Long hostId : hostIdList) { Valid.isTrue(authorizedHostIdList.contains(hostId), Strings.format(ErrorMessage.PLEASE_CHECK_HOST_SSH, hostId)); } diff --git a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/resources/mapper/HostMapper.xml b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/resources/mapper/HostMapper.xml index f6274dac..bf8241c6 100644 --- a/orion-visor-module-asset/orion-visor-module-asset-service/src/main/resources/mapper/HostMapper.xml +++ b/orion-visor-module-asset/orion-visor-module-asset-service/src/main/resources/mapper/HostMapper.xml @@ -5,19 +5,41 @@ + + + + + + + - - - - id, name, code, address, create_time, update_time, creator, updater, deleted + id, type, name, code, address, port, status, config, create_time, update_time, creator, updater, deleted + + UPDATE host + SET config = JSON_REMOVE(config, '$.keyId') + WHERE deleted = 0 + + JSON_CONTAINS(config, JSON_OBJECT('keyId', #{item})) + + + + + UPDATE host + SET config = JSON_REMOVE(config, '$.identityId') + WHERE deleted = 0 + + JSON_CONTAINS(config, JSON_OBJECT('identityId', #{item})) + + + From 4bd2de4ce2594cae57332ff41f7bee12213cb640 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Mon, 22 Jul 2024 19:36:02 +0800 Subject: [PATCH 09/13] =?UTF-8?q?:hammer:=20=E9=87=8D=E6=9E=84=E4=B8=BB?= =?UTF-8?q?=E6=9C=BA=E6=A8=A1=E5=9D=97.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/asset/asset-authorized-data.ts | 4 +- orion-visor-ui/src/api/asset/host-config.ts | 52 ---- orion-visor-ui/src/api/asset/host.ts | 69 ++++- .../src/assets/style/arco-extends.less | 12 +- orion-visor-ui/src/assets/style/layout.less | 30 ++- .../components/host-group.vue | 2 +- .../host/authorized-host-modal/index.vue | 13 +- .../components/asset/host/selector/index.vue | 34 ++- .../src/components/exec/log/const.ts | 28 +- .../components/exec/log/panel/log-appender.ts | 11 +- .../view/card-list/components/card-item.vue | 4 +- .../src/components/view/exec-editor/const.ts | 6 +- .../src/store/modules/cache/index.ts | 9 +- .../src/store/modules/terminal/index.ts | 2 +- orion-visor-ui/src/types/card.ts | 4 +- .../src/types/protocol/terminal.protocol.ts | 242 ++++++++++++++++++ orion-visor-ui/src/types/xterm.ts | 29 +++ .../views/asset-audit/connect-log/index.vue | 2 +- .../asset-audit/connect-session/index.vue | 2 +- .../sftp-log/components/sftp-log-table.vue | 1 + .../src/views/asset-audit/sftp-log/index.vue | 2 +- .../asset/grant/components/host-list.vue | 2 +- .../src/views/asset/grant/index.vue | 2 +- .../components/ssh-config-form.vue | 209 ++++----------- .../views/asset/host-config/drawer/index.vue | 69 +++-- .../views/asset/host-config/types/const.ts | 21 +- .../asset/host-config/types/ssh-form.rules.ts | 11 - .../host-group/components/host-transfer.vue | 2 +- .../components/host-identity-card-list.vue | 28 +- .../components/host-key-card-list.vue | 39 +-- .../host-list/components/host-card-list.vue | 141 +++++++--- .../host-list/components/host-form-modal.vue | 34 ++- .../asset/host-list/components/host-table.vue | 131 ++++++++-- .../src/views/asset/host-list/index.vue | 15 +- .../asset/host-list/types/card.fields.ts | 8 + .../src/views/asset/host-list/types/const.ts | 19 ++ .../views/asset/host-list/types/form.rules.ts | 17 ++ .../asset/host-list/types/table.columns.ts | 21 +- .../batch-upload/components/upload-panel.vue | 1 + .../components/exec-command-panel.vue | 1 + .../src/views/exec/exec-template/index.vue | 1 + .../new-connection/host-group-view.vue | 2 +- .../components/new-connection/hosts-view.vue | 2 +- .../setting/extra/label-setting-form.vue | 2 +- .../components/sftp/sftp-table-header.vue | 17 +- .../terminal/components/sftp/sftp-table.vue | 6 +- .../components/sftp/sftp-upload-modal.vue | 54 ++-- .../terminal/components/sftp/sftp-view.vue | 43 +++- .../components/sftp/types/table.columns.ts | 2 +- .../host/terminal/handler/sftp-session.ts | 2 +- .../handler/sftp-transfer-downloader.ts | 6 +- .../terminal/handler/sftp-transfer-handler.ts | 13 +- .../terminal/handler/sftp-transfer-manager.ts | 37 ++- .../handler/sftp-transfer-uploader.ts | 5 +- .../host/terminal/handler/ssh-session.ts | 16 +- .../host/terminal/handler/terminal-channel.ts | 5 +- .../handler/terminal-output-processor.ts | 29 +-- .../handler/terminal-panel-manager.ts | 18 +- .../handler/terminal-session-manager.ts | 4 +- .../host/terminal/types/terminal.const.ts | 9 +- .../host/terminal/types/terminal.type.ts | 58 +---- .../src/views/job/exec-job/index.vue | 1 + .../dict-key/components/dict-key-table.vue | 2 +- .../views/user/user/types/table.columns.ts | 2 +- 64 files changed, 1062 insertions(+), 603 deletions(-) delete mode 100644 orion-visor-ui/src/api/asset/host-config.ts create mode 100644 orion-visor-ui/src/types/protocol/terminal.protocol.ts create mode 100644 orion-visor-ui/src/types/xterm.ts diff --git a/orion-visor-ui/src/api/asset/asset-authorized-data.ts b/orion-visor-ui/src/api/asset/asset-authorized-data.ts index 237340ad..112c15e3 100644 --- a/orion-visor-ui/src/api/asset/asset-authorized-data.ts +++ b/orion-visor-ui/src/api/asset/asset-authorized-data.ts @@ -1,5 +1,5 @@ import type { HostGroupQueryResponse } from '@/api/asset/host-group'; -import type { HostQueryResponse } from './host'; +import type { HostQueryResponse, HostType } from './host'; import type { HostKeyQueryResponse } from './host-key'; import type { HostIdentityQueryResponse } from './host-identity'; import axios from 'axios'; @@ -17,7 +17,7 @@ export interface AuthorizedHostQueryResponse { /** * 查询当前用户已授权的主机 */ -export function getCurrentAuthorizedHost(type: string) { +export function getCurrentAuthorizedHost(type: HostType) { return axios.get('/asset/authorized-data/current-host', { params: { type } }); } diff --git a/orion-visor-ui/src/api/asset/host-config.ts b/orion-visor-ui/src/api/asset/host-config.ts deleted file mode 100644 index 851b1cbf..00000000 --- a/orion-visor-ui/src/api/asset/host-config.ts +++ /dev/null @@ -1,52 +0,0 @@ -import axios from 'axios'; - -/** - * 主机配置请求 - */ -export interface HostConfigRequest { - hostId?: number; - type?: string; - version?: number; - status?: number; - config?: string; -} - -/** - * 主机配置查询响应 - */ -export interface HostConfigQueryResponse { - id: number; - hostId: number; - type: string; - version: number; - status: number; - config: Record; -} - -/** - * 查询主机配置 - */ -export function getHostConfig(params: HostConfigRequest) { - return axios.get('/asset/host-config/get', { params }); -} - -/** - * 查询全部主机配置 - */ -export function getHostConfigList(hostId: number) { - return axios.get>('/asset/host-config/list', { params: { hostId } }); -} - -/** - * 更新主机配置 - */ -export function updateHostConfig(request: HostConfigRequest) { - return axios.put('/asset/host-config/update', request); -} - -/** - * 更新主机配置状态 - */ -export function updateHostConfigStatus(request: HostConfigRequest) { - return axios.put('/asset/host-config/update-status', request); -} diff --git a/orion-visor-ui/src/api/asset/host.ts b/orion-visor-ui/src/api/asset/host.ts index ef60622d..7221dc06 100644 --- a/orion-visor-ui/src/api/asset/host.ts +++ b/orion-visor-ui/src/api/asset/host.ts @@ -3,13 +3,18 @@ import type { TableData } from '@arco-design/web-vue/es/table/interface'; import axios from 'axios'; import qs from 'query-string'; +// 主机类型 +export type HostType = 'SSH' | string | undefined; + /** * 主机创建请求 */ export interface HostCreateRequest { + type?: string; name?: string; code?: string; address?: string; + port?: number; tags?: Array; groupIdList?: Array; } @@ -21,15 +26,33 @@ export interface HostUpdateRequest extends HostCreateRequest { id?: number; } +/** + * 主机更新状态请求 + */ +export interface HostUpdateStatusRequest { + id: number; + status: string; +} + +/** + * 主机更新配置请求 + */ +export interface HostUpdateConfigRequest { + id: number; + config: string; +} + /** * 主机查询请求 */ export interface HostQueryRequest extends Pagination { searchValue?: string; id?: number; + type?: string; name?: string; code?: string; address?: string; + status?: string; tags?: Array; queryTag?: boolean; } @@ -39,9 +62,12 @@ export interface HostQueryRequest extends Pagination { */ export interface HostQueryResponse extends TableData, HostQueryResponseExtra { id: number; + type: string; name: string; code: string; address: string; + port: string; + status: string; createTime: number; updateTime: number; creator: string; @@ -62,6 +88,22 @@ export interface HostQueryResponseExtra { modCount: number; } +/** + * 主机 配置查询响应 + */ +export interface HostConfigQueryResponse extends HostConfigQueryResponseExtra { + id: number; + type: string; + config: Record; +} + +/** + * 主机配置拓展 + */ +export interface HostConfigQueryResponseExtra { + current: number; +} + /** * 创建主机 */ @@ -77,7 +119,21 @@ export function updateHost(request: HostUpdateRequest) { } /** - * 通过 id 查询主机 + * 通过 id 更新主机状态 + */ +export function updateHostStatus(request: HostUpdateStatusRequest) { + return axios.put('/asset/host/update-status', request); +} + +/** + * 通过 id 更新主机配置 + */ +export function updateHostConfig(request: HostUpdateConfigRequest) { + return axios.put('/asset/host/update-config', request); +} + +/** + * 查询主机 */ export function getHost(id: number) { return axios.get('/asset/host/get', { params: { id } }); @@ -86,8 +142,15 @@ export function getHost(id: number) { /** * 查询全部主机 */ -export function getHostList() { - return axios.get>('/asset/host/list'); +export function getHostList(type: HostType) { + return axios.get>('/asset/host/list', { params: { type } }); +} + +/** + * 通过 id 查询主机配置 + */ +export function getHostConfig(id: number) { + return axios.get('/asset/host/get-config', { params: { id } }); } /** diff --git a/orion-visor-ui/src/assets/style/arco-extends.less b/orion-visor-ui/src/assets/style/arco-extends.less index 57760b59..386470a9 100644 --- a/orion-visor-ui/src/assets/style/arco-extends.less +++ b/orion-visor-ui/src/assets/style/arco-extends.less @@ -30,12 +30,20 @@ border-radius: 50%; background-color: rgb(var(--blue-6)); + &.normal { + color: rgb(var(--arcoblue-6)); + } + &.pass { - background-color: rgb(var(--green-6)); + color: rgb(var(--green-6)); + } + + &.warn { + color: rgb(var(--orange-6)); } &.error { - background-color: rgb(var(--red-6)); + color: rgb(var(--red-6)); } } } diff --git a/orion-visor-ui/src/assets/style/layout.less b/orion-visor-ui/src/assets/style/layout.less index b6d8bb62..9f9128db 100644 --- a/orion-visor-ui/src/assets/style/layout.less +++ b/orion-visor-ui/src/assets/style/layout.less @@ -67,7 +67,7 @@ } // -- drawer -.drawer-form-small{ +.drawer-form-small { padding: 20px 20px 2px 20px; } @@ -185,3 +185,31 @@ background: var(--color-bg-2); border-radius: 4px; } + +// -- doption +.more-doption { + min-width: 42px; + padding: 0 4px; + font-size: 12px; + display: inline-block; + + svg { + margin-right: 2px; + } + + &.normal { + color: rgb(var(--arcoblue-6)); + } + + &.pass { + color: rgb(var(--green-6)); + } + + &.warn { + color: rgb(var(--orange-6)); + } + + &.error { + color: rgb(var(--red-6)); + } +} diff --git a/orion-visor-ui/src/components/asset/host/authorized-host-modal/components/host-group.vue b/orion-visor-ui/src/components/asset/host/authorized-host-modal/components/host-group.vue index 059d86f1..54757e97 100644 --- a/orion-visor-ui/src/components/asset/host/authorized-host-modal/components/host-group.vue +++ b/orion-visor-ui/src/components/asset/host/authorized-host-modal/components/host-group.vue @@ -18,7 +18,7 @@ + empty-message="当前分组内无授权主机!" /> diff --git a/orion-visor-ui/src/components/asset/host/authorized-host-modal/index.vue b/orion-visor-ui/src/components/asset/host/authorized-host-modal/index.vue index 952758d9..1775c142 100644 --- a/orion-visor-ui/src/components/asset/host/authorized-host-modal/index.vue +++ b/orion-visor-ui/src/components/asset/host/authorized-host-modal/index.vue @@ -79,6 +79,7 @@ import type { SelectOptionData } from '@arco-design/web-vue'; import type { AuthorizedHostQueryResponse } from '@/api/asset/asset-authorized-data'; import type { HostQueryResponse } from '@/api/asset/host'; + import type { HostType } from '@/api/asset/host'; import { onMounted, ref, watch, computed } from 'vue'; import { dataColor } from '@/utils'; import { dictKeys, NewConnectionType, newConnectionTypeKey } from './types/const'; @@ -92,6 +93,12 @@ import HostTable from './components/host-table.vue'; import HostGroup from './components/host-group.vue'; + const props = withDefaults(defineProps>(), { + type: undefined, + }); + const emits = defineEmits(['selected']); const { toRadioOptions, loadKeys } = useDictStore(); @@ -110,10 +117,10 @@ const emptyMessage = computed(() => { if (newConnectionType.value === NewConnectionType.LIST) { // 列表 - return '无授权主机/主机未启用 SSH 配置!'; + return '无授权主机!'; } else if (newConnectionType.value === NewConnectionType.FAVORITE) { // 收藏 - return '无收藏主机/主机未启用 SSH 配置!'; + return '无收藏主机!'; } else if (newConnectionType.value === NewConnectionType.LATEST) { // 最近连接 return '暂无连接记录!'; @@ -144,7 +151,7 @@ setLoading(true); try { // 加载主机列表 - const { data } = await getCurrentAuthorizedHost('ssh'); + const { data } = await getCurrentAuthorizedHost(props.type); hosts.value = data; // 禁用别名 data.hostList.forEach(s => s.alias = undefined as unknown as string); diff --git a/orion-visor-ui/src/components/asset/host/selector/index.vue b/orion-visor-ui/src/components/asset/host/selector/index.vue index 32f02271..adb46530 100644 --- a/orion-visor-ui/src/components/asset/host/selector/index.vue +++ b/orion-visor-ui/src/components/asset/host/selector/index.vue @@ -2,6 +2,7 @@ @@ -14,22 +15,30 @@ diff --git a/orion-visor-ui/src/views/asset-audit/connect-session/index.vue b/orion-visor-ui/src/views/asset-audit/connect-session/index.vue index 7014e8ed..2033d5a0 100644 --- a/orion-visor-ui/src/views/asset-audit/connect-session/index.vue +++ b/orion-visor-ui/src/views/asset-audit/connect-session/index.vue @@ -29,7 +29,7 @@ // 重置缓存 onUnmounted(() => { const cacheStore = useCacheStore(); - cacheStore.reset('users', 'hosts'); + cacheStore.reset('users'); }); diff --git a/orion-visor-ui/src/views/asset-audit/sftp-log/components/sftp-log-table.vue b/orion-visor-ui/src/views/asset-audit/sftp-log/components/sftp-log-table.vue index 7f7c8a93..1ba0b40c 100644 --- a/orion-visor-ui/src/views/asset-audit/sftp-log/components/sftp-log-table.vue +++ b/orion-visor-ui/src/views/asset-audit/sftp-log/components/sftp-log-table.vue @@ -16,6 +16,7 @@ diff --git a/orion-visor-ui/src/views/asset-audit/sftp-log/index.vue b/orion-visor-ui/src/views/asset-audit/sftp-log/index.vue index 8f6d4b0c..76f540a0 100644 --- a/orion-visor-ui/src/views/asset-audit/sftp-log/index.vue +++ b/orion-visor-ui/src/views/asset-audit/sftp-log/index.vue @@ -29,7 +29,7 @@ // 重置缓存 onUnmounted(() => { const cacheStore = useCacheStore(); - cacheStore.reset('users', 'hosts'); + cacheStore.reset('users'); }); diff --git a/orion-visor-ui/src/views/asset/grant/components/host-list.vue b/orion-visor-ui/src/views/asset/grant/components/host-list.vue index ae0d2418..bb3eb349 100644 --- a/orion-visor-ui/src/views/asset/grant/components/host-list.vue +++ b/orion-visor-ui/src/views/asset/grant/components/host-list.vue @@ -58,7 +58,7 @@ try { setLoading(true); const { data } = await getHostGroupRelList(groupId as number); - const hosts = await cacheStore.loadHosts(); + const hosts = await cacheStore.loadHosts(undefined); selectedGroupHosts.value = data.map(s => hosts.find(h => h.id === s) as HostQueryResponse) .filter(Boolean); } catch (e) { diff --git a/orion-visor-ui/src/views/asset/grant/index.vue b/orion-visor-ui/src/views/asset/grant/index.vue index 1b7e0d87..ee9f0f01 100644 --- a/orion-visor-ui/src/views/asset/grant/index.vue +++ b/orion-visor-ui/src/views/asset/grant/index.vue @@ -51,7 +51,7 @@ // 卸载时清除 cache onUnmounted(() => { - cacheStore.reset('users', 'roles', 'hosts', 'hostGroups', 'hostKeys', 'hostIdentities'); + cacheStore.reset('users', 'roles', 'hostGroups', 'hostKeys', 'hostIdentities'); }); diff --git a/orion-visor-ui/src/views/asset/host-config/components/ssh-config-form.vue b/orion-visor-ui/src/views/asset/host-config/components/ssh-config-form.vue index 11af8acb..db9ab9e5 100644 --- a/orion-visor-ui/src/views/asset/host-config/components/ssh-config-form.vue +++ b/orion-visor-ui/src/views/asset/host-config/components/ssh-config-form.vue @@ -1,20 +1,25 @@ @@ -151,38 +126,26 @@ diff --git a/orion-visor-ui/src/views/asset/host-config/drawer/index.vue b/orion-visor-ui/src/views/asset/host-config/drawer/index.vue index 90bfc393..ff8fcf1b 100644 --- a/orion-visor-ui/src/views/asset/host-config/drawer/index.vue +++ b/orion-visor-ui/src/views/asset/host-config/drawer/index.vue @@ -11,15 +11,15 @@ + :host-config="hostConfig" + @save="save" + @reset="reset" /> @@ -31,14 +31,14 @@ diff --git a/orion-visor-ui/src/views/asset/host-config/types/const.ts b/orion-visor-ui/src/views/asset/host-config/types/const.ts index 02553a9d..c949d0c6 100644 --- a/orion-visor-ui/src/views/asset/host-config/types/const.ts +++ b/orion-visor-ui/src/views/asset/host-config/types/const.ts @@ -1,19 +1,11 @@ -// 主机所有配置 -export interface HostConfigWrapper { - ssh: HostSshConfig; - - [key: string]: unknown; -} - // 主机 SSH 配置 export interface HostSshConfig { osType?: string; - port?: number; username?: string; password?: string; authType?: string; - identityId?: number; keyId?: number; + identityId?: number; connectTimeout?: number; charset?: string; fileNameCharset?: string; @@ -32,17 +24,6 @@ export const SshAuthType = { IDENTITY: 'IDENTITY' }; -// 主机系统版本 -export const SshOsType = { - LINUX: 'LINUX', - WINDOWS: 'WINDOWS', -}; - -// 主机配置类型 -export const HostConfigType = { - SSH: 'ssh' -}; - // 主机验证方式 字典项 export const sshAuthTypeKey = 'hostSshAuthType'; diff --git a/orion-visor-ui/src/views/asset/host-config/types/ssh-form.rules.ts b/orion-visor-ui/src/views/asset/host-config/types/ssh-form.rules.ts index c7d7a215..772d9268 100644 --- a/orion-visor-ui/src/views/asset/host-config/types/ssh-form.rules.ts +++ b/orion-visor-ui/src/views/asset/host-config/types/ssh-form.rules.ts @@ -5,16 +5,6 @@ export const osType = [{ message: '请选择系统类型' }] as FieldRule[]; -export const port = [{ - required: true, - message: '请输入SSH端口' -}, { - type: 'number', - min: 1, - max: 65535, - message: '输入的端口不合法' -}] as FieldRule[]; - export const authType = [{ required: true, message: '请选择认证方式' @@ -66,7 +56,6 @@ export const fileContentCharset = [{ export default { osType, - port, authType, keyId, identityId, diff --git a/orion-visor-ui/src/views/asset/host-group/components/host-transfer.vue b/orion-visor-ui/src/views/asset/host-group/components/host-transfer.vue index 2aa73e8f..6bbcc899 100644 --- a/orion-visor-ui/src/views/asset/host-group/components/host-transfer.vue +++ b/orion-visor-ui/src/views/asset/host-group/components/host-transfer.vue @@ -112,7 +112,7 @@ }); onMounted(() => { - cacheStore.loadHosts().then(hosts => { + cacheStore.loadHosts(undefined).then(hosts => { data.value = hosts.map(s => { return { value: String(s.id), diff --git a/orion-visor-ui/src/views/asset/host-identity/components/host-identity-card-list.vue b/orion-visor-ui/src/views/asset/host-identity/components/host-identity-card-list.vue index 80e177b7..c78e711b 100644 --- a/orion-visor-ui/src/views/asset/host-identity/components/host-identity-card-list.vue +++ b/orion-visor-ui/src/views/asset/host-identity/components/host-identity-card-list.vue @@ -2,7 +2,7 @@ - - 修改 + + 修改 + - - 删除 + + 删除 + - - diff --git a/orion-visor-ui/src/views/asset/host-key/components/host-key-card-list.vue b/orion-visor-ui/src/views/asset/host-key/components/host-key-card-list.vue index 650c8b15..c871df2f 100644 --- a/orion-visor-ui/src/views/asset/host-key/components/host-key-card-list.vue +++ b/orion-visor-ui/src/views/asset/host-key/components/host-key-card-list.vue @@ -2,7 +2,7 @@ - - 详情 + + 详情 + - - 修改 + + 修改 + - - 删除 + + 删除 + - - diff --git a/orion-visor-ui/src/views/asset/host-list/components/host-card-list.vue b/orion-visor-ui/src/views/asset/host-list/components/host-card-list.vue index 99bcfc34..644a488f 100644 --- a/orion-visor-ui/src/views/asset/host-list/components/host-card-list.vue +++ b/orion-visor-ui/src/views/asset/host-list/components/host-card-list.vue @@ -2,7 +2,7 @@ + + + + + + + + {{ record.code }} + + + + - - @@ -169,24 +198,25 @@ import type { HostQueryRequest, HostQueryResponse } from '@/api/asset/host'; import { usePagination, useColLayout } from '@/types/card'; import { computed, reactive, ref, onMounted } from 'vue'; - import useLoading from '@/hooks/loading'; import { dataColor, objectTruthKeyCount, resetObject } from '@/utils'; - import fieldConfig from '../types/card.fields'; - import { deleteHost, getHostPage } from '@/api/asset/host'; + import { deleteHost, getHostPage, updateHostStatus } from '@/api/asset/host'; import { Message, Modal } from '@arco-design/web-vue'; - import { tagColor } from '../types/const'; + import { hostStatusKey, hostTypeKey, tagColor } from '../types/const'; import { copy } from '@/hooks/copy'; + import { useDictStore } from '@/store'; import { GrantKey, GrantRouteName } from '@/views/asset/grant/types/const'; + import useLoading from '@/hooks/loading'; + import fieldConfig from '../types/card.fields'; import TagMultiSelector from '@/components/meta/tag/multi-selector/index.vue'; - const emits = defineEmits(['openAdd', 'openUpdate', 'openUpdateConfig', 'openHostGroup']); - - const list = ref([]); + const emits = defineEmits(['openAdd', 'openUpdate', 'openUpdateConfig', 'openHostGroup', 'openCopy']); const cardColLayout = useColLayout(); const pagination = usePagination(); const { loading, setLoading } = useLoading(); + const { toOptions, getDictValue, toggleDictValue, toggleDict } = useDictStore(); + const list = ref([]); const formRef = ref(); const formModel = reactive({ searchValue: undefined, @@ -194,6 +224,8 @@ name: undefined, code: undefined, address: undefined, + type: undefined, + status: undefined, tags: undefined, queryTag: true }); @@ -203,6 +235,33 @@ return objectTruthKeyCount(formModel, ['searchValue', 'queryTag']); }); + // 更新状态 + const updateStatus = async (record: HostQueryResponse) => { + const dict = toggleDict(hostStatusKey, record.status); + Modal.confirm({ + title: `${dict.label}确认`, + titleAlign: 'start', + content: `确定要${dict.label}该主机吗?`, + okText: '确定', + onOk: async () => { + try { + setLoading(true); + const newStatus = dict.value as string; + // 调用修改接口 + await updateHostStatus({ + id: record.id, + status: newStatus, + }); + record.status = newStatus; + Message.success(`已${dict.label}`); + } catch (e) { + } finally { + setLoading(false); + } + } + }); + }; + // 删除当前行 const deleteRow = (id: number) => { Modal.confirm({ @@ -273,4 +332,8 @@ diff --git a/orion-visor-ui/src/views/asset/host-list/components/host-form-modal.vue b/orion-visor-ui/src/views/asset/host-list/components/host-form-modal.vue index 09ba1654..d45e2286 100644 --- a/orion-visor-ui/src/views/asset/host-list/components/host-form-modal.vue +++ b/orion-visor-ui/src/views/asset/host-list/components/host-form-modal.vue @@ -18,6 +18,15 @@ label-align="right" :auto-label-width="true" :rules="formRules"> + + + + @@ -30,6 +39,12 @@ + + + + { return { id: undefined, + type: hostType.SSH.type, name: undefined, code: undefined, address: undefined, + port: hostType.SSH.default.port, tags: undefined, groupIdList: undefined, }; @@ -108,13 +127,22 @@ await fetchHostRender(id); }; + // 打开复制 + const openCopy = async (id: number) => { + title.value = '复制主机'; + isAddHandle.value = true; + renderForm({ ...defaultForm() }); + setVisible(true); + await fetchHostRender(id); + }; + // 渲染主机 const fetchHostRender = async (id: number) => { try { setLoading(true); const { data } = await getHost(id); const detail = Object.assign({} as Record, - pick(data, 'id', 'name', 'code', 'address', 'groupIdList')); + pick(data, 'id', 'type', 'name', 'code', 'address', 'port', 'status', 'groupIdList')); // tag const tags = (data.tags || []).map(s => s.id); // 渲染 @@ -130,7 +158,7 @@ formModel.value = Object.assign({}, record); }; - defineExpose({ openAdd, openUpdate }); + defineExpose({ openAdd, openUpdate, openCopy }); // tag 超出所选限制 const onLimitedTag = (count: number, message: string) => { diff --git a/orion-visor-ui/src/views/asset/host-list/components/host-table.vue b/orion-visor-ui/src/views/asset/host-list/components/host-table.vue index 31370702..411239d3 100644 --- a/orion-visor-ui/src/views/asset/host-list/components/host-table.vue +++ b/orion-visor-ui/src/views/asset/host-list/components/host-table.vue @@ -25,6 +25,20 @@ + + + + + + + + - + + + + + @@ -183,43 +237,72 @@ diff --git a/orion-visor-ui/src/views/asset/host-list/types/card.fields.ts b/orion-visor-ui/src/views/asset/host-list/types/card.fields.ts index f0aa2346..236a070e 100644 --- a/orion-visor-ui/src/views/asset/host-list/types/card.fields.ts +++ b/orion-visor-ui/src/views/asset/host-list/types/card.fields.ts @@ -9,6 +9,10 @@ const fieldConfig = { label: 'id', dataIndex: 'id', slotName: 'id', + }, { + label: '主机类型', + dataIndex: 'type', + slotName: 'type', }, { label: '主机编码', dataIndex: 'code', @@ -18,6 +22,10 @@ const fieldConfig = { dataIndex: 'address', slotName: 'address', tooltip: true, + }, { + label: '主机状态', + dataIndex: 'status', + slotName: 'status', }, { label: '主机标签', dataIndex: 'tags', diff --git a/orion-visor-ui/src/views/asset/host-list/types/const.ts b/orion-visor-ui/src/views/asset/host-list/types/const.ts index c23e8139..f41859e0 100644 --- a/orion-visor-ui/src/views/asset/host-list/types/const.ts +++ b/orion-visor-ui/src/views/asset/host-list/types/const.ts @@ -6,3 +6,22 @@ export const tagColor = [ 'pinkpurple', 'magenta' ]; + +// 主机类型 +export const hostType = { + SSH: { + type: 'SSH', + default: { + port: 22, + } + } +}; + +// 主机类型 字典项 +export const hostTypeKey = 'hostType'; + +// 主机状态 字典项 +export const hostStatusKey = 'hostStatus'; + +// 加载的字典值 +export const dictKeys = [hostTypeKey, hostStatusKey]; diff --git a/orion-visor-ui/src/views/asset/host-list/types/form.rules.ts b/orion-visor-ui/src/views/asset/host-list/types/form.rules.ts index f45d9e53..91b1a0a1 100644 --- a/orion-visor-ui/src/views/asset/host-list/types/form.rules.ts +++ b/orion-visor-ui/src/views/asset/host-list/types/form.rules.ts @@ -1,5 +1,10 @@ import type { FieldRule } from '@arco-design/web-vue'; +export const type = [{ + required: true, + message: '请选择主机类型' +}] as FieldRule[]; + export const name = [{ required: true, message: '请输入主机名称' @@ -24,14 +29,26 @@ export const address = [{ message: '主机地址长度不能大于128位' }] as FieldRule[]; +export const port = [{ + required: true, + message: '请输入主机端口' +}, { + type: 'number', + min: 1, + max: 65535, + message: '输入的端口不合法' +}] as FieldRule[]; + export const tags = [{ maxLength: 5, message: '最多选择5个标签' }] as FieldRule[]; export default { + type, name, code, address, + port, tags, } as Record; diff --git a/orion-visor-ui/src/views/asset/host-list/types/table.columns.ts b/orion-visor-ui/src/views/asset/host-list/types/table.columns.ts index 9d54dabd..a718dafa 100644 --- a/orion-visor-ui/src/views/asset/host-list/types/table.columns.ts +++ b/orion-visor-ui/src/views/asset/host-list/types/table.columns.ts @@ -5,7 +5,7 @@ const columns = [ title: 'id', dataIndex: 'id', slotName: 'id', - width: 100, + width: 68, align: 'left', fixed: 'left', }, { @@ -13,20 +13,37 @@ const columns = [ dataIndex: 'name', slotName: 'name', ellipsis: true, - tooltip: true + tooltip: true, + minWidth: 238, }, { title: '主机编码', dataIndex: 'code', slotName: 'code', + minWidth: 120, + }, { + title: '主机类型', + dataIndex: 'type', + slotName: 'type', + align: 'center', + width: 88, }, { title: '主机地址', dataIndex: 'address', slotName: 'address', + minWidth: 238 }, { title: '主机标签', dataIndex: 'tags', slotName: 'tags', align: 'left', + minWidth: 148, + }, { + title: '主机状态', + dataIndex: 'status', + slotName: 'status', + width: 88, + align: 'center', + fixed: 'right', }, { title: '操作', slotName: 'handle', diff --git a/orion-visor-ui/src/views/exec/batch-upload/components/upload-panel.vue b/orion-visor-ui/src/views/exec/batch-upload/components/upload-panel.vue index 0e970ad2..542d90f5 100644 --- a/orion-visor-ui/src/views/exec/batch-upload/components/upload-panel.vue +++ b/orion-visor-ui/src/views/exec/batch-upload/components/upload-panel.vue @@ -38,6 +38,7 @@ diff --git a/orion-visor-ui/src/views/exec/exec-command/components/exec-command-panel.vue b/orion-visor-ui/src/views/exec/exec-command/components/exec-command-panel.vue index bb81b34d..eb436f59 100644 --- a/orion-visor-ui/src/views/exec/exec-command/components/exec-command-panel.vue +++ b/orion-visor-ui/src/views/exec/exec-command/components/exec-command-panel.vue @@ -107,6 +107,7 @@ @selected="setWithTemplate" /> diff --git a/orion-visor-ui/src/views/exec/exec-template/index.vue b/orion-visor-ui/src/views/exec/exec-template/index.vue index a755ce3d..11546c52 100644 --- a/orion-visor-ui/src/views/exec/exec-template/index.vue +++ b/orion-visor-ui/src/views/exec/exec-template/index.vue @@ -15,6 +15,7 @@ @open-host="(e) => openHostModal('exec', e)" /> diff --git a/orion-visor-ui/src/views/host/terminal/components/new-connection/host-group-view.vue b/orion-visor-ui/src/views/host/terminal/components/new-connection/host-group-view.vue index c15faa64..acfaa4e0 100644 --- a/orion-visor-ui/src/views/host/terminal/components/new-connection/host-group-view.vue +++ b/orion-visor-ui/src/views/host/terminal/components/new-connection/host-group-view.vue @@ -17,7 +17,7 @@ + empty-value="当前分组内无授权主机!" /> diff --git a/orion-visor-ui/src/views/host/terminal/components/new-connection/hosts-view.vue b/orion-visor-ui/src/views/host/terminal/components/new-connection/hosts-view.vue index 3b407291..63635539 100644 --- a/orion-visor-ui/src/views/host/terminal/components/new-connection/hosts-view.vue +++ b/orion-visor-ui/src/views/host/terminal/components/new-connection/hosts-view.vue @@ -49,7 +49,7 @@ const emptyMessage = computed(() => { if (props.newConnectionType === NewConnectionType.LIST) { // 列表 - return '无授权主机/主机未启用 SSH 配置!'; + return '无授权主机!'; } else if (props.newConnectionType === NewConnectionType.FAVORITE) { // 收藏 return '无收藏记录, 快去点击主机右侧的⭐进行收藏吧!'; diff --git a/orion-visor-ui/src/views/host/terminal/components/setting/extra/label-setting-form.vue b/orion-visor-ui/src/views/host/terminal/components/setting/extra/label-setting-form.vue index 6d239ae3..d98b761f 100644 --- a/orion-visor-ui/src/views/host/terminal/components/setting/extra/label-setting-form.vue +++ b/orion-visor-ui/src/views/host/terminal/components/setting/extra/label-setting-form.vue @@ -49,7 +49,7 @@ const { toOptions } = useDictStore(); const formModel = ref({ - color: '' + color: '', }); // 渲染表单 diff --git a/orion-visor-ui/src/views/host/terminal/components/sftp/sftp-table-header.vue b/orion-visor-ui/src/views/host/terminal/components/sftp/sftp-table-header.vue index 0e1a2abc..d62f243d 100644 --- a/orion-visor-ui/src/views/host/terminal/components/sftp/sftp-table-header.vue +++ b/orion-visor-ui/src/views/host/terminal/components/sftp/sftp-table-header.vue @@ -216,7 +216,7 @@ selectedFiles: Array; }>(); - const emits = defineEmits(['update:selectedFiles', 'loadFile', 'download', 'setLoading']); + const emits = defineEmits(['loadFile', 'download', 'deleteFile', 'setLoading']); const showHiddenFile = ref(false); const analysisPaths = ref>([]); @@ -295,9 +295,12 @@ // 删除选中文件 const deleteSelectFiles = () => { - if (props.selectedFiles?.length) { - props.session?.remove(props.selectedFiles); - } + emits('deleteFile', [...props.selectedFiles]); + }; + + // 下载文件 + const downloadFile = () => { + emits('download', [...props.selectedFiles], true); }; // 重新连接 @@ -309,12 +312,6 @@ } }; - // 下载文件 - const downloadFile = () => { - emits('download', [...props.selectedFiles]); - emits('update:selectedFiles', []); - }; -