diff --git a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/ErrorMessage.java b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/ErrorMessage.java index 65384894..93e47648 100644 --- a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/ErrorMessage.java +++ b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/ErrorMessage.java @@ -77,4 +77,6 @@ public interface ErrorMessage { String CONNECT_ERROR = "连接失败"; + String PATH_NOT_NORMALIZE = "路径不合法"; + } diff --git a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/utils/Valid.java b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/utils/Valid.java index eed186b6..60fadcb2 100644 --- a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/utils/Valid.java +++ b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/utils/Valid.java @@ -1,6 +1,7 @@ package com.orion.ops.framework.common.utils; import com.orion.lang.utils.Arrays1; +import com.orion.lang.utils.io.Files1; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.spring.SpringHolder; @@ -116,4 +117,15 @@ public class Valid extends com.orion.lang.utils.Valid { return effect; } + /** + * 检查路径是否合法化 即不包含 ./ ../ + * + * @param path path + */ + public static String checkNormalize(String path) { + Valid.notBlank(path); + Valid.isTrue(Files1.isNormalize(path), ErrorMessage.PATH_NOT_NORMALIZE); + return Files1.getPath(path); + } + } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/AbstractTerminalHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/AbstractTerminalHandler.java index 9f9115b1..f9e57385 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/AbstractTerminalHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/AbstractTerminalHandler.java @@ -2,9 +2,12 @@ package com.orion.ops.module.asset.handler.host.terminal.handler; import com.orion.ops.framework.websocket.core.utils.WebSockets; import com.orion.ops.module.asset.handler.host.terminal.enums.OutputTypeEnum; +import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager; import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; import org.springframework.web.socket.WebSocketSession; +import javax.annotation.Resource; + /** * 终端消息处理器 基类 * @@ -14,6 +17,9 @@ import org.springframework.web.socket.WebSocketSession; */ public abstract class AbstractTerminalHandler implements ITerminalHandler { + @Resource + protected TerminalManager terminalManager; + /** * 发送消息 * diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshInputHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshInputHandler.java index dba653d8..c3db3706 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshInputHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshInputHandler.java @@ -1,15 +1,11 @@ package com.orion.ops.module.asset.handler.host.terminal.handler; -import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager; import com.orion.ops.module.asset.handler.host.terminal.model.request.SshInputRequest; import com.orion.ops.module.asset.handler.host.terminal.session.ISshSession; -import com.orion.ops.module.asset.handler.host.terminal.session.ITerminalSession; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketSession; -import javax.annotation.Resource; - /** * ssh 处理输入处理器 * @@ -21,17 +17,12 @@ import javax.annotation.Resource; @Component public class SshInputHandler extends AbstractTerminalHandler { - @Resource - private TerminalManager terminalManager; - @Override public void handle(WebSocketSession channel, SshInputRequest payload) { // 获取会话 - ITerminalSession session = terminalManager.getSession(channel.getId(), payload.getSessionId()); - if (session instanceof ISshSession) { - // 处理输入 - ((ISshSession) session).write(payload.getCommand()); - } + ISshSession session = terminalManager.getSession(channel.getId(), payload.getSessionId()); + // 处理输入 + session.write(payload.getCommand()); } } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshResizeHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshResizeHandler.java index 4d545e6e..de6fa838 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshResizeHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshResizeHandler.java @@ -1,15 +1,11 @@ package com.orion.ops.module.asset.handler.host.terminal.handler; -import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager; import com.orion.ops.module.asset.handler.host.terminal.model.request.SshResizeRequest; import com.orion.ops.module.asset.handler.host.terminal.session.ISshSession; -import com.orion.ops.module.asset.handler.host.terminal.session.ITerminalSession; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketSession; -import javax.annotation.Resource; - /** * ssh 修改大小处理器 * @@ -21,17 +17,12 @@ import javax.annotation.Resource; @Component public class SshResizeHandler extends AbstractTerminalHandler { - @Resource - private TerminalManager terminalManager; - @Override public void handle(WebSocketSession channel, SshResizeRequest payload) { // 获取会话 - ITerminalSession session = terminalManager.getSession(channel.getId(), payload.getSessionId()); - if (session instanceof ISshSession) { - // 修改大小 - ((ISshSession) session).resize(payload.getCols(), payload.getRows()); - } + ISshSession session = terminalManager.getSession(channel.getId(), payload.getSessionId()); + // 修改大小 + session.resize(payload.getCols(), payload.getRows()); } } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java index cbe78d55..77a0b1c1 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java @@ -17,7 +17,6 @@ import com.orion.ops.module.asset.entity.request.host.HostConnectLogCreateReques 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.enums.OutputTypeEnum; -import com.orion.ops.module.asset.handler.host.terminal.manager.TerminalManager; import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalCheckRequest; import com.orion.ops.module.asset.handler.host.terminal.model.response.TerminalCheckResponse; import com.orion.ops.module.asset.handler.host.terminal.session.ITerminalSession; @@ -53,9 +52,6 @@ public class TerminalCheckHandler extends AbstractTerminalHandler { - @Resource - private TerminalManager terminalManager; - @Override public void handle(WebSocketSession channel, TerminalBasePayload payload) { log.info("TerminalCloseHandler-handle start session: {}", payload.getSessionId()); diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java index 4c9decc2..4fa9a1e2 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java @@ -14,7 +14,6 @@ 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.manager.TerminalManager; import com.orion.ops.module.asset.handler.host.terminal.model.TerminalConfig; import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalConnectRequest; import com.orion.ops.module.asset.handler.host.terminal.model.response.TerminalConnectResponse; @@ -46,9 +45,6 @@ public class TerminalConnectHandler extends AbstractTerminalHandler { - @Resource - private TerminalManager terminalManager; - @Override public void handle(WebSocketSession channel, TerminalBasePayload payload) { // 发送 pong diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/manager/TerminalManager.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/manager/TerminalManager.java index 7d8a35fe..f36505fb 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/manager/TerminalManager.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/manager/TerminalManager.java @@ -52,10 +52,12 @@ public class TerminalManager { * * @param channelId channelId * @param sessionId sessionId + * @param T T * @return session */ - public ITerminalSession getSession(String channelId, String sessionId) { - return channelSessions.get(channelId, sessionId); + @SuppressWarnings("unchecked") + public T getSession(String channelId, String sessionId) { + return (T) channelSessions.get(channelId, sessionId); } /** diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpChangeModRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpChangeModRequest.java index 4e98fafc..921b6eea 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpChangeModRequest.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpChangeModRequest.java @@ -28,7 +28,7 @@ public class SftpChangeModRequest extends TerminalBasePayload { @Schema(description = "path") private String path; - @Schema(description = "权限") - private String mod; + @Schema(description = "10进制的8进制 权限") + private Integer mod; } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpRemoveRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpRemoveRequest.java index dcbb1bb9..8e877aeb 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpRemoveRequest.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpRemoveRequest.java @@ -8,10 +8,12 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; +import java.util.List; + /** * sftp 删除文件 实体对象 *

- * i|eff00a1|path + * i|eff00a1|paths * * @author Jiahang Li * @version 1.0.0 @@ -25,7 +27,7 @@ import lombok.experimental.SuperBuilder; @Schema(name = "SftpRemoveRequest", description = "sftp 删除文件 实体对象") public class SftpRemoveRequest extends TerminalBasePayload { - @Schema(description = "path") - private String path; + @Schema(description = "paths 多个用|分割") + private List paths; } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SftpListResponse.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SftpListResponse.java index 38097c6e..30410c48 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SftpListResponse.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SftpListResponse.java @@ -23,12 +23,12 @@ import lombok.experimental.SuperBuilder; @Schema(name = "SftpListResponse", description = "sftp 列表响应 实体对象") public class SftpListResponse extends TerminalBasePayload { - @Schema(description = "检查结果") - private Integer result; - @Schema(description = "path") private String path; + @Schema(description = "结果") + private Integer result; + @Schema(description = "body") private String body; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/ISftpSession.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/ISftpSession.java index da1cb26b..8edb0388 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/ISftpSession.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/ISftpSession.java @@ -34,4 +34,64 @@ public interface ISftpSession extends ITerminalSession { */ List list(String path, boolean showHiddenFile); + /** + * 创建文件夹 + * + * @param path path + */ + void mkdir(String path); + + /** + * 创建文件 + * + * @param path path + */ + void touch(String path); + + /** + * 移动文件 + * + * @param source source + * @param target target + */ + void move(String source, String target); + + /** + * 删除文件 + * + * @param paths paths + */ + void remove(List paths); + + /** + * 截断文件 + * + * @param path path + */ + void truncate(String path); + + /** + * 修改权限 + * + * @param path path + * @param mod mod + */ + void chmod(String path, int mod); + + /** + * 获取内容 + * + * @param path path + * @return content + */ + String getContent(String path); + + /** + * 设置内容 + * + * @param path path + * @param content content + */ + void setContent(String path, String content); + } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/SftpSession.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/SftpSession.java index 5c994288..23a366c2 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/SftpSession.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/SftpSession.java @@ -1,5 +1,7 @@ package com.orion.ops.module.asset.handler.host.terminal.session; +import com.orion.lang.utils.Exceptions; +import com.orion.lang.utils.Strings; import com.orion.lang.utils.io.FileType; import com.orion.lang.utils.io.Files1; import com.orion.lang.utils.io.Streams; @@ -7,17 +9,19 @@ import com.orion.net.host.SessionStore; import com.orion.net.host.sftp.SftpExecutor; import com.orion.net.host.sftp.SftpFile; import com.orion.ops.framework.common.constant.Const; +import com.orion.ops.framework.common.utils.Valid; import com.orion.ops.module.asset.handler.host.terminal.model.TerminalConfig; import com.orion.ops.module.asset.handler.host.terminal.model.response.SftpFileResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.web.socket.WebSocketSession; +import java.io.InputStream; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** - * 终端 ssh 会话 + * 终端 sftp 会话 * * @author Jiahang Li * @version 1.0.0 @@ -55,6 +59,7 @@ public class SftpSession extends TerminalSession implements ISftpSession { @Override public List list(String path, boolean showHiddenFile) { + path = Files1.getPath(path); // 查询文件 List files = executor.listFilesFilter(path, s -> showHiddenFile || !s.getName().startsWith(Const.DOT), @@ -65,6 +70,63 @@ public class SftpSession extends TerminalSession implements ISftpSession { .collect(Collectors.toList()); } + @Override + public void mkdir(String path) { + path = Valid.checkNormalize(path); + executor.makeDirectories(path); + } + + @Override + public void touch(String path) { + path = Valid.checkNormalize(path); + executor.touch(path); + } + + @Override + public void move(String source, String target) { + source = Valid.checkNormalize(source); + executor.move(source, target); + } + + @Override + public void remove(List paths) { + paths.stream() + .map(Valid::checkNormalize) + .forEach(executor::remove); + } + + @Override + public void truncate(String path) { + path = Valid.checkNormalize(path); + executor.truncate(path); + } + + @Override + public void chmod(String path, int mod) { + path = Valid.checkNormalize(path); + executor.changeMode(path, mod); + } + + @Override + public String getContent(String path) { + path = Valid.checkNormalize(path); + try (InputStream in = executor.openInputStream(path)) { + return Streams.toString(in, config.getFileContentCharset()); + } catch (Exception e) { + throw Exceptions.ioRuntime(e); + } + } + + @Override + public void setContent(String path, String content) { + path = Valid.checkNormalize(path); + try { + executor.write(path, Strings.bytes(content, config.getFileContentCharset())); + } catch (Exception e) { + throw Exceptions.ioRuntime(e); + } + } + @Override public void keepAlive() { try {