diff --git a/orion-ops-launch/src/main/resources/application-dev.yaml b/orion-ops-launch/src/main/resources/application-dev.yaml index d56199ec..505e4f38 100644 --- a/orion-ops-launch/src/main/resources/application-dev.yaml +++ b/orion-ops-launch/src/main/resources/application-dev.yaml @@ -1,14 +1,14 @@ spring: datasource: druid: - url: jdbc:mysql://127.0.0.1:3306/orion-ops-pro?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true + url: jdbc:mysql://116.62.194.246:3306/orion-ops-pro?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true username: root password: Data@123456 initial-size: 0 min-idle: 1 max-active: 5 redis: - host: 127.0.0.1 + host: 116.62.194.246 port: 6379 database: 0 password: lijiahang diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/enums/InputTypeEnum.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/enums/InputTypeEnum.java index c1478d33..0d13898f 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/enums/InputTypeEnum.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/enums/InputTypeEnum.java @@ -3,10 +3,7 @@ package com.orion.ops.module.asset.handler.host.terminal.enums; import com.alibaba.fastjson.JSONObject; import com.orion.ops.module.asset.handler.host.terminal.handler.*; import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; -import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalCheckRequest; -import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalConnectRequest; -import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalInputRequest; -import com.orion.ops.module.asset.handler.host.terminal.model.request.TerminalResizeRequest; +import com.orion.ops.module.asset.handler.host.terminal.model.request.*; import com.orion.spring.SpringHolder; import lombok.Getter; import org.springframework.stereotype.Component; @@ -55,27 +52,46 @@ public enum InputTypeEnum { TerminalBasePayload.class), /** - * 修改大小 + * SSH 修改大小 */ - RESIZE("rs", - TerminalResizeHandler.class, + SSH_RESIZE("rs", + SshResizeHandler.class, new String[]{"type", "sessionId", "cols", "rows"}, - TerminalResizeRequest.class), + SshResizeRequest.class), /** - * 输入 + * SSH 输入 */ - INPUT("i", - TerminalInputHandler.class, + SSH_INPUT("i", + SshInputHandler.class, new String[]{"type", "sessionId", "command"}, - TerminalInputRequest.class), + SshInputRequest.class), - // LS - // MK - // RM - // MV - // TC - // CD + /** + * SFTP 文件列表 + */ + SFTP_LIST("ls", + SftpListHandler.class, + new String[]{"type", "sessionId", "path"}, + SftpListRequest.class), + + + // TODO + // MKDIR + // TOUCH + + // REMOVE + // MOVE + // TRUNCATE + + // CHMOD + + // GET + // SAVE + + // COPY + // UPLOAD + // DOWNLOAD ; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/enums/OutputTypeEnum.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/enums/OutputTypeEnum.java index e3eaccfa..b2de818d 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/enums/OutputTypeEnum.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/enums/OutputTypeEnum.java @@ -36,9 +36,14 @@ public enum OutputTypeEnum { PONG("p", "${type}"), /** - * 输出 + * SSH 输出 */ - OUTPUT("o", "${type}|${sessionId}|${body}"), + SSH_OUTPUT("o", "${type}|${sessionId}|${body}"), + + /** + * SFTP 文件列表 + */ + SFTP_LIST("ls", "${type}|${sessionId}|${result}|${path}|${body}"), ; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SftpListHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SftpListHandler.java new file mode 100644 index 00000000..a4ae7df2 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SftpListHandler.java @@ -0,0 +1,66 @@ +package com.orion.ops.module.asset.handler.host.terminal.handler; + +import com.alibaba.fastjson.JSON; +import com.orion.lang.utils.Strings; +import com.orion.ops.framework.common.enums.BooleanBit; +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.SftpListRequest; +import com.orion.ops.module.asset.handler.host.terminal.model.response.SftpFileResponse; +import com.orion.ops.module.asset.handler.host.terminal.model.response.SftpListResponse; +import com.orion.ops.module.asset.handler.host.terminal.session.ISftpSession; +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; +import java.util.List; + +/** + * sftp 文件列表 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/12/29 15:32 + */ +@Slf4j +@Component +public class SftpListHandler extends AbstractTerminalHandler { + + @Resource + private TerminalManager terminalManager; + + @Override + public void handle(WebSocketSession channel, SftpListRequest payload) { + // 获取会话 + ITerminalSession session = terminalManager.getSession(channel.getId(), payload.getSessionId()); + String path = payload.getPath(); + log.info("SftpListHandler-handle session: {}, path: {}", payload.getSessionId(), path); + if (session instanceof ISftpSession) { + Exception ex = null; + List list = null; + try { + // 空目录则直接获取 home 目录 + if (Strings.isBlank(path)) { + path = ((ISftpSession) session).getHome(); + } + // 文件列表 + list = ((ISftpSession) session).list(path); + } catch (Exception e) { + log.error("SftpListHandler-handle error", e); + ex = e; + } + // 返回 + this.send(channel, + OutputTypeEnum.SFTP_LIST, + SftpListResponse.builder() + .sessionId(payload.getSessionId()) + .result(BooleanBit.of(ex == null).getValue()) + .path(path) + .body(list == null ? null : JSON.toJSONString(list)) + .build()); + } + } + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalInputHandler.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 similarity index 81% rename from orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalInputHandler.java rename to orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshInputHandler.java index 24e69842..dba653d8 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalInputHandler.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,7 +1,7 @@ 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.TerminalInputRequest; +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; @@ -11,7 +11,7 @@ import org.springframework.web.socket.WebSocketSession; import javax.annotation.Resource; /** - * 处理输入处理器 + * ssh 处理输入处理器 * * @author Jiahang Li * @version 1.0.0 @@ -19,13 +19,13 @@ import javax.annotation.Resource; */ @Slf4j @Component -public class TerminalInputHandler extends AbstractTerminalHandler { +public class SshInputHandler extends AbstractTerminalHandler { @Resource private TerminalManager terminalManager; @Override - public void handle(WebSocketSession channel, TerminalInputRequest payload) { + public void handle(WebSocketSession channel, SshInputRequest payload) { // 获取会话 ITerminalSession session = terminalManager.getSession(channel.getId(), payload.getSessionId()); if (session instanceof ISshSession) { diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalResizeHandler.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 similarity index 81% rename from orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalResizeHandler.java rename to orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/SshResizeHandler.java index 0f24676c..4d545e6e 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/handler/TerminalResizeHandler.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,7 +1,7 @@ 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.TerminalResizeRequest; +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; @@ -11,7 +11,7 @@ import org.springframework.web.socket.WebSocketSession; import javax.annotation.Resource; /** - * 修改大小处理器 + * ssh 修改大小处理器 * * @author Jiahang Li * @version 1.0.0 @@ -19,13 +19,13 @@ import javax.annotation.Resource; */ @Slf4j @Component -public class TerminalResizeHandler extends AbstractTerminalHandler { +public class SshResizeHandler extends AbstractTerminalHandler { @Resource private TerminalManager terminalManager; @Override - public void handle(WebSocketSession channel, TerminalResizeRequest payload) { + public void handle(WebSocketSession channel, SshResizeRequest payload) { // 获取会话 ITerminalSession session = terminalManager.getSession(channel.getId(), payload.getSessionId()); if (session instanceof ISshSession) { 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/SftpChangeModeRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpChangeModeRequest.java new file mode 100644 index 00000000..a137a99f --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpChangeModeRequest.java @@ -0,0 +1,34 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.request; + +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * sftp 修改文件权限 实体对象 + *

