🐛 SSH 配置未启用还可以连接.
This commit is contained in:
@@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
@@ -40,8 +41,8 @@ public class AssetAuthorizedDataServiceController {
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@GetMapping("/current-host")
|
||||
@Operation(summary = "查询当前用户已授权的主机")
|
||||
public AuthorizedHostWrapperVO getCurrentAuthorizedHostGroup() {
|
||||
return assetAuthorizedDataService.getUserAuthorizedHostGroup(SecurityUtils.getLoginUserId());
|
||||
public AuthorizedHostWrapperVO getCurrentAuthorizedHost(@RequestParam("type") String type) {
|
||||
return assetAuthorizedDataService.getUserAuthorizedHost(SecurityUtils.getLoginUserId(), type);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
|
||||
@@ -43,7 +43,7 @@ public enum HostConfigTypeEnum implements GenericsDataDefinition {
|
||||
return null;
|
||||
}
|
||||
for (HostConfigTypeEnum value : values()) {
|
||||
if (value.type.equals(type)) {
|
||||
if (value.type.equalsIgnoreCase(type)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public enum HostConnectTypeEnum {
|
||||
return null;
|
||||
}
|
||||
for (HostConnectTypeEnum value : values()) {
|
||||
if (value.name().equals(type)) {
|
||||
if (value.name().equalsIgnoreCase(type)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,18 @@ package com.orion.ops.module.asset.handler.host.terminal.constant;
|
||||
*/
|
||||
public interface TerminalMessage {
|
||||
|
||||
String CLOSED_CONNECTION = "closed connection...";
|
||||
String CONFIG_DISABLED = "SSH configuration has been disabled.";
|
||||
|
||||
String AUTHENTICATION_FAILURE = "authentication failure...";
|
||||
String AUTHENTICATION_FAILURE = "authentication failed. please check the configuration.";
|
||||
|
||||
String UNREACHABLE = "remote server unreachable...";
|
||||
String SERVER_UNREACHABLE = "remote server unreachable. please check the configuration.";
|
||||
|
||||
String CONNECTION_TIMEOUT = "connection timeout...";
|
||||
String CONNECTION_FAILED = "connection failed.";
|
||||
|
||||
String FORCED_OFFLINE = "forced offline...";
|
||||
String CONNECTION_TIMEOUT = "connection timeout.";
|
||||
|
||||
String CONNECTION_CLOSED = "connection closed.";
|
||||
|
||||
String FORCED_OFFLINE = "forced offline.";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.orion.ops.module.asset.handler.host.terminal.handler;
|
||||
|
||||
import com.orion.lang.exception.DisabledException;
|
||||
import com.orion.lang.exception.argument.InvalidArgumentException;
|
||||
import com.orion.lang.utils.Exceptions;
|
||||
import com.orion.lang.utils.collect.Maps;
|
||||
@@ -17,6 +18,7 @@ import com.orion.ops.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||
import com.orion.ops.module.asset.entity.request.host.HostConnectLogCreateRequest;
|
||||
import com.orion.ops.module.asset.enums.HostConnectStatusEnum;
|
||||
import com.orion.ops.module.asset.enums.HostConnectTypeEnum;
|
||||
import com.orion.ops.module.asset.handler.host.terminal.constant.TerminalMessage;
|
||||
import com.orion.ops.module.asset.handler.host.terminal.enums.OutputTypeEnum;
|
||||
import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalCheckRequest;
|
||||
import com.orion.ops.module.asset.handler.host.terminal.model.response.TerminalCheckResponse;
|
||||
@@ -82,9 +84,12 @@ public class TerminalCheckHandler extends AbstractTerminalHandler<TerminalCheckR
|
||||
log.info("TerminalCheckHandler-handle success userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId);
|
||||
} catch (InvalidArgumentException e) {
|
||||
ex = e;
|
||||
log.error("TerminalCheckHandler-handle error userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId, e);
|
||||
log.error("TerminalCheckHandler-handle start error userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId, e);
|
||||
} catch (DisabledException e) {
|
||||
ex = Exceptions.runtime(TerminalMessage.CONFIG_DISABLED);
|
||||
log.error("TerminalCheckHandler-handle disabled error userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId);
|
||||
} catch (Exception e) {
|
||||
ex = Exceptions.runtime(ErrorMessage.CONNECT_ERROR);
|
||||
ex = Exceptions.runtime(TerminalMessage.CONNECTION_FAILED);
|
||||
log.error("TerminalCheckHandler-handle exception userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId, e);
|
||||
}
|
||||
// 记录主机日志
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.orion.ops.module.asset.handler.host.terminal.handler;
|
||||
|
||||
import com.orion.lang.exception.AuthenticationException;
|
||||
import com.orion.lang.exception.ConnectionRuntimeException;
|
||||
import com.orion.lang.exception.TimeoutException;
|
||||
import com.orion.lang.exception.argument.InvalidArgumentException;
|
||||
import com.orion.lang.utils.Exceptions;
|
||||
@@ -151,9 +150,6 @@ public class TerminalConnectHandler extends AbstractTerminalHandler<TerminalConn
|
||||
if (Exceptions.isCausedBy(e, TimeoutException.class)) {
|
||||
// 连接超时
|
||||
return TerminalMessage.CONNECTION_TIMEOUT;
|
||||
} else if (Exceptions.isCausedBy(e, ConnectionRuntimeException.class)) {
|
||||
// 无法连接
|
||||
return TerminalMessage.UNREACHABLE;
|
||||
} else if (Exceptions.isCausedBy(e, AuthenticationException.class)) {
|
||||
// 认证失败
|
||||
return TerminalMessage.AUTHENTICATION_FAILURE;
|
||||
@@ -162,7 +158,7 @@ public class TerminalConnectHandler extends AbstractTerminalHandler<TerminalConn
|
||||
return e.getMessage();
|
||||
} else {
|
||||
// 其他错误
|
||||
return TerminalMessage.UNREACHABLE;
|
||||
return TerminalMessage.SERVER_UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public abstract class TerminalSession implements ITerminalSession {
|
||||
.type(OutputTypeEnum.CLOSE.getType())
|
||||
.sessionId(this.sessionId)
|
||||
.forceClose(BooleanBit.of(this.forceOffline).getValue())
|
||||
.msg(this.forceOffline ? TerminalMessage.FORCED_OFFLINE : TerminalMessage.CLOSED_CONNECTION)
|
||||
.msg(this.forceOffline ? TerminalMessage.FORCED_OFFLINE : TerminalMessage.CONNECTION_CLOSED)
|
||||
.build();
|
||||
WebSockets.sendText(channel, OutputTypeEnum.CLOSE.format(resp));
|
||||
}
|
||||
|
||||
@@ -30,9 +30,10 @@ public interface AssetAuthorizedDataService {
|
||||
* 查询用户已授权的主机主机
|
||||
*
|
||||
* @param userId userId
|
||||
* @param type type
|
||||
* @return group
|
||||
*/
|
||||
AuthorizedHostWrapperVO getUserAuthorizedHostGroup(Long userId);
|
||||
AuthorizedHostWrapperVO getUserAuthorizedHost(Long userId, String type);
|
||||
|
||||
/**
|
||||
* 获取用户已授权的主机id 不查询角色
|
||||
|
||||
@@ -66,4 +66,13 @@ public interface HostConfigService {
|
||||
*/
|
||||
void initHostConfig(Long hostId);
|
||||
|
||||
/**
|
||||
* 获取启用配置的 hostId
|
||||
*
|
||||
* @param type type
|
||||
* @param hostIdList hostIdList
|
||||
* @return hostId
|
||||
*/
|
||||
List<Long> getEnabledConfigHostId(String type, List<Long> hostIdList);
|
||||
|
||||
}
|
||||
|
||||
@@ -55,6 +55,9 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
@Resource
|
||||
private HostService hostService;
|
||||
|
||||
@Resource
|
||||
private HostConfigService hostConfigService;
|
||||
|
||||
@Resource
|
||||
private HostKeyService hostKeyService;
|
||||
|
||||
@@ -88,10 +91,10 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthorizedHostWrapperVO getUserAuthorizedHostGroup(Long userId) {
|
||||
public AuthorizedHostWrapperVO getUserAuthorizedHost(Long userId, String type) {
|
||||
if (systemUserApi.isAdminUser(userId)) {
|
||||
// 管理员查询所有
|
||||
return this.buildUserAuthorizedHostGroup(userId, null);
|
||||
return this.buildUserAuthorizedHost(userId, null, type);
|
||||
} else {
|
||||
// 其他用户 查询授权的数据
|
||||
List<Long> authorizedIdList = dataPermissionApi.getUserAuthorizedRelIdList(DataPermissionTypeEnum.HOST_GROUP, userId);
|
||||
@@ -102,7 +105,7 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
.hostList(Lists.empty())
|
||||
.build();
|
||||
}
|
||||
return this.buildUserAuthorizedHostGroup(userId, authorizedIdList);
|
||||
return this.buildUserAuthorizedHost(userId, authorizedIdList, type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,24 +176,27 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
*
|
||||
* @param userId userId
|
||||
* @param authorizedGroupIdList authorizedGroupIdList
|
||||
* @param type type
|
||||
* @return tree
|
||||
*/
|
||||
@SneakyThrows
|
||||
private AuthorizedHostWrapperVO buildUserAuthorizedHostGroup(Long userId, List<Long> authorizedGroupIdList) {
|
||||
private AuthorizedHostWrapperVO buildUserAuthorizedHost(Long userId, List<Long> authorizedGroupIdList, String type) {
|
||||
final boolean allData = Lists.isEmpty(authorizedGroupIdList);
|
||||
AuthorizedHostWrapperVO wrapper = new AuthorizedHostWrapperVO();
|
||||
// 查询我的收藏
|
||||
Future<List<Long>> favoriteResult = favoriteApi.getFavoriteRelIdListAsync(FavoriteTypeEnum.HOST, userId);
|
||||
// 查询最近连接的主机
|
||||
Future<List<Long>> latestConnectHostIdList = hostConnectLogService.getLatestConnectHostIdAsync(HostConnectTypeEnum.SSH, userId);
|
||||
// 查询别名
|
||||
Future<Map<Long, String>> dataAliasResult = dataExtraApi.getExtraItemValuesByCacheAsync(userId, DataExtraTypeEnum.HOST, DataExtraItems.ALIAS);
|
||||
// 查询颜色
|
||||
Future<Map<Long, String>> dataColorResult = dataExtraApi.getExtraItemValuesByCacheAsync(userId, DataExtraTypeEnum.HOST, DataExtraItems.COLOR);
|
||||
Future<List<Long>> latestConnectHostIdList = hostConnectLogService.getLatestConnectHostIdAsync(HostConnectTypeEnum.of(type), userId);
|
||||
// 查询主机拓展信息
|
||||
Future<List<Map<Long, String>>> hostExtraResult = dataExtraApi.getExtraItemsValuesByCacheAsync(userId,
|
||||
DataExtraTypeEnum.HOST,
|
||||
Lists.of(DataExtraItems.ALIAS, DataExtraItems.COLOR));
|
||||
// 查询分组
|
||||
List<DataGroupDTO> dataGroup = dataGroupApi.getDataGroupList(DataGroupTypeEnum.HOST);
|
||||
// 查询分组引用
|
||||
Map<Long, Set<Long>> dataGroupRel = dataGroupRelApi.getGroupRelList(DataGroupTypeEnum.HOST);
|
||||
// 查询配置启用的主机
|
||||
List<Long> enabledConfigHostId = this.getEnabledConfigHostId(allData, dataGroupRel, type);
|
||||
// 过滤已经授权的分组
|
||||
if (!allData) {
|
||||
// 构建已授权的分组
|
||||
@@ -209,17 +215,47 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
wrapper.setHostList(this.getAuthorizedHostList(allData,
|
||||
dataGroup,
|
||||
dataGroupRel,
|
||||
authorizedGroupIdList));
|
||||
authorizedGroupIdList,
|
||||
enabledConfigHostId));
|
||||
// 设置主机拓展信息
|
||||
this.getAuthorizedHostExtra(wrapper.getHostList(),
|
||||
favoriteResult.get(),
|
||||
dataAliasResult.get(),
|
||||
dataColorResult.get());
|
||||
hostExtraResult.get());
|
||||
// 设置最近连接的主机
|
||||
wrapper.setLatestHosts(new LinkedHashSet<>(latestConnectHostIdList.get()));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取已启用配置的 hostId
|
||||
*
|
||||
* @param allData allData
|
||||
* @param dataGroupRel dataGroupRel
|
||||
* @param type type
|
||||
* @return enabledHostIdList
|
||||
*/
|
||||
private List<Long> getEnabledConfigHostId(boolean allData,
|
||||
Map<Long, Set<Long>> dataGroupRel,
|
||||
String type) {
|
||||
List<Long> hostIdList = null;
|
||||
if (!allData) {
|
||||
// 非全部数据从分组映射中获取
|
||||
hostIdList = dataGroupRel.values()
|
||||
.stream()
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (hostIdList.isEmpty()) {
|
||||
return Lists.empty();
|
||||
}
|
||||
}
|
||||
// 查询启用配置的主机
|
||||
List<Long> enabledConfigHostId = hostConfigService.getEnabledConfigHostId(type, hostIdList);
|
||||
// 从分组引用中移除
|
||||
dataGroupRel.forEach((k, v) -> v.removeIf(s -> !enabledConfigHostId.contains(s)));
|
||||
return enabledConfigHostId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建主机分组树
|
||||
*
|
||||
@@ -265,14 +301,19 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
* @param dataGroup dataGroup
|
||||
* @param dataGroupRel dataGroupRel
|
||||
* @param authorizedGroupIdList authorizedGroupIdList
|
||||
* @param enabledConfigHostId enabledConfigHostId
|
||||
* @return hosts
|
||||
*/
|
||||
private List<HostVO> getAuthorizedHostList(boolean allData,
|
||||
List<DataGroupDTO> dataGroup,
|
||||
Map<Long, Set<Long>> dataGroupRel,
|
||||
List<Long> authorizedGroupIdList) {
|
||||
List<Long> authorizedGroupIdList,
|
||||
List<Long> enabledConfigHostId) {
|
||||
// 查询主机列表
|
||||
List<HostVO> hosts = hostService.getHostListByCache();
|
||||
List<HostVO> hosts = hostService.getHostListByCache()
|
||||
.stream()
|
||||
.filter(s -> enabledConfigHostId.contains(s.getId()))
|
||||
.collect(Collectors.toList());
|
||||
// 全部数据直接返回
|
||||
if (allData) {
|
||||
return hosts;
|
||||
@@ -296,15 +337,13 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
/**
|
||||
* 设置授权主机的额外参数
|
||||
*
|
||||
* @param hosts hosts
|
||||
* @param favorite favorite
|
||||
* @param aliasMap aliasMap
|
||||
* @param colorMap colorMap
|
||||
* @param hosts hosts
|
||||
* @param favorite favorite
|
||||
* @param extraList extraList
|
||||
*/
|
||||
private void getAuthorizedHostExtra(List<HostVO> hosts,
|
||||
List<Long> favorite,
|
||||
Map<Long, String> aliasMap,
|
||||
Map<Long, String> colorMap) {
|
||||
List<Map<Long, String>> extraList) {
|
||||
if (Lists.isEmpty(hosts)) {
|
||||
return;
|
||||
}
|
||||
@@ -321,6 +360,7 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
hosts.get(i).setTags(tags.get(i));
|
||||
}
|
||||
// 设置主机别名
|
||||
Map<Long, String> aliasMap = extraList.get(0);
|
||||
if (!Maps.isEmpty(aliasMap)) {
|
||||
hosts.forEach(s -> {
|
||||
String alias = aliasMap.get(s.getId());
|
||||
@@ -330,6 +370,7 @@ public class AssetAuthorizedDataServiceImpl implements AssetAuthorizedDataServic
|
||||
});
|
||||
}
|
||||
// 设置主机颜色
|
||||
Map<Long, String> colorMap = extraList.get(1);
|
||||
if (!Maps.isEmpty(colorMap)) {
|
||||
hosts.forEach(s -> {
|
||||
HostColorExtraModel color = JSON.parseObject(colorMap.get(s.getId()), HostColorExtraModel.class);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.orion.ops.module.asset.service.impl;
|
||||
|
||||
import com.orion.lang.utils.Exceptions;
|
||||
import com.orion.ops.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.ops.framework.common.constant.Const;
|
||||
import com.orion.ops.framework.common.constant.ErrorMessage;
|
||||
import com.orion.ops.framework.common.enums.BooleanBit;
|
||||
import com.orion.ops.framework.common.enums.EnableStatus;
|
||||
import com.orion.ops.framework.common.handler.data.model.GenericsDataModel;
|
||||
import com.orion.ops.framework.common.handler.data.strategy.MapDataStrategy;
|
||||
@@ -21,10 +23,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -66,6 +65,10 @@ public class HostConfigServiceImpl implements HostConfigService {
|
||||
if (config == null) {
|
||||
return null;
|
||||
}
|
||||
// 检查配置状态
|
||||
if (!BooleanBit.toBoolean(config.getStatus())) {
|
||||
throw Exceptions.disabled();
|
||||
}
|
||||
return type.parse(config.getConfig());
|
||||
}
|
||||
|
||||
@@ -145,6 +148,7 @@ public class HostConfigServiceImpl implements HostConfigService {
|
||||
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();
|
||||
@@ -167,6 +171,20 @@ public class HostConfigServiceImpl implements HostConfigService {
|
||||
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()
|
||||
.stream()
|
||||
.map(HostConfigDO::getHostId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过类型获取配置
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user