🐛 SSH 配置未启用还可以连接.
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
* [常见问题](quickstart/faq.md)
|
||||
* 操作手册
|
||||
* [资产管理](operator/asset.md)
|
||||
* [主机运维](operator/host_ops.md)
|
||||
* [运维审计](operator/host_audit.md)
|
||||
* [主机运维](operator/host-ops.md)
|
||||
* [运维审计](operator/asset-audit.md)
|
||||
* [用户管理](operator/user.md)
|
||||
* [系统管理](operator/system.md)
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
> 版本号严格遵循 Semver 规范。
|
||||
|
||||
## v1.0.2
|
||||
|
||||
`2024-03-` `release`
|
||||
|
||||
🐞 修复 SSH 配置未启用还可以连接
|
||||
🐞 修复 主机配置保存后无法修改状态
|
||||
|
||||
[如何升级](/about/update.md?id=_v102)
|
||||
|
||||
## v1.0.1
|
||||
|
||||
`2024-03-06` `release`
|
||||
@@ -11,7 +20,7 @@
|
||||
🌈 新增 主机连接日志删除/清理
|
||||
🌈 新增 用户操作日志日志删除/清理
|
||||
🌈 新增 用户操作日志日志删除/清理
|
||||
🔨 优化 用户锁定次数/时间可配置
|
||||
🔨 优化 用户锁定次数/时间可配置
|
||||
|
||||
[如何升级](/about/update.md?id=_v101)
|
||||
|
||||
|
||||
@@ -75,8 +75,6 @@ public interface ErrorMessage {
|
||||
|
||||
String SESSION_ABSENT = "会话不存在";
|
||||
|
||||
String CONNECT_ERROR = "连接失败";
|
||||
|
||||
String PATH_NOT_NORMALIZE = "路径不合法";
|
||||
|
||||
String OPERATE_ERROR = "操作失败";
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过类型获取配置
|
||||
*
|
||||
|
||||
@@ -101,6 +101,16 @@ public interface DataExtraApi {
|
||||
*/
|
||||
Future<Map<Long, String>> getExtraItemValuesByCacheAsync(Long userId, DataExtraTypeEnum type, String item);
|
||||
|
||||
/**
|
||||
* 异步查询额外配置项 (查询缓存)
|
||||
*
|
||||
* @param userId userId
|
||||
* @param type type
|
||||
* @param items items
|
||||
* @return value
|
||||
*/
|
||||
Future<List<Map<Long, String>>> getExtraItemsValuesByCacheAsync(Long userId, DataExtraTypeEnum type, List<String> items);
|
||||
|
||||
/**
|
||||
* 查询额外配置
|
||||
*
|
||||
|
||||
@@ -102,6 +102,13 @@ public class DataExtraApiImpl implements DataExtraApi {
|
||||
return CompletableFuture.completedFuture(this.getExtraItemValuesByCache(userId, type, item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<List<Map<Long, String>>> getExtraItemsValuesByCacheAsync(Long userId, DataExtraTypeEnum type, List<String> items) {
|
||||
Valid.allNotNull(userId, type);
|
||||
Valid.notEmpty(items);
|
||||
return CompletableFuture.completedFuture(dataExtraService.getExtraItemsValuesByCache(userId, type.name(), items));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataExtraDTO getExtraItem(DataExtraQueryDTO dto, DataExtraTypeEnum type) {
|
||||
Valid.allNotNull(dto.getUserId(), dto.getRelId(), dto.getItem());
|
||||
|
||||
@@ -85,6 +85,16 @@ public interface DataExtraService {
|
||||
*/
|
||||
Map<Long, String> getExtraItemValuesByCache(Long userId, String type, String item);
|
||||
|
||||
/**
|
||||
* 查询额外配置项 (查询缓存)
|
||||
*
|
||||
* @param userId userId
|
||||
* @param type type
|
||||
* @param items items
|
||||
* @return [relId:value, relId:value]
|
||||
*/
|
||||
List<Map<Long, String>> getExtraItemsValuesByCache(Long userId, String type, List<String> items);
|
||||
|
||||
/**
|
||||
* 查询额外配置
|
||||
*
|
||||
|
||||
@@ -170,6 +170,13 @@ public class DataExtraServiceImpl implements DataExtraService {
|
||||
return Maps.map(entities, Long::valueOf, Function.identity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<Long, String>> getExtraItemsValuesByCache(Long userId, String type, List<String> items) {
|
||||
return items.stream()
|
||||
.map(s -> this.getExtraItemValuesByCache(userId, type, s))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataExtraDO getExtraItem(DataExtraQueryRequest request) {
|
||||
return dataExtraDAO.of()
|
||||
|
||||
@@ -17,8 +17,8 @@ export interface AuthorizedHostQueryResponse {
|
||||
/**
|
||||
* 查询当前用户已授权的主机
|
||||
*/
|
||||
export function getCurrentAuthorizedHost() {
|
||||
return axios.get<AuthorizedHostQueryResponse>('/asset/authorized-data/current-host');
|
||||
export function getCurrentAuthorizedHost(type: string) {
|
||||
return axios.get<AuthorizedHostQueryResponse>('/asset/authorized-data/current-host', { params: { type } });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -128,7 +128,7 @@ export default defineStore('terminal', {
|
||||
if (this.hosts.hostList?.length) {
|
||||
return;
|
||||
}
|
||||
const { data } = await getCurrentAuthorizedHost();
|
||||
const { data } = await getCurrentAuthorizedHost('ssh');
|
||||
Object.keys(data).forEach(k => {
|
||||
this.hosts[k as keyof AuthorizedHostQueryResponse] = data[k as keyof AuthorizedHostQueryResponse] as any;
|
||||
});
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
unchecked-text="使用原密码" />
|
||||
</a-form-item>
|
||||
<!-- 秘钥id -->
|
||||
<a-form-item field="keyId" label="主机秘钥">
|
||||
<a-form-item field="keyId"
|
||||
label="主机秘钥"
|
||||
extra="密码和秘钥二选一 优先使用秘钥">
|
||||
<host-key-selector v-model="formModel.keyId" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
@@ -260,7 +260,7 @@
|
||||
setLoading(false);
|
||||
Message.success('修改成功');
|
||||
// 回调 props
|
||||
emits('submitted', { ...props.content, config: { ...formModel.value } });
|
||||
emits('submitted', { ...props.content, ...config, config: { ...formModel.value } });
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<!-- 主机列表 -->
|
||||
<host-list-view class="host-list"
|
||||
:hostList="hostList"
|
||||
empty-value="当前分组内无授权主机!" />
|
||||
empty-value="当前分组内无授权主机/主机未启用 SSH 配置!" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<!-- 列表视图 -->
|
||||
<host-list-view v-if="NewConnectionType.LIST === newConnectionType"
|
||||
:hostList="hostList"
|
||||
empty-value="无授权主机!" />
|
||||
empty-value="无授权主机/主机未启用 SSH 配置!" />
|
||||
<!-- 我的收藏 -->
|
||||
<host-list-view v-if="NewConnectionType.FAVORITE === newConnectionType"
|
||||
class="list-view-container"
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</div>
|
||||
<!-- 已关闭-右侧操作 -->
|
||||
<div v-if="isClose" class="sftp-table-header-right">
|
||||
<span class="close-message">{{ closeMessage }}</span>
|
||||
<span class="close-message" :title="closeMessage">{{ closeMessage }}</span>
|
||||
</div>
|
||||
<!-- 路径编辑模式-右侧操作 -->
|
||||
<a-space v-else-if="pathEditable" class="sftp-table-header-right">
|
||||
|
||||
@@ -190,10 +190,10 @@
|
||||
|
||||
// 关闭回调
|
||||
const onClose = (forceClose: string, msg: string) => {
|
||||
console.log(forceClose);
|
||||
console.log(msg);
|
||||
closed.value = true;
|
||||
closeMessage.value = msg;
|
||||
setTableLoading(false);
|
||||
setEditorLoading(false);
|
||||
};
|
||||
|
||||
// 接收列表回调
|
||||
|
||||
@@ -47,6 +47,7 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor
|
||||
});
|
||||
} else {
|
||||
// 未成功提示错误信息
|
||||
session.resolver?.onClose('0', msg);
|
||||
Message.error(msg || '建立 SFTP 失败');
|
||||
}
|
||||
}
|
||||
@@ -75,6 +76,7 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor
|
||||
session.connect();
|
||||
} else {
|
||||
// 未成功提示错误信息
|
||||
session.resolver?.onClose('0', msg);
|
||||
Message.error(msg || '打开 SFTP 失败');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user