+ * i|eff00a1|path|mode + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 13:31 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "SftpChangeModeRequest", description = "sftp 修改文件权限 实体对象") +public class SftpChangeModeRequest extends TerminalBasePayload { + + @Schema(description = "path") + private String path; + + @Schema(description = "权限") + private String mode; + +} 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/SftpListRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpListRequest.java new file mode 100644 index 00000000..eec64c8d --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpListRequest.java @@ -0,0 +1,31 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.request; + +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * sftp 列表请求 实体对象 + *

+ * i|eff00a1|path + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 13:31 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "SftpListRequest", description = "sftp 列表请求 实体对象") +public class SftpListRequest extends TerminalBasePayload { + + @Schema(description = "path") + private String path; + +} 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/SftpMakeDirectoryRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpMakeDirectoryRequest.java new file mode 100644 index 00000000..fd623c9e --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpMakeDirectoryRequest.java @@ -0,0 +1,31 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.request; + +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * sftp 创建文件夹 实体对象 + *

+ * i|eff00a1|path + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 13:31 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "SftpMakeDirectoryRequest", description = "sftp 创建文件夹 实体对象") +public class SftpMakeDirectoryRequest extends TerminalBasePayload { + + @Schema(description = "path") + private String path; + +} 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/SftpMoveRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpMoveRequest.java new file mode 100644 index 00000000..405f3583 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpMoveRequest.java @@ -0,0 +1,34 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.request; + +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * sftp 移动文件 实体对象 + *

+ * i|eff00a1|source|target + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 13:31 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "SftpMoveRequest", description = "sftp 移动文件 实体对象") +public class SftpMoveRequest extends TerminalBasePayload { + + @Schema(description = "source") + private String source; + + @Schema(description = "target") + private String target; + +} 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 new file mode 100644 index 00000000..dcbb1bb9 --- /dev/null +++ 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 @@ -0,0 +1,31 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.request; + +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * sftp 删除文件 实体对象 + *

+ * i|eff00a1|path + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 13:31 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "SftpRemoveRequest", description = "sftp 删除文件 实体对象") +public class SftpRemoveRequest extends TerminalBasePayload { + + @Schema(description = "path") + private String path; + +} 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/SftpTouchRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpTouchRequest.java new file mode 100644 index 00000000..b63a54ce --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpTouchRequest.java @@ -0,0 +1,31 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.request; + +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * sftp 创建文件 实体对象 + *

+ * i|eff00a1|path + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 13:31 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "SftpTouchRequest", description = "sftp 创建文件 实体对象") +public class SftpTouchRequest extends TerminalBasePayload { + + @Schema(description = "path") + private String path; + +} 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/SftpTruncateRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpTruncateRequest.java new file mode 100644 index 00000000..afa893ec --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SftpTruncateRequest.java @@ -0,0 +1,31 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.request; + +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * sftp 截断文件 实体对象 + *

