Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7015468e04 | ||
|
|
ef57040e1d | ||
|
|
2a6537c604 | ||
|
|
541a9790ad | ||
|
|
011e8ad089 | ||
|
|
3918d36c24 | ||
|
|
37f452c7c3 | ||
|
|
fc885bc0ad | ||
|
|
44c226092d | ||
|
|
14cf8c2492 | ||
|
|
d6f5898e61 | ||
|
|
0ab8e405cc | ||
|
|
4e4231d5a5 | ||
|
|
2df3f2fa1a | ||
|
|
d6048f78f0 |
16
README.md
16
README.md
@@ -1,5 +1,5 @@
|
|||||||
<div align="center"><img src="https://bjuimg.obs.cn-north-4.myhuaweicloud.com/images/2024/5/29/cec03bbd-0eab-464d-9caf-d0b5a7ffc5a6.png" alt="logo" width="32" /></div>
|
<div align="center"><img src="https://bjuimg.obs.cn-north-4.myhuaweicloud.com/images/2024/9/11/11e7e78e-2af0-4c68-9811-db8a4c4400f4.png" alt="logo" width="520" /></div>
|
||||||
<p style="margin-top: 12px" align="center"><b>一款高颜值、现代化的智能运维&轻量堡垒机平台。</b></p>
|
<p style="margin-top: 12px" align="center"><b>一款高颜值、现代化的自动化运维&轻量堡垒机平台。</b></p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
style="text-decoration: none !important;"
|
style="text-decoration: none !important;"
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
**`orion-visor`** 提供一站式服务器运维解决方案。
|
**`orion-visor`** 提供一站式自动化运维解决方案。
|
||||||
|
|
||||||
* **资产管理**:支持对资产进行分组,实现对主机、密钥和身份的统一管理和授权。
|
* **资产管理**:支持对资产进行分组,实现对主机、密钥和身份的统一管理和授权。
|
||||||
* **在线终端**:提供在线终端 SSH 服务,支持快捷命令、自定义快捷键和主题风格。
|
* **在线终端**:提供在线终端 SSH 服务,支持快捷命令、自定义快捷键和主题风格。
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
## 演示环境
|
## 演示环境
|
||||||
|
|
||||||
* 🔗 演示地址: https://dv.orionsec.cn/
|
* 🔗 演示地址: [https://dv.orionsec.cn/](https://dv.orionsec.cn/)
|
||||||
* 🔏 演示账号: admin/admin
|
* 🔏 演示账号: admin/admin
|
||||||
* ⭐ 体验后可以点一下 `star` 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) [gitcode](https://gitcode.com/dromara/orion-visor/overview)
|
* ⭐ 体验后可以点一下 `star` 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) [gitcode](https://gitcode.com/dromara/orion-visor/overview)
|
||||||
* 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
|
* 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
|
||||||
@@ -111,14 +111,18 @@ docker compose up -d
|
|||||||
|
|
||||||
[](https://star-history.com/#lijiahangmax/orion-visor&Date)
|
[](https://star-history.com/#lijiahangmax/orion-visor&Date)
|
||||||
|
|
||||||
|
## 关于我
|
||||||
|
|
||||||
|
本人专注于使用 Java 和 Vue 进行全栈开发, 并在系统自动化运维方面拥有丰富开发的经验。如果您在这些领域有需求或遇到痛点, 请随时联系我, 并备注“合作”。
|
||||||
|
|
||||||
## 联系我
|
## 联系我
|
||||||
|
|
||||||
<div style="display: flex;">
|
<div style="display: flex;">
|
||||||
<img src="https://bjuimg.obs.cn-north-4.myhuaweicloud.com/images/2024/5/17/d42d91f3-f0ee-4c63-adab-a35809e0804c.jpg" alt="wx" width="298px" height="398px"/>
|
<img src="https://bjuimg.obs.cn-north-4.myhuaweicloud.com/images/2024/5/17/d42d91f3-f0ee-4c63-adab-a35809e0804c.jpg" alt="wx" width="298px" height="398px"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||

|
微信: ljh1553488
|
||||||

|
QQ群: 755242157
|
||||||
|
|
||||||
📧 咨询问题微信备注: vis
|
📧 咨询问题微信备注: vis
|
||||||
📧 合作/功能定制备注: 合作
|
📧 合作/功能定制备注: 合作
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
service:
|
service:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.5
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.7
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 1081:80
|
- 1081:80
|
||||||
@@ -32,7 +32,7 @@ services:
|
|||||||
- mysql
|
- mysql
|
||||||
- redis
|
- redis
|
||||||
mysql:
|
mysql:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.5
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.7
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 3307:3306
|
- 3307:3306
|
||||||
@@ -52,7 +52,7 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
start_period: 3s
|
start_period: 3s
|
||||||
redis:
|
redis:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.5
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.7
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 6380:6379
|
- 6380:6379
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
version: '3.3'
|
version: '3.3'
|
||||||
services:
|
services:
|
||||||
service:
|
service:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.5
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.7
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- ${SERVICE_PORT:-1081}:80
|
- ${SERVICE_PORT:-1081}:80
|
||||||
@@ -32,7 +32,7 @@ services:
|
|||||||
- mysql
|
- mysql
|
||||||
- redis
|
- redis
|
||||||
mysql:
|
mysql:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.5
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.7
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 3307:3306
|
- 3307:3306
|
||||||
@@ -52,7 +52,7 @@ services:
|
|||||||
retries: 15
|
retries: 15
|
||||||
start_period: 3s
|
start_period: 3s
|
||||||
redis:
|
redis:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.5
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.7
|
||||||
privileged: true
|
privileged: true
|
||||||
ports:
|
ports:
|
||||||
- 6380:6379
|
- 6380:6379
|
||||||
@@ -68,7 +68,7 @@ services:
|
|||||||
retries: 15
|
retries: 15
|
||||||
start_period: 3s
|
start_period: 3s
|
||||||
adminer:
|
adminer:
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-adminer:2.1.5
|
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-adminer:2.1.7
|
||||||
ports:
|
ports:
|
||||||
- 8081:8080
|
- 8081:8080
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
version=2.1.5
|
version=2.1.7
|
||||||
docker build -t orion-visor-adminer:${version} .
|
docker build -t orion-visor-adminer:${version} .
|
||||||
docker tag orion-visor-adminer:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-adminer:${version}
|
docker tag orion-visor-adminer:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-adminer:${version}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
version=2.1.5
|
version=2.1.7
|
||||||
cp -r ../../sql ./sql
|
cp -r ../../sql ./sql
|
||||||
docker build -t orion-visor-mysql:${version} .
|
docker build -t orion-visor-mysql:${version} .
|
||||||
rm -rf ./sql
|
rm -rf ./sql
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
version=2.1.5
|
version=2.1.7
|
||||||
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-adminer:${version}
|
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-adminer:${version}
|
||||||
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:${version}
|
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:${version}
|
||||||
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
version=2.1.5
|
version=2.1.7
|
||||||
docker build -t orion-visor-redis:${version} .
|
docker build -t orion-visor-redis:${version} .
|
||||||
docker tag orion-visor-redis:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
docker tag orion-visor-redis:${version} registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#/bin/bash
|
#/bin/bash
|
||||||
version=2.1.5
|
version=2.1.7
|
||||||
mv ../../orion-visor-launch/target/orion-visor-launch.jar ./orion-visor-launch.jar
|
mv ../../orion-visor-launch/target/orion-visor-launch.jar ./orion-visor-launch.jar
|
||||||
mv ../../orion-visor-ui/dist ./dist
|
mv ../../orion-visor-ui/dist ./dist
|
||||||
docker build -t orion-visor-service:${version} .
|
docker build -t orion-visor-service:${version} .
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<url>https://github.com/dromara/orion-visor</url>
|
<url>https://github.com/dromara/orion-visor</url>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>2.1.5</revision>
|
<revision>2.1.7</revision>
|
||||||
<spring.boot.version>2.7.17</spring.boot.version>
|
<spring.boot.version>2.7.17</spring.boot.version>
|
||||||
<spring.boot.admin.version>2.7.15</spring.boot.admin.version>
|
<spring.boot.admin.version>2.7.15</spring.boot.admin.version>
|
||||||
<flatten.maven.plugin.version>1.5.0</flatten.maven.plugin.version>
|
<flatten.maven.plugin.version>1.5.0</flatten.maven.plugin.version>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public interface AppConst extends OrionConst {
|
|||||||
/**
|
/**
|
||||||
* 同 ${orion.version} 迭代时候需要手动更改
|
* 同 ${orion.version} 迭代时候需要手动更改
|
||||||
*/
|
*/
|
||||||
String VERSION = "2.1.5";
|
String VERSION = "2.1.7";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同 ${spring.application.name}
|
* 同 ${spring.application.name}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ public interface ExtraFieldConst extends FieldConst {
|
|||||||
|
|
||||||
String USERNAME = "username";
|
String USERNAME = "username";
|
||||||
|
|
||||||
|
String HOME = "home";
|
||||||
|
|
||||||
String STATUS_NAME = "statusName";
|
String STATUS_NAME = "statusName";
|
||||||
|
|
||||||
String KEY_NAME = "keyName";
|
String KEY_NAME = "keyName";
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
package com.orion.visor.framework.common.utils;
|
|
||||||
|
|
||||||
import com.orion.lang.utils.Arrays1;
|
|
||||||
import com.orion.lang.utils.crypto.Caesars;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 混淆工具类
|
|
||||||
*
|
|
||||||
* @author Jiahang Li
|
|
||||||
* @version 1.0.0
|
|
||||||
* @since 2024/6/17 18:27
|
|
||||||
*/
|
|
||||||
public class Mixes {
|
|
||||||
|
|
||||||
private Mixes() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 混淆
|
|
||||||
* <p>
|
|
||||||
* 此方法不可修改
|
|
||||||
*
|
|
||||||
* @param str str
|
|
||||||
* @return str
|
|
||||||
*/
|
|
||||||
public static String obfuscate(String str) {
|
|
||||||
char[] chars = str.toCharArray();
|
|
||||||
Arrays1.reverse(chars);
|
|
||||||
for (int i = 0; i < chars.length; i += 2) {
|
|
||||||
char temp = chars[i];
|
|
||||||
chars[i] = chars[i + 1];
|
|
||||||
chars[i + 1] = temp;
|
|
||||||
}
|
|
||||||
String res = new String(chars);
|
|
||||||
return new Caesars().encrypt(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.orion.visor.framework.common.utils;
|
package com.orion.visor.framework.common.utils;
|
||||||
|
|
||||||
import com.orion.lang.utils.Objects1;
|
import com.orion.lang.utils.Objects1;
|
||||||
|
import com.orion.lang.utils.Systems;
|
||||||
|
import com.orion.lang.utils.io.Files1;
|
||||||
import com.orion.visor.framework.common.constant.AppConst;
|
import com.orion.visor.framework.common.constant.AppConst;
|
||||||
import com.orion.visor.framework.common.constant.Const;
|
import com.orion.visor.framework.common.constant.Const;
|
||||||
|
|
||||||
@@ -24,9 +26,25 @@ public class PathUtils {
|
|||||||
* @return 用户目录
|
* @return 用户目录
|
||||||
*/
|
*/
|
||||||
public static String getHomePath(boolean isWindows, String username) {
|
public static String getHomePath(boolean isWindows, String username) {
|
||||||
|
return getHomePath(isWindows, username, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户根目录
|
||||||
|
*
|
||||||
|
* @param isWindows isWindows
|
||||||
|
* @param username 用户名
|
||||||
|
* @param prependSeparator 是否在头部添加分隔符
|
||||||
|
* @return 用户目录
|
||||||
|
*/
|
||||||
|
public static String getHomePath(boolean isWindows, String username, boolean prependSeparator) {
|
||||||
if (isWindows) {
|
if (isWindows) {
|
||||||
// windows
|
// windows
|
||||||
|
if (prependSeparator) {
|
||||||
|
return "/C:/Users/" + username;
|
||||||
|
} else {
|
||||||
return "C:/Users/" + username;
|
return "C:/Users/" + username;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// linux
|
// linux
|
||||||
if (Const.ROOT.equals(username)) {
|
if (Const.ROOT.equals(username)) {
|
||||||
@@ -66,4 +84,34 @@ public class PathUtils {
|
|||||||
return path.toString();
|
return path.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 头部添加分隔符
|
||||||
|
*
|
||||||
|
* @param path path
|
||||||
|
* @return path
|
||||||
|
*/
|
||||||
|
public static String prependSeparator(String path) {
|
||||||
|
if (path.startsWith("/")) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
return "/" + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 orion path
|
||||||
|
*
|
||||||
|
* @param path path
|
||||||
|
* @return path
|
||||||
|
*/
|
||||||
|
public static String getOrionPath(String path) {
|
||||||
|
path = Systems.HOME_DIR
|
||||||
|
+ Files1.SEPARATOR
|
||||||
|
+ AppConst.ORION
|
||||||
|
+ Files1.SEPARATOR
|
||||||
|
+ AppConst.APP_NAME
|
||||||
|
+ Files1.SEPARATOR
|
||||||
|
+ path;
|
||||||
|
return Files1.getPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,4 +40,6 @@ public interface HostConvert {
|
|||||||
|
|
||||||
List<HostVO> toList(List<HostDO> domain);
|
List<HostVO> toList(List<HostDO> domain);
|
||||||
|
|
||||||
|
List<HostBaseVO> toBaseList(List<HostDO> domain);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,10 @@ public class UploadTaskFileDO extends BaseDO {
|
|||||||
@TableField("file_path")
|
@TableField("file_path")
|
||||||
private String filePath;
|
private String filePath;
|
||||||
|
|
||||||
|
@Schema(description = "实际文件路径")
|
||||||
|
@TableField("real_file_path")
|
||||||
|
private String realFilePath;
|
||||||
|
|
||||||
@Schema(description = "文件大小")
|
@Schema(description = "文件大小")
|
||||||
@TableField("file_size")
|
@TableField("file_size")
|
||||||
private Long fileSize;
|
private Long fileSize;
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ public class UploadTaskFileVO implements Serializable {
|
|||||||
@Schema(description = "文件路径")
|
@Schema(description = "文件路径")
|
||||||
private String filePath;
|
private String filePath;
|
||||||
|
|
||||||
|
@Schema(description = "实际文件路径")
|
||||||
|
private String realFilePath;
|
||||||
|
|
||||||
@Schema(description = "文件大小")
|
@Schema(description = "文件大小")
|
||||||
private Long fileSize;
|
private Long fileSize;
|
||||||
|
|
||||||
|
|||||||
@@ -40,4 +40,24 @@ public enum HostSshOsTypeEnum {
|
|||||||
return LINUX;
|
return LINUX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为 linux 系统
|
||||||
|
*
|
||||||
|
* @param type type
|
||||||
|
* @return isLinux
|
||||||
|
*/
|
||||||
|
public static boolean isLinux(String type) {
|
||||||
|
return LINUX.name().equals(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否为 windows 系统
|
||||||
|
*
|
||||||
|
* @param type type
|
||||||
|
* @return isWindows
|
||||||
|
*/
|
||||||
|
public static boolean isWindows(String type) {
|
||||||
|
return WINDOWS.name().equals(type);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import com.orion.net.host.ssh.command.CommandExecutor;
|
|||||||
import com.orion.spring.SpringHolder;
|
import com.orion.spring.SpringHolder;
|
||||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||||
import com.orion.visor.framework.common.file.FileClient;
|
import com.orion.visor.framework.common.file.FileClient;
|
||||||
|
import com.orion.visor.framework.common.utils.PathUtils;
|
||||||
import com.orion.visor.module.asset.dao.ExecHostLogDAO;
|
import com.orion.visor.module.asset.dao.ExecHostLogDAO;
|
||||||
import com.orion.visor.module.asset.entity.domain.ExecHostLogDO;
|
import com.orion.visor.module.asset.entity.domain.ExecHostLogDO;
|
||||||
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||||
@@ -159,11 +160,8 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler {
|
|||||||
// 打开 sftp
|
// 打开 sftp
|
||||||
sftpExecutor = sessionStore.getSftpExecutor(execHostCommand.getFileNameCharset());
|
sftpExecutor = sessionStore.getSftpExecutor(execHostCommand.getFileNameCharset());
|
||||||
sftpExecutor.connect();
|
sftpExecutor.connect();
|
||||||
// 必须要以 / 开头
|
// 文件上传必须要以 / 开头
|
||||||
String scriptPath = execHostCommand.getScriptPath();
|
String scriptPath = PathUtils.prependSeparator(execHostCommand.getScriptPath());
|
||||||
if (!scriptPath.startsWith("/")) {
|
|
||||||
scriptPath = "/" + scriptPath;
|
|
||||||
}
|
|
||||||
// 创建文件
|
// 创建文件
|
||||||
sftpExecutor.touch(scriptPath);
|
sftpExecutor.touch(scriptPath);
|
||||||
// 写入命令
|
// 写入命令
|
||||||
@@ -225,6 +223,7 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler {
|
|||||||
Long id = execHostCommand.getHostLogId();
|
Long id = execHostCommand.getHostLogId();
|
||||||
String statusName = status.name();
|
String statusName = status.name();
|
||||||
log.info("BaseExecCommandHandler.updateStatus start id: {}, status: {}", id, statusName);
|
log.info("BaseExecCommandHandler.updateStatus start id: {}, status: {}", id, statusName);
|
||||||
|
try {
|
||||||
updateRecord.setId(id);
|
updateRecord.setId(id);
|
||||||
updateRecord.setStatus(statusName);
|
updateRecord.setStatus(statusName);
|
||||||
if (ExecHostStatusEnum.RUNNING.equals(status)) {
|
if (ExecHostStatusEnum.RUNNING.equals(status)) {
|
||||||
@@ -248,6 +247,9 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler {
|
|||||||
}
|
}
|
||||||
int effect = execHostLogDAO.updateById(updateRecord);
|
int effect = execHostLogDAO.updateById(updateRecord);
|
||||||
log.info("BaseExecCommandHandler.updateStatus finish id: {}, effect: {}", id, effect);
|
log.info("BaseExecCommandHandler.updateStatus finish id: {}, effect: {}", id, effect);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("BaseExecCommandHandler.updateStatus error id: {}", id, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ public class ExecTaskHandler implements IExecTaskHandler {
|
|||||||
*/
|
*/
|
||||||
private void updateStatus(ExecStatusEnum status) {
|
private void updateStatus(ExecStatusEnum status) {
|
||||||
Long id = execCommand.getLogId();
|
Long id = execCommand.getLogId();
|
||||||
|
try {
|
||||||
String statusName = status.name();
|
String statusName = status.name();
|
||||||
log.info("ExecTaskHandler-updateStatus start id: {}, status: {}", id, statusName);
|
log.info("ExecTaskHandler-updateStatus start id: {}, status: {}", id, statusName);
|
||||||
ExecLogDO update = new ExecLogDO();
|
ExecLogDO update = new ExecLogDO();
|
||||||
@@ -172,6 +173,9 @@ public class ExecTaskHandler implements IExecTaskHandler {
|
|||||||
}
|
}
|
||||||
int effect = execLogDAO.updateById(update);
|
int effect = execLogDAO.updateById(update);
|
||||||
log.info("ExecTaskHandler-updateStatus finish id: {}, effect: {}", id, effect);
|
log.info("ExecTaskHandler-updateStatus finish id: {}, effect: {}", id, effect);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("ExecTaskHandler-updateStatus error id: {}", id, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package com.orion.visor.module.asset.handler.host.upload.task;
|
package com.orion.visor.module.asset.handler.host.upload.task;
|
||||||
|
|
||||||
import com.orion.lang.utils.Threads;
|
import com.orion.lang.utils.Threads;
|
||||||
import com.orion.lang.utils.io.Files1;
|
|
||||||
import com.orion.lang.utils.io.Streams;
|
import com.orion.lang.utils.io.Streams;
|
||||||
import com.orion.lang.utils.time.Dates;
|
import com.orion.lang.utils.time.Dates;
|
||||||
import com.orion.spring.SpringHolder;
|
import com.orion.spring.SpringHolder;
|
||||||
import com.orion.visor.framework.common.constant.Const;
|
|
||||||
import com.orion.visor.framework.common.constant.ExtraFieldConst;
|
import com.orion.visor.framework.common.constant.ExtraFieldConst;
|
||||||
import com.orion.visor.module.asset.dao.UploadTaskDAO;
|
import com.orion.visor.module.asset.dao.UploadTaskDAO;
|
||||||
import com.orion.visor.module.asset.dao.UploadTaskFileDAO;
|
import com.orion.visor.module.asset.dao.UploadTaskFileDAO;
|
||||||
@@ -143,7 +141,7 @@ public class FileUploadTask implements IFileUploadTask {
|
|||||||
.map(s -> FileUploadFileItemDTO.builder()
|
.map(s -> FileUploadFileItemDTO.builder()
|
||||||
.id(s.getId())
|
.id(s.getId())
|
||||||
.fileId(s.getFileId())
|
.fileId(s.getFileId())
|
||||||
.remotePath(Files1.getPath(Const.SLASH + record.getRemotePath() + Const.SLASH + s.getFilePath()))
|
.remotePath(s.getRealFilePath())
|
||||||
.status(UploadTaskFileStatusEnum.WAITING.name())
|
.status(UploadTaskFileStatusEnum.WAITING.name())
|
||||||
.current(0L)
|
.current(0L)
|
||||||
.build())
|
.build())
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package com.orion.visor.module.asset.handler.host.upload.uploader;
|
package com.orion.visor.module.asset.handler.host.upload.uploader;
|
||||||
|
|
||||||
import com.orion.lang.utils.Strings;
|
|
||||||
import com.orion.lang.utils.collect.Maps;
|
|
||||||
import com.orion.lang.utils.io.Files1;
|
|
||||||
import com.orion.lang.utils.io.Streams;
|
import com.orion.lang.utils.io.Streams;
|
||||||
import com.orion.net.host.SessionStore;
|
import com.orion.net.host.SessionStore;
|
||||||
import com.orion.net.host.sftp.SftpExecutor;
|
import com.orion.net.host.sftp.SftpExecutor;
|
||||||
@@ -10,12 +7,10 @@ import com.orion.spring.SpringHolder;
|
|||||||
import com.orion.visor.framework.common.constant.Const;
|
import com.orion.visor.framework.common.constant.Const;
|
||||||
import com.orion.visor.framework.common.enums.EndpointDefine;
|
import com.orion.visor.framework.common.enums.EndpointDefine;
|
||||||
import com.orion.visor.framework.common.file.FileClient;
|
import com.orion.visor.framework.common.file.FileClient;
|
||||||
import com.orion.visor.framework.common.utils.PathUtils;
|
|
||||||
import com.orion.visor.module.asset.dao.UploadTaskFileDAO;
|
import com.orion.visor.module.asset.dao.UploadTaskFileDAO;
|
||||||
import com.orion.visor.module.asset.define.config.AppSftpConfig;
|
import com.orion.visor.module.asset.define.config.AppSftpConfig;
|
||||||
import com.orion.visor.module.asset.entity.domain.UploadTaskFileDO;
|
import com.orion.visor.module.asset.entity.domain.UploadTaskFileDO;
|
||||||
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
|
||||||
import com.orion.visor.module.asset.enums.HostSshOsTypeEnum;
|
|
||||||
import com.orion.visor.module.asset.enums.UploadTaskFileStatusEnum;
|
import com.orion.visor.module.asset.enums.UploadTaskFileStatusEnum;
|
||||||
import com.orion.visor.module.asset.handler.host.jsch.SessionStores;
|
import com.orion.visor.module.asset.handler.host.jsch.SessionStores;
|
||||||
import com.orion.visor.module.asset.handler.host.upload.model.FileUploadFileItemDTO;
|
import com.orion.visor.module.asset.handler.host.upload.model.FileUploadFileItemDTO;
|
||||||
@@ -28,7 +23,6 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,10 +100,8 @@ public class FileUploader implements IFileUploader {
|
|||||||
private boolean initSession() {
|
private boolean initSession() {
|
||||||
log.info("HostFileUploader.initSession start taskId: {}, hostId: {}", taskId, hostId);
|
log.info("HostFileUploader.initSession start taskId: {}, hostId: {}", taskId, hostId);
|
||||||
try {
|
try {
|
||||||
// 替换用户路径
|
|
||||||
HostTerminalConnectDTO connectInfo = hostTerminalService.getTerminalConnectInfo(hostId);
|
|
||||||
this.replaceRemotePathVariable(connectInfo.getOsType(), connectInfo.getUsername());
|
|
||||||
// 打开会话
|
// 打开会话
|
||||||
|
HostTerminalConnectDTO connectInfo = hostTerminalService.getTerminalConnectInfo(hostId);
|
||||||
this.sessionStore = SessionStores.openSessionStore(connectInfo);
|
this.sessionStore = SessionStores.openSessionStore(connectInfo);
|
||||||
this.executor = sessionStore.getSftpExecutor(connectInfo.getFileNameCharset());
|
this.executor = sessionStore.getSftpExecutor(connectInfo.getFileNameCharset());
|
||||||
executor.connect();
|
executor.connect();
|
||||||
@@ -222,27 +214,6 @@ public class FileUploader implements IFileUploader {
|
|||||||
uploadTaskFileDAO.updateById(update);
|
uploadTaskFileDAO.updateById(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 替换文件路径变量
|
|
||||||
*
|
|
||||||
* @param osType osType
|
|
||||||
* @param username username
|
|
||||||
*/
|
|
||||||
private void replaceRemotePathVariable(String osType, String username) {
|
|
||||||
// 包含变量
|
|
||||||
if (!files.get(0).getRemotePath().contains(Const.DOLLAR)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String home = PathUtils.getHomePath(HostSshOsTypeEnum.WINDOWS.name().equals(osType), username);
|
|
||||||
// 替换变量
|
|
||||||
Map<String, String> env = Maps.newMap(4);
|
|
||||||
env.put("username", username);
|
|
||||||
env.put("home", home);
|
|
||||||
for (FileUploadFileItemDTO file : files) {
|
|
||||||
file.setRemotePath(Files1.getPath(Strings.format(file.getRemotePath(), env)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
log.info("HostFileUploader.cancel taskId: {}, hostId: {}, canceled: {}, closed: {}", taskId, hostId, canceled, closed);
|
log.info("HostFileUploader.cancel taskId: {}, hostId: {}, canceled: {}, closed: {}", taskId, hostId, canceled, closed);
|
||||||
|
|||||||
@@ -259,9 +259,10 @@ public class HostServiceImpl implements HostService {
|
|||||||
if (wrapper == null) {
|
if (wrapper == null) {
|
||||||
return DataGrid.of(Lists.empty());
|
return DataGrid.of(Lists.empty());
|
||||||
}
|
}
|
||||||
|
// 数量条件
|
||||||
|
LambdaQueryWrapper<HostDO> countWrapper = wrapper.clone();
|
||||||
// 基础条件
|
// 基础条件
|
||||||
LambdaQueryWrapper<HostDO> countWrapper = wrapper.clone()
|
wrapper.select(HostDAO.BASE_COLUMN)
|
||||||
.select(HostDAO.BASE_COLUMN)
|
|
||||||
.orderByAsc(HostDO::getId);
|
.orderByAsc(HostDO::getId);
|
||||||
// 查询
|
// 查询
|
||||||
DataGrid<HostVO> hosts = hostDAO.of(wrapper)
|
DataGrid<HostVO> hosts = hostDAO.of(wrapper)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.orion.visor.module.asset.service.impl;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.orion.lang.annotation.Keep;
|
import com.orion.lang.annotation.Keep;
|
||||||
|
import com.orion.lang.define.collect.MultiHashMap;
|
||||||
import com.orion.lang.define.wrapper.DataGrid;
|
import com.orion.lang.define.wrapper.DataGrid;
|
||||||
import com.orion.lang.utils.Arrays1;
|
import com.orion.lang.utils.Arrays1;
|
||||||
import com.orion.lang.utils.Booleans;
|
import com.orion.lang.utils.Booleans;
|
||||||
@@ -15,9 +16,11 @@ import com.orion.lang.utils.time.Dates;
|
|||||||
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
import com.orion.visor.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||||
import com.orion.visor.framework.common.constant.Const;
|
import com.orion.visor.framework.common.constant.Const;
|
||||||
import com.orion.visor.framework.common.constant.ErrorMessage;
|
import com.orion.visor.framework.common.constant.ErrorMessage;
|
||||||
|
import com.orion.visor.framework.common.constant.ExtraFieldConst;
|
||||||
import com.orion.visor.framework.common.enums.EndpointDefine;
|
import com.orion.visor.framework.common.enums.EndpointDefine;
|
||||||
import com.orion.visor.framework.common.file.FileClient;
|
import com.orion.visor.framework.common.file.FileClient;
|
||||||
import com.orion.visor.framework.common.security.LoginUser;
|
import com.orion.visor.framework.common.security.LoginUser;
|
||||||
|
import com.orion.visor.framework.common.utils.PathUtils;
|
||||||
import com.orion.visor.framework.common.utils.SqlUtils;
|
import com.orion.visor.framework.common.utils.SqlUtils;
|
||||||
import com.orion.visor.framework.common.utils.Valid;
|
import com.orion.visor.framework.common.utils.Valid;
|
||||||
import com.orion.visor.framework.mybatis.core.query.Conditions;
|
import com.orion.visor.framework.mybatis.core.query.Conditions;
|
||||||
@@ -28,20 +31,21 @@ import com.orion.visor.module.asset.convert.UploadTaskFileConvert;
|
|||||||
import com.orion.visor.module.asset.dao.HostDAO;
|
import com.orion.visor.module.asset.dao.HostDAO;
|
||||||
import com.orion.visor.module.asset.dao.UploadTaskDAO;
|
import com.orion.visor.module.asset.dao.UploadTaskDAO;
|
||||||
import com.orion.visor.module.asset.dao.UploadTaskFileDAO;
|
import com.orion.visor.module.asset.dao.UploadTaskFileDAO;
|
||||||
|
import com.orion.visor.module.asset.entity.domain.HostDO;
|
||||||
import com.orion.visor.module.asset.entity.domain.UploadTaskDO;
|
import com.orion.visor.module.asset.entity.domain.UploadTaskDO;
|
||||||
import com.orion.visor.module.asset.entity.domain.UploadTaskFileDO;
|
import com.orion.visor.module.asset.entity.domain.UploadTaskFileDO;
|
||||||
import com.orion.visor.module.asset.entity.dto.UploadTaskExtraDTO;
|
import com.orion.visor.module.asset.entity.dto.UploadTaskExtraDTO;
|
||||||
import com.orion.visor.module.asset.entity.request.upload.*;
|
import com.orion.visor.module.asset.entity.request.upload.*;
|
||||||
import com.orion.visor.module.asset.entity.vo.*;
|
import com.orion.visor.module.asset.entity.vo.*;
|
||||||
import com.orion.visor.module.asset.enums.HostTypeEnum;
|
import com.orion.visor.module.asset.enums.*;
|
||||||
import com.orion.visor.module.asset.enums.UploadTaskFileStatusEnum;
|
import com.orion.visor.module.asset.handler.host.config.model.HostSshConfigModel;
|
||||||
import com.orion.visor.module.asset.enums.UploadTaskStatusEnum;
|
|
||||||
import com.orion.visor.module.asset.handler.host.upload.FileUploadTasks;
|
import com.orion.visor.module.asset.handler.host.upload.FileUploadTasks;
|
||||||
import com.orion.visor.module.asset.handler.host.upload.manager.FileUploadTaskManager;
|
import com.orion.visor.module.asset.handler.host.upload.manager.FileUploadTaskManager;
|
||||||
import com.orion.visor.module.asset.handler.host.upload.model.FileUploadFileItemDTO;
|
import com.orion.visor.module.asset.handler.host.upload.model.FileUploadFileItemDTO;
|
||||||
import com.orion.visor.module.asset.handler.host.upload.task.IFileUploadTask;
|
import com.orion.visor.module.asset.handler.host.upload.task.IFileUploadTask;
|
||||||
import com.orion.visor.module.asset.handler.host.upload.uploader.IFileUploader;
|
import com.orion.visor.module.asset.handler.host.upload.uploader.IFileUploader;
|
||||||
import com.orion.visor.module.asset.service.AssetAuthorizedDataService;
|
import com.orion.visor.module.asset.service.AssetAuthorizedDataService;
|
||||||
|
import com.orion.visor.module.asset.service.HostConfigService;
|
||||||
import com.orion.visor.module.asset.service.UploadTaskFileService;
|
import com.orion.visor.module.asset.service.UploadTaskFileService;
|
||||||
import com.orion.visor.module.asset.service.UploadTaskService;
|
import com.orion.visor.module.asset.service.UploadTaskService;
|
||||||
import com.orion.visor.module.infra.api.FileUploadApi;
|
import com.orion.visor.module.infra.api.FileUploadApi;
|
||||||
@@ -83,6 +87,9 @@ public class UploadTaskServiceImpl implements UploadTaskService {
|
|||||||
@Resource
|
@Resource
|
||||||
private AssetAuthorizedDataService assetAuthorizedDataService;
|
private AssetAuthorizedDataService assetAuthorizedDataService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private HostConfigService hostConfigService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private FileUploadTaskManager fileUploadTaskManager;
|
private FileUploadTaskManager fileUploadTaskManager;
|
||||||
|
|
||||||
@@ -103,10 +110,9 @@ public class UploadTaskServiceImpl implements UploadTaskService {
|
|||||||
// 检查主机是否有权限
|
// 检查主机是否有权限
|
||||||
this.checkHostPermission(hostIdList);
|
this.checkHostPermission(hostIdList);
|
||||||
// 查询主机信息
|
// 查询主机信息
|
||||||
List<HostBaseVO> hosts = hostDAO.selectBaseByIdList(hostIdList)
|
List<HostDO> hosts = this.getUploadTaskHosts(hostIdList);
|
||||||
.stream()
|
// 计算文件路径
|
||||||
.map(HostConvert.MAPPER::toBase)
|
MultiHashMap<Long, String, String> realRemoteFilePathMap = this.setFileRealRemotePath(request, hosts);
|
||||||
.collect(Collectors.toList());
|
|
||||||
// 转换
|
// 转换
|
||||||
UploadTaskDO record = UploadTaskConvert.MAPPER.to(request);
|
UploadTaskDO record = UploadTaskConvert.MAPPER.to(request);
|
||||||
record.setUserId(user.getId());
|
record.setUserId(user.getId());
|
||||||
@@ -117,7 +123,7 @@ public class UploadTaskServiceImpl implements UploadTaskService {
|
|||||||
record.setHostCount(hostIdList.size());
|
record.setHostCount(hostIdList.size());
|
||||||
UploadTaskExtraDTO extra = UploadTaskExtraDTO.builder()
|
UploadTaskExtraDTO extra = UploadTaskExtraDTO.builder()
|
||||||
.hostIdList(hostIdList)
|
.hostIdList(hostIdList)
|
||||||
.hosts(hosts)
|
.hosts(HostConvert.MAPPER.toBaseList(hosts))
|
||||||
.build();
|
.build();
|
||||||
record.setExtraInfo(JSON.toJSONString(extra));
|
record.setExtraInfo(JSON.toJSONString(extra));
|
||||||
// 插入任务表
|
// 插入任务表
|
||||||
@@ -132,6 +138,7 @@ public class UploadTaskServiceImpl implements UploadTaskService {
|
|||||||
.hostId(hostId)
|
.hostId(hostId)
|
||||||
.fileId(s.getFileId())
|
.fileId(s.getFileId())
|
||||||
.filePath(s.getFilePath())
|
.filePath(s.getFilePath())
|
||||||
|
.realFilePath(realRemoteFilePathMap.get(hostId, s.getFileId()))
|
||||||
.fileSize(s.getFileSize())
|
.fileSize(s.getFileSize())
|
||||||
.status(UploadTaskFileStatusEnum.WAITING.name())
|
.status(UploadTaskFileStatusEnum.WAITING.name())
|
||||||
.build())
|
.build())
|
||||||
@@ -336,6 +343,68 @@ public class UploadTaskServiceImpl implements UploadTaskService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询上传任务主机信息
|
||||||
|
*
|
||||||
|
* @param hostIdList hostIdList
|
||||||
|
* @return hosts
|
||||||
|
*/
|
||||||
|
public List<HostDO> getUploadTaskHosts(List<Long> hostIdList) {
|
||||||
|
// 查询主机信息
|
||||||
|
List<HostDO> hosts = hostDAO.selectBatchIds(hostIdList);
|
||||||
|
// 检查主机数量
|
||||||
|
Valid.eq(hosts.size(), hostIdList.size(), ErrorMessage.HOST_ABSENT);
|
||||||
|
// 检查主机状态
|
||||||
|
boolean allEnabled = hosts.stream()
|
||||||
|
.map(HostDO::getStatus)
|
||||||
|
.allMatch(s -> HostStatusEnum.ENABLED.name().equals(s));
|
||||||
|
Valid.isTrue(allEnabled, ErrorMessage.HOST_NOT_ENABLED);
|
||||||
|
return hosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置文件实际路径
|
||||||
|
*
|
||||||
|
* @param request request
|
||||||
|
* @param hosts hosts
|
||||||
|
* @return realRemoteFilePathMap
|
||||||
|
*/
|
||||||
|
public MultiHashMap<Long, String, String> setFileRealRemotePath(UploadTaskCreateRequest request,
|
||||||
|
List<HostDO> hosts) {
|
||||||
|
MultiHashMap<Long, String, String> realRemoteFilePathMap = MultiHashMap.create();
|
||||||
|
// 计算上传目录
|
||||||
|
String remotePath = request.getRemotePath();
|
||||||
|
List<UploadTaskFileRequest> files = request.getFiles();
|
||||||
|
boolean containsEnv = remotePath.contains(Const.DOLLAR);
|
||||||
|
if (containsEnv) {
|
||||||
|
// 获取主机配置信息
|
||||||
|
Map<Long, HostSshConfigModel> hostConfigMap = hostConfigService.buildHostConfigMap(hosts, HostTypeEnum.SSH);
|
||||||
|
hostConfigMap.forEach((k, v) -> {
|
||||||
|
// 替换占位符
|
||||||
|
String username = v.getUsername();
|
||||||
|
String home = PathUtils.getHomePath(HostSshOsTypeEnum.isWindows(v.getOsType()), username);
|
||||||
|
// 替换环境变量路径
|
||||||
|
Map<String, String> env = Maps.newMap(4);
|
||||||
|
env.put(ExtraFieldConst.USERNAME, username);
|
||||||
|
env.put(ExtraFieldConst.HOME, home);
|
||||||
|
// 设置主机上传路径
|
||||||
|
String realRemotePath = Files1.getPath(Strings.format(remotePath, env));
|
||||||
|
for (UploadTaskFileRequest file : files) {
|
||||||
|
realRemoteFilePathMap.put(k, file.getFileId(), Files1.getPath(realRemotePath, file.getFilePath()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 无占位符
|
||||||
|
for (UploadTaskFileRequest file : files) {
|
||||||
|
String path = Files1.getPath(remotePath, file.getFilePath());
|
||||||
|
for (HostDO host : hosts) {
|
||||||
|
realRemoteFilePathMap.put(host.getId(), file.getFileId(), path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return realRemoteFilePathMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查文件完整性
|
* 检查文件完整性
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
<result column="host_id" property="hostId"/>
|
<result column="host_id" property="hostId"/>
|
||||||
<result column="file_id" property="fileId"/>
|
<result column="file_id" property="fileId"/>
|
||||||
<result column="file_path" property="filePath"/>
|
<result column="file_path" property="filePath"/>
|
||||||
|
<result column="real_file_path" property="realFilePath"/>
|
||||||
<result column="file_size" property="fileSize"/>
|
<result column="file_size" property="fileSize"/>
|
||||||
<result column="status" property="status"/>
|
<result column="status" property="status"/>
|
||||||
<result column="start_time" property="startTime"/>
|
<result column="start_time" property="startTime"/>
|
||||||
@@ -22,7 +23,7 @@
|
|||||||
|
|
||||||
<!-- 通用查询结果列 -->
|
<!-- 通用查询结果列 -->
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, task_id, host_id, file_id, file_path, file_size, status, start_time, end_time, create_time, update_time, creator, updater, deleted
|
id, task_id, host_id, file_id, file_path, real_file_path, file_size, status, start_time, end_time, create_time, update_time, creator, updater, deleted
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import com.orion.ext.process.ProcessAwaitExecutor;
|
|||||||
import com.orion.lang.support.Attempt;
|
import com.orion.lang.support.Attempt;
|
||||||
import com.orion.lang.utils.Arrays1;
|
import com.orion.lang.utils.Arrays1;
|
||||||
import com.orion.lang.utils.Strings;
|
import com.orion.lang.utils.Strings;
|
||||||
|
import com.orion.lang.utils.crypto.Signatures;
|
||||||
import com.orion.lang.utils.io.Streams;
|
import com.orion.lang.utils.io.Streams;
|
||||||
import com.orion.visor.framework.common.constant.AppConst;
|
import com.orion.visor.framework.common.constant.AppConst;
|
||||||
import com.orion.visor.framework.common.constant.Const;
|
import com.orion.visor.framework.common.constant.Const;
|
||||||
import com.orion.visor.framework.common.utils.Mixes;
|
|
||||||
import com.orion.visor.module.infra.entity.vo.AppInfoVO;
|
import com.orion.visor.module.infra.entity.vo.AppInfoVO;
|
||||||
import com.orion.visor.module.infra.service.SystemSettingService;
|
import com.orion.visor.module.infra.service.SystemSettingService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -70,7 +70,7 @@ public class SystemSettingServiceImpl implements SystemSettingService {
|
|||||||
if (!Strings.isBlank(extraUuid)) {
|
if (!Strings.isBlank(extraUuid)) {
|
||||||
uuid = extraUuid.trim();
|
uuid = extraUuid.trim();
|
||||||
}
|
}
|
||||||
return this.uuid = Mixes.obfuscate(uuid);
|
return this.uuid = Signatures.md5(uuid);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// IGNORED
|
// IGNORED
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
VITE_API_BASE_URL= 'http://127.0.0.1:9200/orion-visor/api'
|
VITE_API_BASE_URL= 'http://127.0.0.1:9200/orion-visor/api'
|
||||||
VITE_WS_BASE_URL= 'ws://127.0.0.1:9200/orion-visor/keep-alive'
|
VITE_WS_BASE_URL= 'ws://127.0.0.1:9200/orion-visor/keep-alive'
|
||||||
VITE_APP_VERSION= '2.1.5'
|
VITE_APP_VERSION= '2.1.7'
|
||||||
VITE_APP_RELEASE= 'community'
|
VITE_APP_RELEASE= 'community'
|
||||||
VITE_SFTP_PREVIEW_MB= 2
|
VITE_SFTP_PREVIEW_MB= 2
|
||||||
VITE_DEMO_MODE= false
|
VITE_DEMO_MODE= false
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
VITE_API_BASE_URL= '/orion-visor/api'
|
VITE_API_BASE_URL= '/orion-visor/api'
|
||||||
VITE_WS_BASE_URL= '/orion-visor/keep-alive'
|
VITE_WS_BASE_URL= '/orion-visor/keep-alive'
|
||||||
VITE_APP_VERSION= '2.1.5'
|
VITE_APP_VERSION= '2.1.7'
|
||||||
VITE_APP_RELEASE= 'community'
|
VITE_APP_RELEASE= 'community'
|
||||||
VITE_SFTP_PREVIEW_MB= 2
|
VITE_SFTP_PREVIEW_MB= 2
|
||||||
VITE_DEMO_MODE= false
|
VITE_DEMO_MODE= false
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const enabled = (): Partial<VitePWAOptions> => {
|
|||||||
manifest: {
|
manifest: {
|
||||||
name: 'Orion Visor Community',
|
name: 'Orion Visor Community',
|
||||||
short_name: 'Orion Visor',
|
short_name: 'Orion Visor',
|
||||||
description: '一款高颜值、现代化的智能运维&轻量堡垒机平台。',
|
description: '一款高颜值、现代化的自动化运维&轻量堡垒机平台。',
|
||||||
theme_color: '#212529',
|
theme_color: '#212529',
|
||||||
icons: [{
|
icons: [{
|
||||||
src: 'manifest_logo_267.png',
|
src: 'manifest_logo_267.png',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "orion-visor-ui",
|
"name": "orion-visor-ui",
|
||||||
"description": "Orion Visor UI",
|
"description": "Orion Visor UI",
|
||||||
"version": "2.1.5",
|
"version": "2.1.7",
|
||||||
"private": true,
|
"private": true,
|
||||||
"author": "Jiahang Li",
|
"author": "Jiahang Li",
|
||||||
"license": "Apache 2.0",
|
"license": "Apache 2.0",
|
||||||
|
|||||||
BIN
orion-visor-ui/src/assets/logo_horizontal.png
Normal file
BIN
orion-visor-ui/src/assets/logo_horizontal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
@@ -59,8 +59,8 @@
|
|||||||
<a-form-item field="limit" label="数量限制">
|
<a-form-item field="limit" label="数量限制">
|
||||||
<a-input-number v-model="formModel.limit"
|
<a-input-number v-model="formModel.limit"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="maxLimit"
|
:max="maxClearLimit"
|
||||||
:placeholder="`请输入数量限制 最大: ${maxLimit}`"
|
:placeholder="`请输入数量限制 最大: ${maxClearLimit}`"
|
||||||
hide-button
|
hide-button
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -101,16 +101,14 @@
|
|||||||
type: undefined,
|
type: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
startTimeRange: undefined,
|
startTimeRange: undefined,
|
||||||
limit: maxLimit.value,
|
limit: maxClearLimit,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const maxLimit = ref<number>(0);
|
|
||||||
const formModel = ref<HostConnectLogQueryRequest>({});
|
const formModel = ref<HostConnectLogQueryRequest>({});
|
||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
const open = (record: any) => {
|
const open = (record: any) => {
|
||||||
maxLimit.value = maxClearLimit;
|
|
||||||
renderForm({ ...defaultForm(), ...record });
|
renderForm({ ...defaultForm(), ...record });
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default {
|
|||||||
'login.form.userName.placeholder': '用户名',
|
'login.form.userName.placeholder': '用户名',
|
||||||
'login.form.password.placeholder': '密码',
|
'login.form.password.placeholder': '密码',
|
||||||
'login.form.login': '登录',
|
'login.form.login': '登录',
|
||||||
'login.banner.slogan1': '现代化的智能运维平台',
|
'login.banner.slogan1': '现代化的自动化运维平台',
|
||||||
'login.banner.subSlogan1': '一站式操作 让运维变得更简单',
|
'login.banner.subSlogan1': '一站式操作 让运维变得更简单',
|
||||||
'login.banner.slogan2': '高颜值的轻量堡垒机平台',
|
'login.banner.slogan2': '高颜值的轻量堡垒机平台',
|
||||||
'login.banner.subSlogan2': '内置批量处理模块 让工作更高效',
|
'login.banner.subSlogan2': '内置批量处理模块 让工作更高效',
|
||||||
|
|||||||
@@ -51,8 +51,8 @@
|
|||||||
<a-form-item field="limit" label="数量限制">
|
<a-form-item field="limit" label="数量限制">
|
||||||
<a-input-number v-model="formModel.limit"
|
<a-input-number v-model="formModel.limit"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="maxLimit"
|
:max="maxClearLimit"
|
||||||
:placeholder="`请输入数量限制 最大: ${maxLimit}`"
|
:placeholder="`请输入数量限制 最大: ${maxClearLimit}`"
|
||||||
hide-button
|
hide-button
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -85,7 +85,6 @@
|
|||||||
const { loading, setLoading } = useLoading();
|
const { loading, setLoading } = useLoading();
|
||||||
const { toOptions } = useDictStore();
|
const { toOptions } = useDictStore();
|
||||||
|
|
||||||
const maxLimit = ref<number>(0);
|
|
||||||
const formModel = ref<ExecLogQueryRequest>({});
|
const formModel = ref<ExecLogQueryRequest>({});
|
||||||
|
|
||||||
const defaultForm = (): ExecLogQueryRequest => {
|
const defaultForm = (): ExecLogQueryRequest => {
|
||||||
@@ -96,13 +95,12 @@
|
|||||||
command: undefined,
|
command: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
startTimeRange: undefined,
|
startTimeRange: undefined,
|
||||||
limit: maxLimit.value,
|
limit: maxClearLimit,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
const open = (record: any) => {
|
const open = (record: any) => {
|
||||||
maxLimit.value = maxClearLimit;
|
|
||||||
renderForm({ ...defaultForm(), ...record });
|
renderForm({ ...defaultForm(), ...record });
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,8 +52,8 @@
|
|||||||
<a-form-item field="limit" label="数量限制">
|
<a-form-item field="limit" label="数量限制">
|
||||||
<a-input-number v-model="formModel.limit"
|
<a-input-number v-model="formModel.limit"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="maxLimit"
|
:max="maxClearLimit"
|
||||||
:placeholder="`请输入数量限制 最大: ${maxLimit}`"
|
:placeholder="`请输入数量限制 最大: ${maxClearLimit}`"
|
||||||
hide-button
|
hide-button
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -85,7 +85,6 @@
|
|||||||
const { loading, setLoading } = useLoading();
|
const { loading, setLoading } = useLoading();
|
||||||
const { toOptions } = useDictStore();
|
const { toOptions } = useDictStore();
|
||||||
|
|
||||||
const maxLimit = ref<number>(0);
|
|
||||||
const formModel = ref<UploadTaskQueryRequest>({});
|
const formModel = ref<UploadTaskQueryRequest>({});
|
||||||
|
|
||||||
const defaultForm = (): UploadTaskQueryRequest => {
|
const defaultForm = (): UploadTaskQueryRequest => {
|
||||||
@@ -95,13 +94,12 @@
|
|||||||
description: undefined,
|
description: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
createTimeRange: undefined,
|
createTimeRange: undefined,
|
||||||
limit: maxLimit.value,
|
limit: maxClearLimit,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
const open = (record: any) => {
|
const open = (record: any) => {
|
||||||
maxLimit.value = maxClearLimit;
|
|
||||||
renderForm({ ...defaultForm(), ...record });
|
renderForm({ ...defaultForm(), ...record });
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -46,8 +46,8 @@
|
|||||||
<a-form-item field="limit" label="数量限制">
|
<a-form-item field="limit" label="数量限制">
|
||||||
<a-input-number v-model="formModel.limit"
|
<a-input-number v-model="formModel.limit"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="maxLimit"
|
:max="maxClearLimit"
|
||||||
:placeholder="`请输入数量限制 最大: ${maxLimit}`"
|
:placeholder="`请输入数量限制 最大: ${maxClearLimit}`"
|
||||||
hide-button
|
hide-button
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -80,7 +80,6 @@
|
|||||||
const { loading, setLoading } = useLoading();
|
const { loading, setLoading } = useLoading();
|
||||||
const { toOptions } = useDictStore();
|
const { toOptions } = useDictStore();
|
||||||
|
|
||||||
const maxLimit = ref<number>(0);
|
|
||||||
const formModel = ref<ExecLogQueryRequest>({});
|
const formModel = ref<ExecLogQueryRequest>({});
|
||||||
|
|
||||||
const defaultForm = (): ExecLogQueryRequest => {
|
const defaultForm = (): ExecLogQueryRequest => {
|
||||||
@@ -91,13 +90,12 @@
|
|||||||
command: undefined,
|
command: undefined,
|
||||||
status: undefined,
|
status: undefined,
|
||||||
startTimeRange: undefined,
|
startTimeRange: undefined,
|
||||||
limit: maxLimit.value,
|
limit: maxClearLimit,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
const open = (record: any) => {
|
const open = (record: any) => {
|
||||||
maxLimit.value = maxClearLimit;
|
|
||||||
renderForm({ ...defaultForm(), ...record });
|
renderForm({ ...defaultForm(), ...record });
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -65,8 +65,8 @@
|
|||||||
<a-form-item field="limit" label="数量限制">
|
<a-form-item field="limit" label="数量限制">
|
||||||
<a-input-number v-model="formModel.limit"
|
<a-input-number v-model="formModel.limit"
|
||||||
:min="1"
|
:min="1"
|
||||||
:max="maxLimit"
|
:max="maxClearLimit"
|
||||||
:placeholder="`请输入数量限制 最大: ${maxLimit}`"
|
:placeholder="`请输入数量限制 最大: ${maxClearLimit}`"
|
||||||
hide-button
|
hide-button
|
||||||
allow-clear />
|
allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@@ -105,11 +105,10 @@
|
|||||||
riskLevel: undefined,
|
riskLevel: undefined,
|
||||||
result: undefined,
|
result: undefined,
|
||||||
startTimeRange: undefined,
|
startTimeRange: undefined,
|
||||||
limit: maxLimit.value,
|
limit: maxClearLimit,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const maxLimit = ref<number>(0);
|
|
||||||
const typeOptions = ref<SelectOptionData[]>(toOptions(operatorLogTypeKey));
|
const typeOptions = ref<SelectOptionData[]>(toOptions(operatorLogTypeKey));
|
||||||
const formModel = ref<OperatorLogQueryRequest>({});
|
const formModel = ref<OperatorLogQueryRequest>({});
|
||||||
|
|
||||||
@@ -117,7 +116,6 @@
|
|||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
const open = (record: OperatorLogQueryRequest) => {
|
const open = (record: OperatorLogQueryRequest) => {
|
||||||
maxLimit.value = maxClearLimit;
|
|
||||||
renderForm({ ...defaultForm(), ...record });
|
renderForm({ ...defaultForm(), ...record });
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
};
|
};
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -22,7 +22,7 @@
|
|||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<revision>2.1.5</revision>
|
<revision>2.1.7</revision>
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
<maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
|
<maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
|
||||||
|
|||||||
@@ -829,6 +829,7 @@ CREATE TABLE `upload_task_file`
|
|||||||
`host_id` bigint(0) NULL DEFAULT NULL COMMENT '主机id',
|
`host_id` bigint(0) NULL DEFAULT NULL COMMENT '主机id',
|
||||||
`file_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '文件id',
|
`file_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '文件id',
|
||||||
`file_path` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '文件路径',
|
`file_path` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '文件路径',
|
||||||
|
`real_file_path` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '实际文件路径',
|
||||||
`file_size` bigint(0) NULL DEFAULT NULL COMMENT '文件大小',
|
`file_size` bigint(0) NULL DEFAULT NULL COMMENT '文件大小',
|
||||||
`status` char(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态',
|
`status` char(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '状态',
|
||||||
`start_time` datetime(3) NULL DEFAULT NULL COMMENT '开始时间',
|
`start_time` datetime(3) NULL DEFAULT NULL COMMENT '开始时间',
|
||||||
|
|||||||
Reference in New Issue
Block a user