🔨 修改主机逻辑.
This commit is contained in:
@@ -53,7 +53,7 @@
|
||||
|
||||
* 🔗 演示地址: http://101.43.254.243:1081/
|
||||
* 🔏 演示账号: admin/admin
|
||||
* ⭐ 体验后可以点一下 `star` 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor)
|
||||
* ⭐ 体验后可以点一下 `star` 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) [gitcode](https://gitcode.com/qq_41011894/orion-visor/overview)
|
||||
* 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
|
||||
* 🎭 演示环境部分功能不可用, 完整功能请本地部署!
|
||||
* 📛 演示环境请不要随便删除数据!
|
||||
|
||||
@@ -61,6 +61,10 @@ public interface ErrorMessage {
|
||||
|
||||
String GROUP_ABSENT = "分组不存在";
|
||||
|
||||
String HOST_TYPE_ERROR = "主机类型错误";
|
||||
|
||||
String HOST_NOT_ENABLED = "主机未启用";
|
||||
|
||||
String UNABLE_OPERATE_ADMIN_ROLE = "无法操作管理员账号";
|
||||
|
||||
String UNSUPPORTED_CHARSET = "不支持的编码 [{}]";
|
||||
|
||||
@@ -79,6 +79,6 @@ public interface FieldConst {
|
||||
|
||||
String FILTER = "filter";
|
||||
|
||||
String LICENSE = "license";
|
||||
String ALL = "all";
|
||||
|
||||
}
|
||||
|
||||
@@ -210,14 +210,23 @@ public class DataQuery<T> {
|
||||
// -------------------- data grid --------------------
|
||||
|
||||
public DataGrid<T> dataGrid() {
|
||||
return this.dataGrid(Function.identity());
|
||||
return this.dataGrid(this.wrapper, Function.identity());
|
||||
}
|
||||
|
||||
public DataGrid<T> dataGrid(Wrapper<T> countWrapper) {
|
||||
return this.dataGrid(countWrapper, Function.identity());
|
||||
}
|
||||
|
||||
public <R> DataGrid<R> dataGrid(Function<T, R> mapper) {
|
||||
Valid.notNull(mapper, "convert function is null");
|
||||
return this.dataGrid(this.wrapper, mapper);
|
||||
}
|
||||
|
||||
public <R> DataGrid<R> dataGrid(Wrapper<T> countWrapper, Function<T, R> mapper) {
|
||||
Valid.notNull(page, "page is null");
|
||||
Valid.notNull(wrapper, "wrapper is null");
|
||||
Long count = dao.selectCount(wrapper);
|
||||
Valid.notNull(countWrapper, "count wrapper is null");
|
||||
Valid.notNull(mapper, "convert function is null");
|
||||
Long count = dao.selectCount(countWrapper);
|
||||
Pager<R> pager = new Pager<>(page);
|
||||
pager.setTotal(count.intValue());
|
||||
boolean next = pager.hasMoreData();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
search-input-placeholder="输入搜索值"
|
||||
create-card-position="head"
|
||||
:loading="loading"
|
||||
:fieldConfig="fieldConfig"
|
||||
:field-config="fieldConfig"
|
||||
:list="list"
|
||||
:pagination="pagination"
|
||||
:card-layout-cols="cardColLayout"
|
||||
@@ -74,15 +74,16 @@
|
||||
<!-- 修改 -->
|
||||
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']"
|
||||
@click="emits('openUpdate', record)">
|
||||
<icon-edit />
|
||||
修改
|
||||
<span class="more-doption normal">
|
||||
<icon-edit /> 修改
|
||||
</span>
|
||||
</a-doption>
|
||||
<!-- 删除 -->
|
||||
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
|
||||
class="span-red"
|
||||
@click="deleteRow(record.id)">
|
||||
<icon-delete />
|
||||
删除
|
||||
<span class="more-doption error">
|
||||
<icon-delete /> 删除
|
||||
</span>
|
||||
</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
@@ -93,15 +94,17 @@
|
||||
<!-- 修改 -->
|
||||
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']"
|
||||
@click="emits('openUpdate', record)">
|
||||
<icon-edit />
|
||||
修改
|
||||
<span class="more-doption normal">
|
||||
<icon-edit /> 修改
|
||||
</span>
|
||||
</a-doption>
|
||||
<!-- 删除 -->
|
||||
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
|
||||
class="span-red"
|
||||
@click="deleteRow(record.id)">
|
||||
<icon-delete />
|
||||
删除
|
||||
<span class="more-doption error">
|
||||
<icon-delete /> 删除
|
||||
</span>
|
||||
</a-doption>
|
||||
</template>
|
||||
</card-list>
|
||||
|
||||
@@ -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"){
|
||||
|
||||
@@ -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<HostConfigVO> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<HostVO> getHostList() {
|
||||
return hostService.getHostListByCache();
|
||||
public List<HostVO> getHostList(@RequestParam(value = "type", required = false) String type) {
|
||||
return hostService.getHostList(type);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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<HostConfigDO> {
|
||||
|
||||
/**
|
||||
* 通过 hostId 查询主机配置
|
||||
*
|
||||
* @param hostId hostId
|
||||
* @param type type
|
||||
* @return row
|
||||
*/
|
||||
default HostConfigDO getHostConfigByHostId(Long hostId, String type) {
|
||||
// 条件
|
||||
LambdaQueryWrapper<HostConfigDO> wrapper = this.lambda()
|
||||
.eq(HostConfigDO::getHostId, hostId)
|
||||
.eq(HostConfigDO::getType, type);
|
||||
// 查询
|
||||
return this.of(wrapper).getOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 hostId 查询主机配置
|
||||
*
|
||||
* @param hostId hostId
|
||||
* @return rows
|
||||
*/
|
||||
default List<HostConfigDO> getHostConfigByHostId(Long hostId) {
|
||||
// 条件
|
||||
LambdaQueryWrapper<HostConfigDO> wrapper = this.lambda()
|
||||
.eq(HostConfigDO::getHostId, hostId);
|
||||
// 查询
|
||||
return this.of(wrapper).list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 hostId 批量查询主机配置
|
||||
*
|
||||
* @param hostIdList hostIdList
|
||||
* @param type type
|
||||
* @return rows
|
||||
*/
|
||||
default List<HostConfigDO> getHostConfigByHostIdList(List<Long> hostIdList, String type) {
|
||||
// 条件
|
||||
LambdaQueryWrapper<HostConfigDO> 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<HostConfigDO> wrapper = this.lambda()
|
||||
.eq(HostConfigDO::getHostId, hostId);
|
||||
// 删除
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 hostId 批量删除主机配置
|
||||
*
|
||||
* @param hostIdList hostIdList
|
||||
* @return effect
|
||||
*/
|
||||
default Integer deleteByHostIdList(List<Long> hostIdList) {
|
||||
// 条件
|
||||
LambdaQueryWrapper<HostConfigDO> wrapper = this.lambda()
|
||||
.in(HostConfigDO::getHostId, hostIdList);
|
||||
// 删除
|
||||
return this.delete(wrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 keyId 为 NULL
|
||||
*
|
||||
* @param keyIdList keyIdList
|
||||
* @return effect
|
||||
*/
|
||||
int setKeyIdWithNull(@Param("keyIdList") List<Long> keyIdList);
|
||||
|
||||
/**
|
||||
* 设置 identityId 为 NULL
|
||||
*
|
||||
* @param identityIdList identityIdList
|
||||
* @return effect
|
||||
*/
|
||||
int setIdentityIdWithNull(@Param("identityIdList") List<Long> identityIdList);
|
||||
|
||||
}
|
||||
@@ -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<HostDO> {
|
||||
|
||||
List<SFunction<HostDO, ?>> 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<HostDO> selectBaseByIdList(List<Long> 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<Long> getHostIdList(List<Long> 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<Long> keyIdList);
|
||||
|
||||
/**
|
||||
* 设置 identityId 为 NULL
|
||||
*
|
||||
* @param identityIdList identityIdList
|
||||
* @return effect
|
||||
*/
|
||||
int setIdentityIdWithNull(@Param("identityIdList") List<Long> identityIdList);
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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, "创建主机 <sb>${name}</sb>"),
|
||||
new OperatorType(L, UPDATE, "修改主机 <sb>${name}</sb>"),
|
||||
new OperatorType(H, DELETE, "删除主机 <sb>${name}</sb>"),
|
||||
new OperatorType(M, UPDATE_CONFIG, "修改主机配置 <sb>${name}</sb> | <sb>${type}</sb>"),
|
||||
new OperatorType(M, UPDATE_CONFIG_STATUS, "修改主机配置状态 <sb>${name}</sb> | <sb>${type}</sb> - <sb>${statusName}</sb>"),
|
||||
new OperatorType(M, UPDATE_STATUS, "修改主机状态 <sb>${name}</sb> - <sb>${status}</sb>"),
|
||||
new OperatorType(M, UPDATE_CONFIG, "修改主机配置 <sb>${name}</sb>"),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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<Long> groupIdList;
|
||||
|
||||
|
||||
@@ -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<Long> tags;
|
||||
|
||||
@Schema(description = "是否查询 tag 信息")
|
||||
private Boolean queryTag;
|
||||
|
||||
@Schema(description = "是否查询配置信息")
|
||||
private Boolean queryConfig;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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<Long> groupIdList;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -69,6 +69,6 @@ public class ExecJobVO implements Serializable {
|
||||
private List<Long> hostIdList;
|
||||
|
||||
@Schema(description = "执行主机")
|
||||
private List<HostVO> hostList;
|
||||
private List<HostBaseVO> hostList;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String, Object> config;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<? extends GenericsDataStrategy<? extends GenericsDataModel>> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<? extends GenericsDataStrategy<? extends GenericsDataModel>> 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
|
||||
@@ -34,8 +34,6 @@ public class HostSshConfigStrategy extends AbstractGenericsDataStrategy<HostSshC
|
||||
@Resource
|
||||
private HostIdentityDAO hostIdentityDAO;
|
||||
|
||||
private static final int SSH_PORT = 22;
|
||||
|
||||
private static final String USERNAME = "root";
|
||||
|
||||
public HostSshConfigStrategy() {
|
||||
@@ -45,7 +43,6 @@ public class HostSshConfigStrategy extends AbstractGenericsDataStrategy<HostSshC
|
||||
@Override
|
||||
public HostSshConfigModel getDefault() {
|
||||
return HostSshConfigModel.builder()
|
||||
.port(SSH_PORT)
|
||||
.username(USERNAME)
|
||||
.authType(HostSshAuthTypeEnum.PASSWORD.name())
|
||||
.osType(HostSshOsTypeEnum.LINUX.name())
|
||||
|
||||
@@ -19,10 +19,12 @@ import com.orion.spring.SpringHolder;
|
||||
import com.orion.visor.framework.common.file.FileClient;
|
||||
import com.orion.visor.module.asset.dao.ExecHostLogDAO;
|
||||
import com.orion.visor.module.asset.entity.domain.ExecHostLogDO;
|
||||
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||
import com.orion.visor.module.asset.enums.ExecHostStatusEnum;
|
||||
import com.orion.visor.module.asset.handler.host.exec.command.model.ExecCommandDTO;
|
||||
import com.orion.visor.module.asset.handler.host.exec.command.model.ExecCommandHostDTO;
|
||||
import com.orion.visor.module.asset.handler.host.exec.log.manager.ExecLogManager;
|
||||
import com.orion.visor.module.asset.handler.host.jsch.SessionStores;
|
||||
import com.orion.visor.module.asset.service.HostTerminalService;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -128,7 +130,8 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler {
|
||||
// 初始化日志
|
||||
this.initLogOutputStream();
|
||||
// 打开会话
|
||||
this.sessionStore = hostTerminalService.openSessionStore(execHostCommand.getHostId());
|
||||
HostTerminalConnectDTO connect = hostTerminalService.getTerminalConnectInfo(execHostCommand.getHostId());
|
||||
this.sessionStore = SessionStores.openSessionStore(connect);
|
||||
if (Booleans.isTrue(execCommand.getScriptExec())) {
|
||||
// 上传脚本文件
|
||||
this.uploadScriptFile();
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.orion.visor.module.asset.handler.host.jsch;
|
||||
|
||||
/**
|
||||
* 连接消息
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/7/11 16:30
|
||||
*/
|
||||
public interface SessionMessage {
|
||||
|
||||
String AUTHENTICATION_FAILURE = "authentication failed. please check the configuration. - {}";
|
||||
|
||||
String SERVER_UNREACHABLE = "remote server unreachable. please check the configuration. - {}";
|
||||
|
||||
String CONNECTION_TIMEOUT = "connection timeout. - {}";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.orion.visor.module.asset.handler.host.jsch;
|
||||
|
||||
import com.orion.lang.exception.AuthenticationException;
|
||||
import com.orion.lang.exception.argument.InvalidArgumentException;
|
||||
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.utils.CryptoUtils;
|
||||
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* sessionStore 工具类
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2024/7/11 16:58
|
||||
*/
|
||||
@Slf4j
|
||||
public class SessionStores {
|
||||
|
||||
protected static final ThreadLocal<String> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<TerminalConnectRequest> {
|
||||
|
||||
@Resource
|
||||
private HostTerminalService hostTerminalService;
|
||||
|
||||
@Resource
|
||||
private HostConnectLogService hostConnectLogService;
|
||||
|
||||
@@ -117,7 +114,7 @@ public class TerminalConnectHandler extends AbstractTerminalHandler<TerminalConn
|
||||
.fileContentCharset(connect.getFileContentCharset())
|
||||
.build();
|
||||
// 建立连接
|
||||
SessionStore sessionStore = hostTerminalService.openSessionStore(connect);
|
||||
SessionStore sessionStore = SessionStores.openSessionStore(connect);
|
||||
if (HostConnectTypeEnum.SSH.name().equals(connectType)) {
|
||||
// 打开 ssh 会话
|
||||
SshSession sshSession = new SshSession(sessionId, channel, sessionStore, config);
|
||||
|
||||
@@ -7,9 +7,11 @@ import com.orion.spring.SpringHolder;
|
||||
import com.orion.visor.framework.common.constant.ExtraFieldConst;
|
||||
import com.orion.visor.framework.websocket.core.utils.WebSockets;
|
||||
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||
import com.orion.visor.module.asset.handler.host.jsch.SessionStores;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.enums.TransferOperator;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.enums.TransferReceiver;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.enums.TransferType;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.model.HostConnection;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.model.TransferOperatorRequest;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.session.DownloadSession;
|
||||
import com.orion.visor.module.asset.handler.host.transfer.session.ITransferSession;
|
||||
@@ -39,9 +41,12 @@ public class TransferHandler implements ITransferHandler {
|
||||
|
||||
private final ConcurrentHashMap<String, ITransferSession> sessions;
|
||||
|
||||
private final ConcurrentHashMap<Long, HostConnection> 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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -38,4 +38,9 @@ public class TransferOperatorRequest {
|
||||
*/
|
||||
private Long hostId;
|
||||
|
||||
/**
|
||||
* 错误信息 后端赋值
|
||||
*/
|
||||
private String errorMessage;
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,12 @@ public class TransferOperatorResponse {
|
||||
/**
|
||||
* 传输的大小
|
||||
*/
|
||||
private Integer currentSize;
|
||||
private Long currentSize;
|
||||
|
||||
/**
|
||||
* 文件总大小
|
||||
*/
|
||||
private Long totalSize;
|
||||
|
||||
/**
|
||||
* transferToken
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -73,4 +73,11 @@ public interface ITransferSession extends SafeCloseable {
|
||||
*/
|
||||
void setToken(String token);
|
||||
|
||||
/**
|
||||
* 获取 hostId
|
||||
*
|
||||
* @return hostId
|
||||
*/
|
||||
Long getHostId();
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存操作日志
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Long> getUserAuthorizedHostIdWithEnabledConfig(Long userId, HostConfigTypeEnum type);
|
||||
List<Long> getUserAuthorizedEnabledHostId(Long userId, HostTypeEnum type);
|
||||
|
||||
/**
|
||||
* 查询用户已授权的主机
|
||||
|
||||
@@ -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> T
|
||||
* @return host
|
||||
*/
|
||||
HostConfigVO getHostConfig(Long hostId, String type);
|
||||
<T extends GenericsDataModel> T getHostConfig(Long id, HostTypeEnum type);
|
||||
|
||||
/**
|
||||
* 获取配置 配置未启用会报错
|
||||
* 构建主机配置
|
||||
*
|
||||
* @param hostId hostId
|
||||
* @param host host
|
||||
* @param type type
|
||||
* @param <T> T
|
||||
* @return host
|
||||
*/
|
||||
<T extends GenericsDataModel> T buildHostConfig(HostDO host, HostTypeEnum type);
|
||||
|
||||
/**
|
||||
* 获取主机配置
|
||||
*
|
||||
* @param idList idList
|
||||
* @param type type
|
||||
* @param <T> T
|
||||
* @return config
|
||||
*/
|
||||
<T extends GenericsDataModel> T getHostConfig(Long hostId, HostConfigTypeEnum type);
|
||||
<T extends GenericsDataModel> Map<Long, T> getHostConfigMap(List<Long> idList, HostTypeEnum type);
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
* 构建主机配置
|
||||
*
|
||||
* @param hostId hostId
|
||||
* @param hostList hostList
|
||||
* @param type type
|
||||
* @param <T> T
|
||||
* @return config
|
||||
*/
|
||||
List<HostConfigVO> getHostConfigList(Long hostId);
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*
|
||||
* @param hostIdList hostIdList
|
||||
* @param type type
|
||||
* @return config
|
||||
*/
|
||||
List<HostConfigVO> getHostConfigList(List<Long> hostIdList, String type);
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*
|
||||
* @param hostIdList hostIdList
|
||||
* @param type type
|
||||
* @param <T> T
|
||||
* @return config
|
||||
*/
|
||||
<T extends GenericsDataModel> Map<Long, T> getHostConfigMap(List<Long> 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<Long> getEnabledConfigHostId(String type, List<Long> hostIdList);
|
||||
<T extends GenericsDataModel> Map<Long, T> buildHostConfigMap(List<HostDO> hostList, HostTypeEnum type);
|
||||
|
||||
}
|
||||
|
||||
@@ -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<HostVO> getHostListByCache();
|
||||
List<HostVO> getHostList(String type);
|
||||
|
||||
/**
|
||||
* 分页查询主机
|
||||
@@ -79,4 +103,11 @@ public interface HostService {
|
||||
*/
|
||||
void deleteHostRelByIdListAsync(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 获取当前更新配置的 hostId
|
||||
*
|
||||
* @return hostId
|
||||
*/
|
||||
Long getCurrentUpdateConfigHostId();
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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<Long> getUserAuthorizedHostIdWithEnabledConfig(Long userId, HostConfigTypeEnum type) {
|
||||
// 获取启用的主机
|
||||
public List<Long> getUserAuthorizedEnabledHostId(Long userId, HostTypeEnum type) {
|
||||
// 获取有权限的的主机
|
||||
List<Long> 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<Map<Long, String>> labelExtraResult = dataExtraApi.getExtraItemValuesByCacheAsync(userId,
|
||||
DataExtraTypeEnum.HOST,
|
||||
HostExtraItemEnum.LABEL.getItem());
|
||||
HostExtraItemEnum.LABEL.name());
|
||||
// 查询分组
|
||||
List<DataGroupDTO> dataGroup = dataGroupApi.getDataGroupList(DataGroupTypeEnum.HOST);
|
||||
// 查询分组引用
|
||||
Map<Long, Set<Long>> 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<Long> hostIdList = dataGroupRel.values()
|
||||
// 查询已启用的主机
|
||||
List<Long> allHostId = dataGroupRel.values()
|
||||
.stream()
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
List<Long> enabledConfigHostId = hostConfigService.getEnabledConfigHostId(type, hostIdList);
|
||||
if (allHostId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Long> 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<HostVO> getAuthorizedHostList(Map<Long, Set<Long>> dataGroupRel) {
|
||||
private List<HostVO> getAuthorizedHostList(String type, Map<Long, Set<Long>> dataGroupRel) {
|
||||
// 查询主机列表
|
||||
Map<Long, HostVO> hostMap = hostService.getHostListByCache()
|
||||
Map<Long, HostVO> hostMap = hostService.getHostList(type)
|
||||
.stream()
|
||||
.collect(Collectors.toMap(HostVO::getId, Function.identity(), Functions.right()));
|
||||
// 设置已授权的数据
|
||||
|
||||
@@ -97,7 +97,7 @@ public class ExecCommandServiceImpl implements ExecCommandService {
|
||||
Long userId = user.getId();
|
||||
List<Long> hostIdList = request.getHostIdList();
|
||||
// 检查主机权限
|
||||
List<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(userId, HostConfigTypeEnum.SSH);
|
||||
List<Long> 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<HostDO> hosts = hostDAO.selectBatchIds(hostIdList);
|
||||
// 查询主机配置
|
||||
Map<Long, HostSshConfigModel> hostConfigMap = hostConfigService.getHostConfigMap(hostIdList, HostConfigTypeEnum.SSH);
|
||||
Map<Long, HostSshConfigModel> 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;
|
||||
|
||||
@@ -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<HostDO> hostList = hostDAO.selectBatchIds(hostIdList);
|
||||
vo.setHostList(HostConvert.MAPPER.toList(hostList));
|
||||
List<HostBaseVO> 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<Long> hostIdList) {
|
||||
// 查询有权限的主机
|
||||
List<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(SecurityUtils.getLoginUserId(), HostConfigTypeEnum.SSH);
|
||||
List<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedEnabledHostId(SecurityUtils.getLoginUserId(), HostTypeEnum.SSH);
|
||||
for (Long hostId : hostIdList) {
|
||||
Valid.isTrue(authorizedHostIdList.contains(hostId), Strings.format(ErrorMessage.PLEASE_CHECK_HOST_SSH, hostId));
|
||||
}
|
||||
|
||||
@@ -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<Long> hostIdList = hostLogs.stream()
|
||||
.map(ExecHostLogDO::getHostId)
|
||||
.collect(Collectors.toList());
|
||||
Map<Long, HostSshConfigModel> configMap = hostConfigService.getHostConfigMap(hostIdList, HostConfigTypeEnum.SSH);
|
||||
Map<Long, HostSshConfigModel> configMap = hostConfigService.getHostConfigMap(hostIdList, HostTypeEnum.SSH);
|
||||
// 生成缓存
|
||||
String token = UUIds.random19();
|
||||
String cacheKey = ExecCacheKeyDefine.EXEC_TAIL.format(token);
|
||||
|
||||
@@ -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<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(SecurityUtils.getLoginUserId(), HostConfigTypeEnum.SSH);
|
||||
List<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedEnabledHostId(SecurityUtils.getLoginUserId(), HostTypeEnum.SSH);
|
||||
hostIdList.removeIf(s -> !authorizedHostIdList.contains(s));
|
||||
template.setHostIdList(hostIdList);
|
||||
return template;
|
||||
|
||||
@@ -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<String, Object> configMap = configType.toView(config.getConfig()).toMap();
|
||||
vo.setConfig(configMap);
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GenericsDataModel> 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<HostConfigVO> getHostConfigList(Long hostId) {
|
||||
// 查询
|
||||
List<HostConfigDO> configs = hostConfigDAO.getHostConfigByHostId(hostId);
|
||||
return configs.stream()
|
||||
.map(this::convertHostConfig)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostConfigVO> getHostConfigList(List<Long> hostIdList, String type) {
|
||||
// 查询
|
||||
List<HostConfigDO> configs = hostConfigDAO.getHostConfigByHostIdList(hostIdList, type);
|
||||
// 返回
|
||||
return configs.stream()
|
||||
.map(this::convertHostConfig)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GenericsDataModel> Map<Long, T> getHostConfigMap(List<Long> hostIdList, HostConfigTypeEnum type) {
|
||||
// 查询
|
||||
List<HostConfigDO> 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 extends GenericsDataModel> 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<GenericsDataModel> 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 extends GenericsDataModel> 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 <T extends GenericsDataModel> Map<Long, T> getHostConfigMap(List<Long> 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<HostConfigDO> configs = Arrays.stream(HostConfigTypeEnum.values())
|
||||
.map(s -> this.getDefaultConfig(hostId, s))
|
||||
.collect(Collectors.toList());
|
||||
hostConfigDAO.insertBatch(configs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getEnabledConfigHostId(String type, List<Long> hostIdList) {
|
||||
return hostConfigDAO.of()
|
||||
.createValidateWrapper()
|
||||
.select(HostConfigDO::getHostId)
|
||||
.eq(HostConfigDO::getType, type)
|
||||
.eq(HostConfigDO::getStatus, BooleanBit.TRUE.getValue())
|
||||
.in(HostConfigDO::getHostId, hostIdList)
|
||||
.then()
|
||||
Map<Long, HostDO> 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<Long, T> result = new HashMap<>();
|
||||
for (Long id : idList) {
|
||||
result.put(id, this.buildHostConfig(hostMap.get(id), type));
|
||||
}
|
||||
// 转为视图
|
||||
HostConfigVO vo = HostConfigConvert.MAPPER.to(row);
|
||||
Map<String, Object> config = type.toView(row.getConfig()).toMap();
|
||||
vo.setConfig(config);
|
||||
return vo;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GenericsDataModel> Map<Long, T> buildHostConfigMap(List<HostDO> hostList, HostTypeEnum type) {
|
||||
Map<Long, T> result = new HashMap<>();
|
||||
for (HostDO host : hostList) {
|
||||
result.put(host.getId(), this.buildHostConfig(host, type));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String, Map<String, Object>> result = Maps.newMap();
|
||||
for (HostExtraItemEnum extraItem : extraItems) {
|
||||
String item = extraItem.getItem();
|
||||
String item = extraItem.name();
|
||||
// 检查初始化并转为视图
|
||||
Map<String, Object> 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);
|
||||
|
||||
@@ -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);
|
||||
// 删除数据权限
|
||||
|
||||
@@ -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);
|
||||
// 删除数据权限
|
||||
|
||||
@@ -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<Long> 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<Set<Long>> 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<HostVO> 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<String, Object> config = hostType.toView(host.getConfig()).toMap();
|
||||
// 返回
|
||||
return HostConfigVO.builder()
|
||||
.id(id)
|
||||
.type(type)
|
||||
.config(config)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<HostVO> getHostList(String type) {
|
||||
// 查询缓存
|
||||
List<HostCacheDTO> 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<HostCacheDTO> 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<HostDO> countWrapper = wrapper.clone();
|
||||
wrapper.select(HostDAO.BASE_COLUMN);
|
||||
// 查询
|
||||
DataGrid<HostVO> 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<Long> idList) {
|
||||
log.info("HostService-deleteHostByIdList idList: {}", idList);
|
||||
// 查询
|
||||
List<HostDO> hosts = hostDAO.selectBatchIds(idList);
|
||||
List<HostDO> 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<Long> 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()
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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<HostBaseVO> hosts = hostDAO.selectBatchIds(hostIdList)
|
||||
List<HostBaseVO> 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<Long> hostIdList) {
|
||||
// 查询有权限的主机
|
||||
List<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostIdWithEnabledConfig(SecurityUtils.getLoginUserId(), HostConfigTypeEnum.SSH);
|
||||
List<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedEnabledHostId(SecurityUtils.getLoginUserId(), HostTypeEnum.SSH);
|
||||
for (Long hostId : hostIdList) {
|
||||
Valid.isTrue(authorizedHostIdList.contains(hostId), Strings.format(ErrorMessage.PLEASE_CHECK_HOST_SSH, hostId));
|
||||
}
|
||||
|
||||
@@ -5,19 +5,41 @@
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.orion.visor.module.asset.entity.domain.HostDO">
|
||||
<id column="id" property="id"/>
|
||||
<result column="type" property="type"/>
|
||||
<result column="name" property="name"/>
|
||||
<result column="code" property="code"/>
|
||||
<result column="address" property="address"/>
|
||||
<result column="port" property="port"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="config" property="config"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
<result column="creator" property="creator"/>
|
||||
<result column="updater" property="updater"/>
|
||||
<result column="deleted" property="deleted"/>
|
||||
<result column="name" property="name"/>
|
||||
<result column="code" property="code"/>
|
||||
<result column="address" property="address"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
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
|
||||
</sql>
|
||||
|
||||
<update id="setKeyIdWithNull">
|
||||
UPDATE host
|
||||
SET config = JSON_REMOVE(config, '$.keyId')
|
||||
WHERE deleted = 0
|
||||
<foreach collection="keyIdList" item="item" separator="OR" open="AND (" close=")">
|
||||
JSON_CONTAINS(config, JSON_OBJECT('keyId', #{item}))
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<update id="setIdentityIdWithNull">
|
||||
UPDATE host
|
||||
SET config = JSON_REMOVE(config, '$.identityId')
|
||||
WHERE deleted = 0
|
||||
<foreach collection="identityIdList" item="item" separator="OR" open="AND (" close=")">
|
||||
JSON_CONTAINS(config, JSON_OBJECT('identityId', #{item}))
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user