+ * i|eff00a1|path + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 13:31 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "SftpTruncateRequest", description = "sftp 截断文件 实体对象") +public class SftpTruncateRequest extends TerminalBasePayload { + + @Schema(description = "path") + private String path; + +} 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/TerminalInputRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SshInputRequest.java similarity index 78% rename from orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/TerminalInputRequest.java rename to orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SshInputRequest.java index 6ab16e58..a5583ed1 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/TerminalInputRequest.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SshInputRequest.java @@ -9,7 +9,7 @@ import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; /** - * 输入请求 实体对象 + * ssh 输入请求 实体对象 *

* i|eff00a1|command * @@ -22,8 +22,8 @@ import lombok.experimental.SuperBuilder; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) -@Schema(name = "TerminalInputRequest", description = "输入请求 实体对象") -public class TerminalInputRequest extends TerminalBasePayload { +@Schema(name = "SshInputRequest", description = "ssh 输入请求 实体对象") +public class SshInputRequest extends TerminalBasePayload { @Schema(description = "command") private String command; 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/TerminalResizeRequest.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SshResizeRequest.java similarity index 78% rename from orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/TerminalResizeRequest.java rename to orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SshResizeRequest.java index 16574560..f3cd6d01 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/TerminalResizeRequest.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/request/SshResizeRequest.java @@ -9,7 +9,7 @@ import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; /** - * 修改大小请求 实体对象 + * ssh 修改大小请求 实体对象 *

* rs|eff00a1|100|20 * @@ -22,8 +22,8 @@ import lombok.experimental.SuperBuilder; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) -@Schema(name = "TerminalResizeRequest", description = "修改大小请求 实体对象") -public class TerminalResizeRequest extends TerminalBasePayload { +@Schema(name = "SshResizeRequest", description = "ssh 修改大小请求 实体对象") +public class SshResizeRequest extends TerminalBasePayload { @Schema(description = "列数") private Integer cols; 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/SftpFileResponse.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SftpFileResponse.java new file mode 100644 index 00000000..15334247 --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SftpFileResponse.java @@ -0,0 +1,58 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.Date; + +/** + * sftp 文件响应 实体对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 13:57 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "SftpFileResponse", description = "sftp 文件响应 实体对象") +public class SftpFileResponse { + + @Schema(description = "名称") + private String name; + + @Schema(description = "绝对路径") + private String path; + + @Schema(description = "文件后缀") + private String suffix; + + @Schema(description = "文件大小") + private String size; + + @Schema(description = "文件大小(byte)") + private Long sizeByte; + + @Schema(description = "属性") + private String attr; + + @Schema(description = "是否为目录") + private Boolean isDir; + + @Schema(description = "10进制表现的8进制权限") + private Integer permission; + + @Schema(description = "用户id") + private Integer uid; + + @Schema(description = "组id") + private Integer gid; + + @Schema(description = "更新时间") + private Date modifyTime; + +} 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 new file mode 100644 index 00000000..38097c6e --- /dev/null +++ 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 @@ -0,0 +1,35 @@ +package com.orion.ops.module.asset.handler.host.terminal.model.response; + +import com.orion.ops.module.asset.handler.host.terminal.model.TerminalBasePayload; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +/** + * sftp 列表响应 实体对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/2/6 16:20 + */ +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@Schema(name = "SftpListResponse", description = "sftp 列表响应 实体对象") +public class SftpListResponse extends TerminalBasePayload { + + @Schema(description = "检查结果") + private Integer result; + + @Schema(description = "path") + private String path; + + @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/model/response/TerminalOutputResponse.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SshOutputResponse.java similarity index 76% rename from orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/TerminalOutputResponse.java rename to orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SshOutputResponse.java index 01efddc7..f34296e5 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/TerminalOutputResponse.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/model/response/SshOutputResponse.java @@ -9,7 +9,7 @@ import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; /** - * 主机输出响应 实体对象 + * ssh 输出响应 实体对象 * * @author Jiahang Li * @version 1.0.0 @@ -20,8 +20,8 @@ import lombok.experimental.SuperBuilder; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = true) -@Schema(name = "TerminalOutputResponse", description = "主机输出响应 实体对象") -public class TerminalOutputResponse extends TerminalBasePayload { +@Schema(name = "SshOutputResponse", description = "ssh 输出响应 实体对象") +public class SshOutputResponse extends TerminalBasePayload { @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 e8157daa..887f9b26 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 @@ -1,5 +1,9 @@ package com.orion.ops.module.asset.handler.host.terminal.session; +import com.orion.ops.module.asset.handler.host.terminal.model.response.SftpFileResponse; + +import java.util.List; + /** * sftp 会话定义 * @@ -14,4 +18,19 @@ public interface ISftpSession extends ITerminalSession { */ void connect(); + /** + * 获取 home 路径 + * + * @return homePath + */ + String getHome(); + + /** + * 文件列表 + * + * @param path path + * @return list + */ + List list(String path); + } 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 b1823d1b..8b8e2e47 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,13 +1,23 @@ package com.orion.ops.module.asset.handler.host.terminal.session; +import com.orion.lang.utils.Strings; +import com.orion.lang.utils.convert.TypeStore; +import com.orion.lang.utils.io.FileType; +import com.orion.lang.utils.io.Files1; import com.orion.lang.utils.io.Streams; 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.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.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + /** * 终端 ssh 会话 * @@ -40,6 +50,20 @@ public class SftpSession extends TerminalSession implements ISftpSession { executor.connect(); } + @Override + public String getHome() { + return executor.getHome(); + } + + @Override + public List list(String path) { + // 查询文件 + List files = executor.listFilesFilter(path, f -> !f.getName().startsWith("."), false, true); + return files.stream() + .map(SftpSession::fileMapping) + .collect(Collectors.toList()); + } + @Override public void keepAlive() { try { @@ -56,4 +80,29 @@ public class SftpSession extends TerminalSession implements ISftpSession { Streams.close(sessionStore); } + /** + * 文件映射 + * + * @param sftpFile sftpFile + * @return file + */ + private static SftpFileResponse fileMapping(SftpFile sftpFile) { + SftpFileResponse file = new SftpFileResponse(); + file.setName(sftpFile.getName()); + file.setPath(sftpFile.getPath()); + file.setSuffix(Files1.getSuffix(sftpFile.getName())); + file.setSize(Files1.getSize(sftpFile.getSize())); + file.setSizeByte(sftpFile.getSize()); + file.setPermission(sftpFile.getPermission()); + file.setUid(sftpFile.getUid()); + file.setGid(sftpFile.getGid()); + file.setAttr(sftpFile.getPermissionString()); + file.setModifyTime(sftpFile.getModifyTime()); + Boolean isDir = Optional.ofNullable(FileType.of(file.getAttr())) + .map(FileType.DIRECTORY::equals) + .orElse(false); + file.setIsDir(isDir); + return file; + } + } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/SshSession.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/SshSession.java index 2e1ef5a9..155966e7 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/SshSession.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/terminal/session/SshSession.java @@ -10,7 +10,7 @@ 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.TerminalConfig; import com.orion.ops.module.asset.handler.host.terminal.model.response.TerminalCloseResponse; -import com.orion.ops.module.asset.handler.host.terminal.model.response.TerminalOutputResponse; +import com.orion.ops.module.asset.handler.host.terminal.model.response.SshOutputResponse; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.web.socket.WebSocketSession; @@ -117,12 +117,12 @@ public class SshSession extends TerminalSession implements ISshSession { while (channel.isOpen() && (read = in.read(bs)) != -1) { String body = lastLine = new String(bs, 0, read, config.getCharset()); // 响应 - TerminalOutputResponse resp = TerminalOutputResponse.builder() - .type(OutputTypeEnum.OUTPUT.getType()) + SshOutputResponse resp = SshOutputResponse.builder() + .type(OutputTypeEnum.SSH_OUTPUT.getType()) .sessionId(sessionId) .body(body) .build(); - WebSockets.sendText(channel, OutputTypeEnum.OUTPUT.format(resp)); + WebSockets.sendText(channel, OutputTypeEnum.SSH_OUTPUT.format(resp)); } } catch (IOException ex) { log.error("terminal 读取流失败", ex); diff --git a/orion-ops-ui/src/assets/style/host-terminal-layout.less b/orion-ops-ui/src/assets/style/host-terminal-layout.less index 461c6512..f190b787 100644 --- a/orion-ops-ui/src/assets/style/host-terminal-layout.less +++ b/orion-ops-ui/src/assets/style/host-terminal-layout.less @@ -81,6 +81,147 @@ body[terminal-theme='dark'] { // arco 亮色配色 body .host-terminal-layout, .arco-modal-container { + --red-1: 255, 236, 232; + --red-2: 253, 205, 197; + --red-3: 251, 172, 163; + --red-4: 249, 137, 129; + --red-5: 247, 101, 96; + --red-6: 245, 63, 63; + --red-7: 203, 39, 45; + --red-8: 161, 21, 30; + --red-9: 119, 8, 19; + --red-10: 77, 0, 10; + --orangered-1: 255, 243, 232; + --orangered-2: 253, 221, 195; + --orangered-3: 252, 197, 159; + --orangered-4: 250, 172, 123; + --orangered-5: 249, 144, 87; + --orangered-6: 247, 114, 52; + --orangered-7: 204, 81, 32; + --orangered-8: 162, 53, 17; + --orangered-9: 119, 31, 6; + --orangered-10: 77, 14, 0; + --orange-1: 255, 247, 232; + --orange-2: 255, 228, 186; + --orange-3: 255, 207, 139; + --orange-4: 255, 182, 93; + --orange-5: 255, 154, 46; + --orange-6: 255, 125, 0; + --orange-7: 210, 95, 0; + --orange-8: 166, 69, 0; + --orange-9: 121, 46, 0; + --orange-10: 77, 27, 0; + --gold-1: 255, 252, 232; + --gold-2: 253, 244, 191; + --gold-3: 252, 233, 150; + --gold-4: 250, 220, 109; + --gold-5: 249, 204, 69; + --gold-6: 247, 186, 30; + --gold-7: 204, 146, 19; + --gold-8: 162, 109, 10; + --gold-9: 119, 75, 4; + --gold-10: 77, 45, 0; + --yellow-1: 254, 255, 232; + --yellow-2: 254, 254, 190; + --yellow-3: 253, 250, 148; + --yellow-4: 252, 242, 107; + --yellow-5: 251, 232, 66; + --yellow-6: 250, 220, 25; + --yellow-7: 207, 175, 15; + --yellow-8: 163, 132, 8; + --yellow-9: 120, 93, 3; + --yellow-10: 77, 56, 0; + --lime-1: 252, 255, 232; + --lime-2: 237, 248, 187; + --lime-3: 220, 241, 144; + --lime-4: 201, 233, 104; + --lime-5: 181, 226, 65; + --lime-6: 159, 219, 29; + --lime-7: 126, 183, 18; + --lime-8: 95, 148, 10; + --lime-9: 67, 112, 4; + --lime-10: 42, 77, 0; + --green-1: 232, 255, 234; + --green-2: 175, 240, 181; + --green-3: 123, 225, 136; + --green-4: 76, 210, 99; + --green-5: 35, 195, 67; + --green-6: 0, 180, 42; + --green-7: 0, 154, 41; + --green-8: 0, 128, 38; + --green-9: 0, 102, 34; + --green-10: 0, 77, 28; + --cyan-1: 232, 255, 251; + --cyan-2: 183, 244, 236; + --cyan-3: 137, 233, 224; + --cyan-4: 94, 223, 214; + --cyan-5: 55, 212, 207; + --cyan-6: 20, 201, 201; + --cyan-7: 13, 165, 170; + --cyan-8: 7, 130, 139; + --cyan-9: 3, 97, 108; + --cyan-10: 0, 66, 77; + --blue-1: 232, 247, 255; + --blue-2: 195, 231, 254; + --blue-3: 159, 212, 253; + --blue-4: 123, 192, 252; + --blue-5: 87, 169, 251; + --blue-6: 52, 145, 250; + --blue-7: 32, 108, 207; + --blue-8: 17, 75, 163; + --blue-9: 6, 48, 120; + --blue-10: 0, 26, 77; + --arcoblue-1: 232, 243, 255; + --arcoblue-2: 190, 218, 255; + --arcoblue-3: 148, 191, 255; + --arcoblue-4: 106, 161, 255; + --arcoblue-5: 64, 128, 255; + --arcoblue-6: 22, 93, 255; + --arcoblue-7: 14, 66, 210; + --arcoblue-8: 7, 44, 166; + --arcoblue-9: 3, 26, 121; + --arcoblue-10: 0, 13, 77; + --purple-1: 245, 232, 255; + --purple-2: 221, 190, 246; + --purple-3: 195, 150, 237; + --purple-4: 168, 113, 227; + --purple-5: 141, 78, 218; + --purple-6: 114, 46, 209; + --purple-7: 85, 29, 176; + --purple-8: 60, 16, 143; + --purple-9: 39, 6, 110; + --purple-10: 22, 0, 77; + --pinkpurple-1: 255, 232, 251; + --pinkpurple-2: 247, 186, 239; + --pinkpurple-3: 240, 142, 230; + --pinkpurple-4: 232, 101, 223; + --pinkpurple-5: 225, 62, 219; + --pinkpurple-6: 217, 26, 217; + --pinkpurple-7: 176, 16, 182; + --pinkpurple-8: 138, 9, 147; + --pinkpurple-9: 101, 3, 112; + --pinkpurple-10: 66, 0, 77; + --magenta-1: 255, 232, 241; + --magenta-2: 253, 194, 219; + --magenta-3: 251, 157, 199; + --magenta-4: 249, 121, 183; + --magenta-5: 247, 84, 168; + --magenta-6: 245, 49, 157; + --magenta-7: 203, 30, 131; + --magenta-8: 161, 16, 105; + --magenta-9: 119, 6, 79; + --magenta-10: 77, 0, 52; + --gray-1: 247, 248, 250; + --gray-2: 242, 243, 245; + --gray-3: 229, 230, 235; + --gray-4: 201, 205, 212; + --gray-5: 169, 174, 184; + --gray-6: 134, 144, 156; + --gray-7: 107, 119, 133; + --gray-8: 78, 89, 105; + --gray-9: 39, 46, 59; + --gray-10: 29, 33, 41; + --color-white: #ffffff; --color-black: #000000; --color-border: rgb(var(--gray-3)); @@ -154,6 +295,147 @@ body .host-terminal-layout, .arco-modal-container { body[terminal-theme='dark'], body[terminal-theme='dark'] .host-terminal-layout, body[terminal-theme='dark'] .arco-modal-container { + --red-1: 77, 0, 10; + --red-2: 119, 6, 17; + --red-3: 161, 22, 31; + --red-4: 203, 46, 52; + --red-5: 245, 78, 78; + --red-6: 247, 105, 101; + --red-7: 249, 141, 134; + --red-8: 251, 176, 167; + --red-9: 253, 209, 202; + --red-10: 255, 240, 236; + --orangered-1: 77, 14, 0; + --orangered-2: 119, 30, 5; + --orangered-3: 162, 55, 20; + --orangered-4: 204, 87, 41; + --orangered-5: 247, 126, 69; + --orangered-6: 249, 146, 90; + --orangered-7: 250, 173, 125; + --orangered-8: 252, 198, 161; + --orangered-9: 253, 222, 197; + --orangered-10: 255, 244, 235; + --orange-1: 77, 27, 0; + --orange-2: 121, 48, 4; + --orange-3: 166, 75, 10; + --orange-4: 210, 105, 19; + --orange-5: 255, 141, 31; + --orange-6: 255, 150, 38; + --orange-7: 255, 179, 87; + --orange-8: 255, 205, 135; + --orange-9: 255, 227, 184; + --orange-10: 255, 247, 232; + --gold-1: 77, 45, 0; + --gold-2: 119, 75, 4; + --gold-3: 162, 111, 15; + --gold-4: 204, 150, 31; + --gold-5: 247, 192, 52; + --gold-6: 249, 204, 68; + --gold-7: 250, 220, 108; + --gold-8: 252, 233, 149; + --gold-9: 253, 244, 190; + --gold-10: 255, 252, 232; + --yellow-1: 77, 56, 0; + --yellow-2: 120, 94, 7; + --yellow-3: 163, 134, 20; + --yellow-4: 207, 179, 37; + --yellow-5: 250, 225, 60; + --yellow-6: 251, 233, 75; + --yellow-7: 252, 243, 116; + --yellow-8: 253, 250, 157; + --yellow-9: 254, 254, 198; + --yellow-10: 254, 255, 240; + --lime-1: 42, 77, 0; + --lime-2: 68, 112, 6; + --lime-3: 98, 148, 18; + --lime-4: 132, 183, 35; + --lime-5: 168, 219, 57; + --lime-6: 184, 226, 75; + --lime-7: 203, 233, 112; + --lime-8: 222, 241, 152; + --lime-9: 238, 248, 194; + --lime-10: 253, 255, 238; + --green-1: 0, 77, 28; + --green-2: 4, 102, 37; + --green-3: 10, 128, 45; + --green-4: 18, 154, 55; + --green-5: 29, 180, 64; + --green-6: 39, 195, 70; + --green-7: 80, 210, 102; + --green-8: 126, 225, 139; + --green-9: 178, 240, 183; + --green-10: 235, 255, 236; + --cyan-1: 0, 66, 77; + --cyan-2: 6, 97, 108; + --cyan-3: 17, 131, 139; + --cyan-4: 31, 166, 170; + --cyan-5: 48, 201, 201; + --cyan-6: 63, 212, 207; + --cyan-7: 102, 223, 215; + --cyan-8: 144, 233, 225; + --cyan-9: 190, 244, 237; + --cyan-10: 240, 255, 252; + --blue-1: 0, 26, 77; + --blue-2: 5, 47, 120; + --blue-3: 19, 76, 163; + --blue-4: 41, 113, 207; + --blue-5: 70, 154, 250; + --blue-6: 90, 170, 251; + --blue-7: 125, 193, 252; + --blue-8: 161, 213, 253; + --blue-9: 198, 232, 254; + --blue-10: 234, 248, 255; + --arcoblue-1: 0, 13, 77; + --arcoblue-2: 4, 27, 121; + --arcoblue-3: 14, 50, 166; + --arcoblue-4: 29, 77, 210; + --arcoblue-5: 48, 111, 255; + --arcoblue-6: 60, 126, 255; + --arcoblue-7: 104, 159, 255; + --arcoblue-8: 147, 190, 255; + --arcoblue-9: 190, 218, 255; + --arcoblue-10: 234, 244, 255; + --purple-1: 22, 0, 77; + --purple-2: 39, 6, 110; + --purple-3: 62, 19, 143; + --purple-4: 90, 37, 176; + --purple-5: 123, 61, 209; + --purple-6: 142, 81, 218; + --purple-7: 169, 116, 227; + --purple-8: 197, 154, 237; + --purple-9: 223, 194, 246; + --purple-10: 247, 237, 255; + --pinkpurple-1: 66, 0, 77; + --pinkpurple-2: 101, 3, 112; + --pinkpurple-3: 138, 13, 147; + --pinkpurple-4: 176, 27, 182; + --pinkpurple-5: 217, 46, 217; + --pinkpurple-6: 225, 61, 219; + --pinkpurple-7: 232, 102, 223; + --pinkpurple-8: 240, 146, 230; + --pinkpurple-9: 247, 193, 240; + --pinkpurple-10: 255, 242, 253; + --magenta-1: 77, 0, 52; + --magenta-2: 119, 8, 80; + --magenta-3: 161, 23, 108; + --magenta-4: 203, 43, 136; + --magenta-5: 245, 69, 166; + --magenta-6: 247, 86, 169; + --magenta-7: 249, 122, 184; + --magenta-8: 251, 158, 200; + --magenta-9: 253, 195, 219; + --magenta-10: 255, 232, 241; + --gray-1: 23, 23, 26; + --gray-2: 46, 46, 48; + --gray-3: 72, 72, 73; + --gray-4: 95, 95, 96; + --gray-5: 120, 120, 122; + --gray-6: 146, 146, 147; + --gray-7: 171, 171, 172; + --gray-8: 197, 197, 197; + --gray-9: 223, 223, 223; + --gray-10: 246, 246, 246; + --color-white: rgba(255, 255, 255, 0.9); --color-black: #000000; --color-border: #333335; diff --git a/orion-ops-ui/src/store/modules/terminal/index.ts b/orion-ops-ui/src/store/modules/terminal/index.ts index 89e1a6cc..efd2de3c 100644 --- a/orion-ops-ui/src/store/modules/terminal/index.ts +++ b/orion-ops-ui/src/store/modules/terminal/index.ts @@ -64,8 +64,7 @@ export default defineStore('terminal', { } as TerminalShortcutSetting, }, hosts: {} as AuthorizedHostQueryResponse, - // fixme - tabManager: new TerminalTabManager(TerminalTabs.TERMINAL_PANEL), + tabManager: new TerminalTabManager(TerminalTabs.NEW_CONNECTION), panelManager: new TerminalPanelManager(), sessionManager: new TerminalSessionManager() }), diff --git a/orion-ops-ui/src/views/host/terminal/components/sftp/data.ts b/orion-ops-ui/src/views/host/terminal/components/sftp/data.ts new file mode 100644 index 00000000..abc77abc --- /dev/null +++ b/orion-ops-ui/src/views/host/terminal/components/sftp/data.ts @@ -0,0 +1,457 @@ +export default [{ + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1639399737000, + 'name': '04', + 'path': '/root/04', + 'permission': 644, + 'size': '34.2 MB', + 'sizeByte': 35845278, + 'suffix': '', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1662630786000, + 'name': 'j3', + 'path': '/root/j3', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1658895079000, + 'name': '123', + 'path': '/root/123', + 'permission': 644, + 'size': '13 B', + 'sizeByte': 13, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--rwx', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1664427351000, + 'name': 'bug.txt', + 'path': '/root/bug.txt', + 'permission': 647, + 'size': '50.3 KB', + 'sizeByte': 51491, + 'suffix': 'txt', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1659888021000, + 'name': 'ops-monitor-agent', + 'path': '/root/ops-monitor-agent', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1635143381000, + 'name': '04_体验一下面试官对于消息队列的7个连环炮.zip', + 'path': '/root/04_体验一下面试官对于消息队列的7个连环炮.zip', + 'permission': 644, + 'size': '34.2 MB', + 'sizeByte': 35845278, + 'suffix': 'zip', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1637921002000, + 'name': '一个超长的文件一个超长的文件一个超长的文件一个超长的文件一个超长的文件一个超长的文件', + 'path': '/root/一个超长的文件一个超长的文件一个超长的文件一个超长的文件一个超长的文件一个超长的文件', + 'permission': 644, + 'size': '4 B', + 'sizeByte': 4, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1662627298000, + 'name': 'WebStorm-2021.2.2.exe', + 'path': '/root/WebStorm-2021.2.2.exe', + 'permission': 644, + 'size': '366.2 MB', + 'sizeByte': 383998600, + 'suffix': 'exe', + 'uid': 0 +}, { + 'attr': 'drwxrwxr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1557936457000, + 'name': 'redis-5.0.5', + 'path': '/root/redis-5.0.5', + 'permission': 775, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '5', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1643003400000, + 'name': 'pic', + 'path': '/root/pic', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1635127278000, + 'name': 'pvzβv6.25-R4.7z', + 'path': '/root/pvzβv6.25-R4.7z', + 'permission': 644, + 'size': '37.2 MB', + 'sizeByte': 38978762, + 'suffix': '7z', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1652947847000, + 'name': '1.txt', + 'path': '/root/1.txt', + 'permission': 644, + 'size': '133 B', + 'sizeByte': 133, + 'suffix': 'txt', + 'uid': 0 +}, { + 'attr': 'drw-r--r--', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1653015555000, + 'name': 'write', + 'path': '/root/write', + 'permission': 644, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1660552691000, + 'name': 'k.pub', + 'path': '/root/k.pub', + 'permission': 644, + 'size': '401 B', + 'sizeByte': 401, + 'suffix': 'pub', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1625065314000, + 'name': 'ideaIU-2021.1.1.exe', + 'path': '/root/ideaIU-2021.1.1.exe', + 'permission': 644, + 'size': '729.3 MB', + 'sizeByte': 764705864, + 'suffix': 'exe', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1636525624000, + 'name': '文本.txt', + 'path': '/root/文本.txt', + 'permission': 644, + 'size': '0 B', + 'sizeByte': 0, + 'suffix': 'txt', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1635090233000, + 'name': '数据头.txt', + 'path': '/root/数据头.txt', + 'permission': 644, + 'size': '4.3 KB', + 'sizeByte': 4376, + 'suffix': 'txt', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1662627659000, + 'name': 'j1', + 'path': '/root/j1', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1642956894000, + 'name': 'PowerShell-7.1.4-win-x64.msi', + 'path': '/root/PowerShell-7.1.4-win-x64.msi', + 'permission': 644, + 'size': '94.9 MB', + 'sizeByte': 99524608, + 'suffix': 'msi', + 'uid': 0 +}, { + 'attr': '-rw-------', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1660552691000, + 'name': 'k', + 'path': '/root/k', + 'permission': 600, + 'size': '1.7 KB', + 'sizeByte': 1766, + 'suffix': '', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1652942938000, + 'name': 'bbb', + 'path': '/root/bbb', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1675653580000, + 'name': 'swapper', + 'path': '/root/swapper', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1639443147000, + 'name': 'tmp2.txt', + 'path': '/root/tmp2.txt', + 'permission': 644, + 'size': '184 B', + 'sizeByte': 184, + 'suffix': 'txt', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1653277297000, + 'name': 'test', + 'path': '/root/test', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1625064193000, + 'name': 'a1.rar', + 'path': '/root/a1.rar', + 'permission': 644, + 'size': '52 MB', + 'sizeByte': 54528512, + 'suffix': 'rar', + 'uid': 0 +}, { + 'attr': '-rwxrwxrwx', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1704289282000, + 'name': 'bridge.sh', + 'path': '/root/bridge.sh', + 'permission': 777, + 'size': '396 B', + 'sizeByte': 396, + 'suffix': 'sh', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1663829274000, + 'name': 'orion-ops', + 'path': '/root/orion-ops', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1668680082000, + 'name': 'ub.txt', + 'path': '/root/ub.txt', + 'permission': 644, + 'size': '71.7 MB', + 'sizeByte': 75167744, + 'suffix': 'txt', + 'uid': 0 +}, { + 'attr': '-rwxrwxrwx', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1668594989000, + 'name': 'osx.d', + 'path': '/root/osx.d', + 'permission': 777, + 'size': '170 B', + 'sizeByte': 170, + 'suffix': 'd', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1636337848000, + 'name': 'temp', + 'path': '/root/temp', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1659524667000, + 'name': '46746619-175F-41c0-8D0E-0007E9271507.png', + 'path': '/root/46746619-175F-41c0-8D0E-0007E9271507.png', + 'permission': 644, + 'size': '158.1 KB', + 'sizeByte': 161927, + 'suffix': 'png', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1646190836000, + 'name': 'video', + 'path': '/root/video', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1625136042000, + 'name': 'sql1.txt', + 'path': '/root/sql1.txt', + 'permission': 644, + 'size': '16.9 KB', + 'sizeByte': 17334, + 'suffix': 'txt', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1665545226000, + 'name': 'ts.txt', + 'path': '/root/ts.txt', + 'permission': 644, + 'size': '101.6 KB', + 'sizeByte': 104004, + 'suffix': 'txt', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1635090505000, + 'name': 'shop.xlsx', + 'path': '/root/shop.xlsx', + 'permission': 644, + 'size': '87.9 KB', + 'sizeByte': 89993, + 'suffix': 'xlsx', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1635127741000, + 'name': 'Java 8实战.pdf', + 'path': '/root/Java 8实战.pdf', + 'permission': 644, + 'size': '12.9 MB', + 'sizeByte': 13490536, + 'suffix': 'pdf', + 'uid': 0 +}, { + 'attr': '-rw-r--r--', + 'gid': 0, + 'isDir': false, + 'modifyTime': 1662626999000, + 'name': 'Postman-win64-6.5.3-Setup.exe', + 'path': '/root/Postman-win64-6.5.3-Setup.exe', + 'permission': 644, + 'size': '68.1 MB', + 'sizeByte': 71401080, + 'suffix': 'exe', + 'uid': 0 +}, { + 'attr': 'drwxr-xr-x', + 'gid': 0, + 'isDir': true, + 'modifyTime': 1662627183000, + 'name': 'jar', + 'path': '/root/jar', + 'permission': 755, + 'size': '4 KB', + 'sizeByte': 4096, + 'suffix': '', + 'uid': 0 +}]; diff --git a/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-table.vue b/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-table.vue new file mode 100644 index 00000000..8a59f778 --- /dev/null +++ b/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-table.vue @@ -0,0 +1,97 @@ + + + + + + + diff --git a/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-view.vue b/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-view.vue index e013f311..26892565 100644 --- a/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-view.vue +++ b/orion-ops-ui/src/views/host/terminal/components/sftp/sftp-view.vue @@ -1,8 +1,29 @@ @@ -13,14 +34,75 @@ diff --git a/orion-ops-ui/src/views/host/terminal/components/sftp/types/table.columns.ts b/orion-ops-ui/src/views/host/terminal/components/sftp/types/table.columns.ts new file mode 100644 index 00000000..22dee322 --- /dev/null +++ b/orion-ops-ui/src/views/host/terminal/components/sftp/types/table.columns.ts @@ -0,0 +1,49 @@ +import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'; +import { dateFormat } from '@/utils'; + +// 表格列 +const columns = [ + { + title: '名称', + dataIndex: 'name', + slotName: 'name', + fixed: 'left', + sortable: { + sortDirections: ['ascend', 'descend'], + }, + filterable: { + filter: (value, record) => record.name.includes(value), + slotName: 'nameFilter', + } + }, { + title: '大小', + dataIndex: 'sizeByte', + slotName: 'size', + sortable: { + sortDirections: ['ascend', 'descend'], + }, + }, { + title: '属性', + dataIndex: 'attr', + slotName: 'attr', + }, { + title: '修改时间', + dataIndex: 'modifyTime', + slotName: 'modifyTime', + align: 'center', + sortable: { + sortDirections: ['ascend', 'descend'], + }, + render: ({ record }) => { + return dateFormat(new Date(record.modifyTime)); + }, + }, { + title: '操作', + dataIndex: 'actions', + slotName: 'actions', + align: 'left', + fixed: 'right', + }, +] as TableColumnData[]; + +export default columns; diff --git a/orion-ops-ui/src/views/host/terminal/handler/sftp-session-resolver.ts b/orion-ops-ui/src/views/host/terminal/handler/sftp-session-resolver.ts new file mode 100644 index 00000000..a75e5c07 --- /dev/null +++ b/orion-ops-ui/src/views/host/terminal/handler/sftp-session-resolver.ts @@ -0,0 +1,29 @@ +import type { ISftpSession, ISftpSessionResolver, SftpDataRef, SftpFile } from '../types/terminal.type'; +import { Message } from '@arco-design/web-vue'; + +// sftp 会话接收器实现 +export default class SftpSessionResolver implements ISftpSessionResolver { + + private readonly dataRef: SftpDataRef; + + private readonly session: ISftpSession; + + constructor(session: ISftpSession, + dataRef: SftpDataRef) { + this.session = session; + this.dataRef = dataRef; + } + + // 接受文件列表响应 + resolveList(result: string, path: string, list: Array) { + const success = !!Number.parseInt(result); + this.dataRef.setLoading(false); + if (!success) { + Message.error('查询失败'); + return; + } + this.dataRef.currentPath = path; + this.dataRef.list = list; + } + +} diff --git a/orion-ops-ui/src/views/host/terminal/handler/sftp-session.ts b/orion-ops-ui/src/views/host/terminal/handler/sftp-session.ts index de3c2961..777b4ab4 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/sftp-session.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/sftp-session.ts @@ -1,5 +1,6 @@ -import type { ISftpSession, ITerminalChannel } from '../types/terminal.type'; +import type { ISftpSession, ISftpSessionResolver, ITerminalChannel, SftpDataRef } from '../types/terminal.type'; import { InputProtocol } from '../types/terminal.protocol'; +import SftpSessionResolver from './sftp-session-resolver'; // sftp 会话实现 export default class SftpSession implements ISftpSession { @@ -10,6 +11,10 @@ export default class SftpSession implements ISftpSession { public connected: boolean; + public resolver: ISftpSessionResolver; + + private dataRef: SftpDataRef; + private readonly channel: ITerminalChannel; constructor(hostId: number, @@ -19,13 +24,33 @@ export default class SftpSession implements ISftpSession { this.sessionId = sessionId; this.channel = channel; this.connected = false; + this.dataRef = undefined as unknown as SftpDataRef; + this.resolver = undefined as unknown as ISftpSessionResolver; + } + + // 初始化 + init(dataRef: SftpDataRef): void { + this.dataRef = dataRef; + // 处理器 + this.resolver = new SftpSessionResolver(this, dataRef); } // 设置已连接 connect(): void { this.connected = true; + // 加载 home 目录文件数据 + this.list(undefined); } + // 查询文件列表 + list(path: string | undefined) { + this.dataRef.setLoading(true); + this.channel.send(InputProtocol.SFTP_LIST, { + sessionId: this.sessionId, + path + }); + }; + // 断开连接 disconnect(): void { // 发送关闭消息 diff --git a/orion-ops-ui/src/views/host/terminal/handler/ssh-session.ts b/orion-ops-ui/src/views/host/terminal/handler/ssh-session.ts index e414598d..3de8329d 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/ssh-session.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/ssh-session.ts @@ -110,7 +110,7 @@ export default class SshSession implements ISshSession { return; } // 输入 - this.channel.send(InputProtocol.INPUT, { + this.channel.send(InputProtocol.SSH_INPUT, { sessionId: this.sessionId, command: s }); @@ -134,7 +134,7 @@ export default class SshSession implements ISshSession { if (!this.connected) { return; } - this.channel.send(InputProtocol.RESIZE, { + this.channel.send(InputProtocol.SSH_RESIZE, { sessionId: this.sessionId, cols, rows diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-output-processor.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-output-processor.ts index 679ff546..8324136b 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-output-processor.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-output-processor.ts @@ -1,4 +1,4 @@ -import { ISshSession, ITerminalChannel, ITerminalOutputProcessor, ITerminalSessionManager, OutputPayload } from '../types/terminal.type'; +import { ISftpSession, ISshSession, ITerminalChannel, ITerminalOutputProcessor, ITerminalSessionManager, OutputPayload } from '../types/terminal.type'; import { InputProtocol } from '../types/terminal.protocol'; import { TerminalStatus } from '../types/terminal.const'; import { useTerminalStore } from '@/store'; @@ -42,8 +42,9 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor // sftp 会话 if (success) { // 检查成功发送 connect 命令 - // TODO - + this.channel.send(InputProtocol.CONNECT, { + sessionId, + }); } else { // 未成功提示错误信息 Message.error(msg || '建立 SFTP 失败'); @@ -105,10 +106,17 @@ export default class TerminalOutputProcessor implements ITerminalOutputProcessor // console.log('pong'); } - // 处理输出消息 - processOutput({ sessionId, body }: OutputPayload): void { + // 处理 SSH 输出消息 + processSshOutput({ sessionId, body }: OutputPayload): void { const session = this.sessionManager.getSession(sessionId); session && session.write(body); } + // 处理 SFTP 文件列表 + processSftpList({ sessionId, result, path, body }: OutputPayload): void { + // 获取会话 + const session = this.sessionManager.getSession(sessionId); + session && session.resolver.resolveList(result, path, JSON.parse(body)); + } + } diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts index 187c97a3..20dc7011 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts @@ -1,4 +1,12 @@ -import type { ISftpSession, ITerminalChannel, ITerminalSession, ITerminalSessionManager, TerminalTabItem, XtermDomRef } from '../types/terminal.type'; +import type { + ISftpSession, + ITerminalChannel, + ITerminalSession, + ITerminalSessionManager, + SftpDataRef, + TerminalTabItem, + XtermDomRef +} from '../types/terminal.type'; import { sleep } from '@/utils'; import { InputProtocol } from '../types/terminal.protocol'; import { PanelSessionType } from '../types/terminal.const'; @@ -54,7 +62,7 @@ export default class TerminalSessionManager implements ITerminalSessionManager { } // 打开 sftp 会话 - async openSftp(tab: TerminalTabItem): Promise { + async openSftp(tab: TerminalTabItem, dataRef: SftpDataRef): Promise { const sessionId = tab.key; const hostId = tab.hostId as number; // 初始化客户端 @@ -65,6 +73,8 @@ export default class TerminalSessionManager implements ITerminalSessionManager { sessionId, this.channel ); + // 初始化 + session.init(dataRef); // 添加会话 this.sessions[sessionId] = session; // 发送会话初始化请求 diff --git a/orion-ops-ui/src/views/host/terminal/types/terminal.const.ts b/orion-ops-ui/src/views/host/terminal/types/terminal.const.ts index e745e76e..78dc4fad 100644 --- a/orion-ops-ui/src/views/host/terminal/types/terminal.const.ts +++ b/orion-ops-ui/src/views/host/terminal/types/terminal.const.ts @@ -55,11 +55,11 @@ export const ExtraSshAuthType = { // 面板会话 tab 类型 export const PanelSessionType = { SSH: { - type: 'ssh', + type: 'SSH', icon: 'icon-desktop' }, SFTP: { - type: 'sftp', + type: 'SFTP', icon: 'icon-folder' }, }; diff --git a/orion-ops-ui/src/views/host/terminal/types/terminal.protocol.ts b/orion-ops-ui/src/views/host/terminal/types/terminal.protocol.ts index 22c7771b..69d561ba 100644 --- a/orion-ops-ui/src/views/host/terminal/types/terminal.protocol.ts +++ b/orion-ops-ui/src/views/host/terminal/types/terminal.protocol.ts @@ -20,16 +20,21 @@ export const InputProtocol = { type: 'p', template: ['type'] }, - // 修改大小 - RESIZE: { + // SSH 修改大小 + SSH_RESIZE: { type: 'rs', template: ['type', 'sessionId', 'cols', 'rows'] }, - // 输入 - INPUT: { + // SSH 输入 + SSH_INPUT: { type: 'i', template: ['type', 'sessionId', 'command'] - } + }, + // SFTP 文件列表 + SFTP_LIST: { + type: 'ls', + template: ['type', 'sessionId', 'path'] + }, }; // 输出协议 @@ -58,10 +63,16 @@ export const OutputProtocol = { template: ['type'], processMethod: 'processPong' }, - // 输出 - OUTPUT: { + // SSH 输出 + SSH_OUTPUT: { type: 'o', template: ['type', 'sessionId', 'body'], - processMethod: 'processOutput' + processMethod: 'processSshOutput' + }, + // SFTP 文件列表 + SFTP_LIST: { + type: 'ls', + template: ['type', 'sessionId', 'result', 'path', 'body'], + processMethod: 'processSftpList' }, }; diff --git a/orion-ops-ui/src/views/host/terminal/types/terminal.type.ts b/orion-ops-ui/src/views/host/terminal/types/terminal.type.ts index 7c234fec..58c66f6c 100644 --- a/orion-ops-ui/src/views/host/terminal/types/terminal.type.ts +++ b/orion-ops-ui/src/views/host/terminal/types/terminal.type.ts @@ -145,7 +145,7 @@ export interface ITerminalSessionManager { // 打开 ssh 会话 openSsh: (tab: TerminalTabItem, domRef: XtermDomRef) => Promise; // 打开 sftp 会话 - openSftp: (tab: TerminalTabItem) => Promise; + openSftp: (tab: TerminalTabItem, dataRef: SftpDataRef) => Promise; // 获取终端会话 getSession: (sessionId: string) => T; // 关闭终端会话 @@ -176,18 +176,20 @@ export interface ITerminalOutputProcessor { processClose: (payload: OutputPayload) => void; // 处理 pong 消息 processPong: (payload: OutputPayload) => void; - // 处理输出消息 - processOutput: (payload: OutputPayload) => void; + // 处理 SSH 输出消息 + processSshOutput: (payload: OutputPayload) => void; + // 处理 SFTP 文件列表 + processSftpList: (payload: OutputPayload) => void; } -// 终端 dom 元素引用 +// xterm dom 元素引用 export interface XtermDomRef { el: HTMLElement; searchModal: any; editorModal: any; } -// 终端插件 +// xterm 插件 export interface XtermAddons { fit: FitAddon; webgl: WebglAddon; @@ -197,6 +199,16 @@ export interface XtermAddons { image: ImageAddon; } +// sftp 数据引用 +export interface SftpDataRef { + // 文件列表 + list: any; + // 当前路径 + currentPath: any; + // 设置加载状态 + setLoading: (loading: boolean) => void; +} + // 终端会话定义 export interface ITerminalSession { hostId: number; @@ -288,5 +300,32 @@ export interface ISshSessionHandler { // sftp 会话定义 export interface ISftpSession extends ITerminalSession { + // 接收器 + resolver: ISftpSessionResolver; + // 初始化 + init: (dataRef: SftpDataRef) => void; + // 查询文件列表 + list: (path: string | undefined) => void; +} + +// sftp 会话接收器定义 +export interface ISftpSessionResolver { + // 接受文件列表响应 + resolveList: (result: string, path: string, list: Array) => void; +} + +// sftp 文件 +export interface SftpFile { + name: string; + path: string; + suffix: string; + size: string; + sizeByte: number; + attr: string; + isDir: boolean; + permission: number; + uid: number; + gid: number; + modifyTime: number; }