Compare commits

...

38 Commits

Author SHA1 Message Date
李佳航
1b2753a2b7 Merge pull request #44 from dromara/dev
Dev
2024-07-26 11:11:47 +08:00
lijiahang
29b44b8b77 🚨 修复 ts 构建报错. 2024-07-26 10:56:36 +08:00
lijiahang
7290b1364c 🔖 升级版本. 2024-07-26 10:25:38 +08:00
lijiahang
3851ead8bb 💄 修改滚动条样式. 2024-07-26 10:18:39 +08:00
lijiahang
305312cc26 🐛 修复文件上传列表显示错误. 2024-07-25 13:46:48 +08:00
李佳航
b4217555d2 Merge pull request #43 from dromara/dev
Dev
2024-07-25 11:16:59 +08:00
lijiahang
87b8e405f5 🔖 升级版本. 2024-07-25 10:27:49 +08:00
lijiahang
3513196a78 修改类型定义. 2024-07-24 15:29:15 +08:00
lijiahang
0240a12321 ⬆️ 修改升级sql. 2024-07-24 15:04:29 +08:00
lijiahang
3a8eac4d4a 重构终端功能. 2024-07-23 10:47:59 +08:00
lijiahang
4bd2de4ce2 🔨 重构主机模块. 2024-07-22 19:36:02 +08:00
lijiahang
b7608fccb3 🔨 修改主机逻辑. 2024-07-22 18:05:00 +08:00
lijiahang
bb925d354d 📝 修改 md 地址. 2024-07-22 10:37:11 +08:00
lijiahang
3a476d41d2 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	README.md
2024-07-22 10:31:45 +08:00
lijiahang
1927b10bcc 📝 修改 md 地址. 2024-07-22 10:31:05 +08:00
lijiahang
0664eff151 🐛 windows 移动文件失败. 2024-07-22 10:27:21 +08:00
lijiahang
a71456b209 去除注解. 2024-07-18 15:39:31 +08:00
lijiahang
48d308b1a8 🐛 批量执行历史显示错误. 2024-07-17 13:38:51 +08:00
lijiahang
f75d097d8a 删除 http 文件. 2024-07-17 13:35:04 +08:00
lijiahang
0d46d81c4e 优化文件上传逻辑. 2024-07-15 10:15:20 +08:00
lijiahangmax
c20c83245f 🐛 修复 windows 文件备份失败. 2024-07-14 21:24:53 +08:00
lijiahangmax
849e010bc3 Merge remote-tracking branch 'origin/dev' into dev 2024-07-12 00:02:57 +08:00
lijiahangmax
95c299eea4 💄 修改主机编辑样式. 2024-07-12 00:02:45 +08:00
李佳航
ad3edd4ccd Merge pull request #41 from dromara/dev
Dev
2024-07-11 11:08:52 +08:00
lijiahang
81b7b3505e 🚀 修改启动命令. 2024-07-11 10:56:49 +08:00
lijiahang
1522a6f3ad 🔖 升级版本. 2024-07-11 10:28:44 +08:00
lijiahang
04bae45955 修改执行参数. 2024-07-10 11:46:07 +08:00
lijiahang
873e910eb1 定时任务添加参数. 2024-07-10 10:21:16 +08:00
lijiahang
a7f86bf62a 💄 修改表格样式. 2024-07-09 10:34:39 +08:00
lijiahang
7ba278d210 📝 添加 NOTICE 文件. 2024-07-08 14:45:12 +08:00
lijiahang
e9ac9b9f13 修改字典值长度. 2024-07-08 14:44:33 +08:00
lijiahangmax
d34843f90c 主机终端主题从字典中获取. 2024-07-04 21:53:21 +08:00
lijiahang
374d0bdd9c Merge remote-tracking branch 'origin/dev' into dev 2024-07-04 10:29:58 +08:00
lijiahang
5d3dc83bab 🐛 修复操作日志分页无效. 2024-07-04 10:29:39 +08:00
lijiahangmax
05d0f75cdc Merge remote-tracking branch 'origin/dev' into dev 2024-06-30 01:14:58 +08:00
lijiahangmax
711a4a6bab 🐛 修复终端大小适配失效. 2024-06-30 01:14:44 +08:00
李佳航
08895ba170 Merge pull request #37 from LinuxSuRen/fix/e2e
🐛 e2e 配置失效.
2024-06-27 15:27:11 +08:00
rick
c2c8b108ac fix: the e2e testing failure due to auth error 2024-06-27 07:23:24 +00:00
357 changed files with 3550 additions and 4619 deletions

View File

@@ -4,9 +4,8 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
- dev
concurrency: concurrency:
group: ${{github.workflow}} - ${{github.ref}} group: ${{github.workflow}} - ${{github.ref}}
cancel-in-progress: true cancel-in-progress: true

7
NOTICE Normal file
View File

@@ -0,0 +1,7 @@
* 在使用本项目前,请您仔细阅读免责声明,确保您已充分理解其中的内容
* 本项目采用 APACHE LICENSE 2.0 开源协议,如您需要源码的开发方式,需要遵循以下几点
1. 禁止修改或删除 LICENSE 文件。
2. 不可二次开发或参与同类竞品的开发。
3. 本项目可免费商业使用,商业使用请保留项目源码、出处、描述文件和作者声明等。

View File

@@ -53,7 +53,7 @@
* 🔗 演示地址: http://101.43.254.243:1081/ * 🔗 演示地址: http://101.43.254.243:1081/
* 🔏 演示账号: admin/admin * 🔏 演示账号: admin/admin
* ⭐ 体验后可以点一下 `star` 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) * ⭐ 体验后可以点一下 `star` 这对我很重要! [github](https://github.com/dromara/orion-visor) [gitee](https://gitee.com/dromara/orion-visor) [gitcode](https://gitcode.com/dromara/orion-visor/overview)
* 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目! * 🌈 如果本项目对你有帮助请帮忙推广一下 让更多的人知道此项目!
* 🎭 演示环境部分功能不可用, 完整功能请本地部署! * 🎭 演示环境部分功能不可用, 完整功能请本地部署!
* 📛 演示环境请不要随便删除数据! * 📛 演示环境请不要随便删除数据!

View File

@@ -1,7 +1,7 @@
version: '3.3' version: '3.3'
services: services:
orion-visor-service: orion-visor-service:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.0.10 image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.1
privileged: true privileged: true
ports: ports:
- 1081:80 - 1081:80
@@ -32,7 +32,7 @@ services:
- orion-visor-mysql - orion-visor-mysql
- orion-visor-redis - orion-visor-redis
orion-visor-mysql: orion-visor-mysql:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.0.10 image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.1
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
orion-visor-redis: orion-visor-redis:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.0.10 image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.1
privileged: true privileged: true
ports: ports:
- 6380:6379 - 6380:6379

View File

@@ -1,7 +1,7 @@
version: '3.3' version: '3.3'
services: services:
orion-visor-service: orion-visor-service:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.0.10 image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-service:2.1.1
privileged: true privileged: true
ports: ports:
- 1081:80 - 1081:80
@@ -32,7 +32,7 @@ services:
- orion-visor-mysql - orion-visor-mysql
- orion-visor-redis - orion-visor-redis
orion-visor-mysql: orion-visor-mysql:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.0.10 image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-mysql:2.1.1
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
orion-visor-redis: orion-visor-redis:
image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.0.10 image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:2.1.1
privileged: true privileged: true
ports: ports:
- 6380:6379 - 6380:6379

View File

@@ -4,4 +4,4 @@ docker compose down
if [ "$1" == "demo" ]; then if [ "$1" == "demo" ]; then
sed -i 's/DEMO_MODE=false/DEMO_MODE=true/g' docker-compose.yml sed -i 's/DEMO_MODE=false/DEMO_MODE=true/g' docker-compose.yml
fi fi
docker compose up -d docker compose up -d --remove-orphans

View File

@@ -36,22 +36,14 @@ items:
- name: haveUnRead - name: haveUnRead
request: request:
api: /orion-visor/api/infra/system-message/has-unread api: /orion-visor/api/infra/system-message/has-unread
header:
Authorization: Bearer {{.login.data.token}}
- name: queryOperatorLog - name: queryOperatorLog
request: request:
api: /orion-visor/api/infra/mine/query-operator-log api: /orion-visor/api/infra/mine/query-operator-log
method: POST method: POST
header:
Authorization: Bearer {{.login.data.token}}
- name: hostList - name: hostList
request: request:
api: /orion-visor/api/infra/tag/list?type=HOST api: /orion-visor/api/infra/tag/list?type=HOST
header:
Authorization: Bearer {{.login.data.token}}
- name: queryHost - name: queryHost
request: request:
api: /orion-visor/api/asset/host/query api: /orion-visor/api/asset/host/query
method: POST method: POST
header:
Authorization: Bearer {{.login.data.token}}

View File

@@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
version=2.0.10 version=2.1.1
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

View File

@@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
version=2.0.10 version=2.1.1
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}
docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version} docker push registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-visor-redis:${version}

View File

@@ -1,5 +1,5 @@
#/bin/bash #/bin/bash
version=2.0.10 version=2.1.1
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} .

View File

@@ -14,7 +14,7 @@
<url>https://github.com/dromara/orion-visor</url> <url>https://github.com/dromara/orion-visor</url>
<properties> <properties>
<revision>2.0.10</revision> <revision>2.1.1</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>

View File

@@ -14,7 +14,7 @@ public interface AppConst extends OrionConst {
/** /**
* 同 ${orion.version} 迭代时候需要手动更改 * 同 ${orion.version} 迭代时候需要手动更改
*/ */
String VERSION = "2.0.10"; String VERSION = "2.1.1";
/** /**
* 同 ${spring.application.name} * 同 ${spring.application.name}

View File

@@ -61,6 +61,10 @@ public interface ErrorMessage {
String GROUP_ABSENT = "分组不存在"; String GROUP_ABSENT = "分组不存在";
String HOST_TYPE_ERROR = "主机类型错误";
String HOST_NOT_ENABLED = "主机未启用";
String UNABLE_OPERATE_ADMIN_ROLE = "无法操作管理员账号"; String UNABLE_OPERATE_ADMIN_ROLE = "无法操作管理员账号";
String UNSUPPORTED_CHARSET = "不支持的编码 [{}]"; String UNSUPPORTED_CHARSET = "不支持的编码 [{}]";

View File

@@ -43,4 +43,6 @@ public interface ExtraFieldConst extends FieldConst {
String LOG_ID = "logId"; String LOG_ID = "logId";
String DARK = "dark";
} }

View File

@@ -31,6 +31,8 @@ public interface FieldConst {
String INFO = "info"; String INFO = "info";
String EXTRA = "extra";
String REL_ID = "relId"; String REL_ID = "relId";
String BEFORE = "before"; String BEFORE = "before";
@@ -59,10 +61,24 @@ public interface FieldConst {
String TIME = "time"; String TIME = "time";
String ISSUE = "issue";
String EXPIRE = "expire";
String LOCATION = "location"; String LOCATION = "location";
String USER_AGENT = "userAgent"; String USER_AGENT = "userAgent";
String ERROR_MESSAGE = "errorMessage"; String ERROR_MESSAGE = "errorMessage";
String UUID = "uuid";
String REDIRECT = "redirect";
String SCHEMA = "schema";
String FILTER = "filter";
String ALL = "all";
} }

View File

@@ -310,8 +310,6 @@ public class CodeGenerator implements Executable {
new String[]{"/templates/orion-server-module-entity-request-update.java.vm", "${type}UpdateRequest.java", "entity.request.${bizPackage}"}, new String[]{"/templates/orion-server-module-entity-request-update.java.vm", "${type}UpdateRequest.java", "entity.request.${bizPackage}"},
// query request 文件 // query request 文件
new String[]{"/templates/orion-server-module-entity-request-query.java.vm", "${type}QueryRequest.java", "entity.request.${bizPackage}"}, new String[]{"/templates/orion-server-module-entity-request-query.java.vm", "${type}QueryRequest.java", "entity.request.${bizPackage}"},
// export 文件
new String[]{"/templates/orion-server-module-entity-export.java.vm", "${type}Export.java", "entity.export"},
// convert 文件 // convert 文件
new String[]{"/templates/orion-server-module-convert.java.vm", "${type}Convert.java", "convert"}, new String[]{"/templates/orion-server-module-convert.java.vm", "${type}Convert.java", "convert"},
// cache dto 文件 // cache dto 文件

View File

@@ -113,7 +113,6 @@ public class CodeGeneratorEngine extends VelocityTemplateEngine {
apiComment.put("deleteById", "删除" + comment); apiComment.put("deleteById", "删除" + comment);
apiComment.put("deleteAll", "根据条件删除" + comment); apiComment.put("deleteAll", "根据条件删除" + comment);
apiComment.put("batchDelete", "批量删除" + comment); apiComment.put("batchDelete", "批量删除" + comment);
apiComment.put("export", "导出" + comment);
objectMap.put("apiComment", apiComment); objectMap.put("apiComment", apiComment);
} }

View File

@@ -38,14 +38,18 @@ public class CustomFileFilter {
public List<CustomFile> doFilter() { public List<CustomFile> doFilter() {
// 生成文件副本 // 生成文件副本
List<CustomFile> files = originCustomerFile.stream().map(s -> List<CustomFile> files = originCustomerFile.stream().map(s ->
new CustomFile.Builder() new CustomFile.Builder()
.enableFileOverride() .enableFileOverride()
.templatePath(s.getTemplatePath()) .templatePath(s.getTemplatePath())
.filePath(s.getFilePath()) .filePath(s.getFilePath())
.fileName(s.getFileName()) .fileName(s.getFileName())
.packageName(s.getPackageName()) .packageName(s.getPackageName())
.build()) .build())
.collect(Collectors.toList()); .collect(Collectors.toList());
// 不生成 api http 文件
if (!table.isEnableApiHttp()) {
files.removeIf(file -> isApiHttpFile(file.getTemplatePath()));
}
// 不生成对外 api 文件 // 不生成对外 api 文件
if (!table.isEnableProviderApi()) { if (!table.isEnableProviderApi()) {
files.removeIf(file -> isServerProviderFile(file.getTemplatePath())); files.removeIf(file -> isServerProviderFile(file.getTemplatePath()));
@@ -139,13 +143,13 @@ public class CustomFileFilter {
} }
/** /**
* 是否为导出文件 * 是否为 api http 文件
* *
* @param templatePath templatePath * @param templatePath templatePath
* @return 是否为导出文件 * @return 是否为导出文件
*/ */
public static boolean isExportFile(String templatePath) { public static boolean isApiHttpFile(String templatePath) {
return templatePath.contains("orion-server-module-entity-export"); return templatePath.contains("orion-server-module-controller.http");
} }
/** /**

View File

@@ -63,6 +63,16 @@ public class ServerTemplate extends Template {
return this; return this;
} }
/**
* 是否生成 api http 文件
*
* @return this
*/
public ServerTemplate enableApiHttp() {
table.enableApiHttp = true;
return this;
}
/** /**
* 是否生成对外 api * 是否生成对外 api
* *

View File

@@ -33,6 +33,11 @@ public class Table {
*/ */
protected String bizPackage; protected String bizPackage;
/**
* 是否生成 api http 文件
*/
protected boolean enableApiHttp;
/** /**
* 是否生成对外 api * 是否生成对外 api
*/ */

View File

@@ -210,14 +210,23 @@ public class DataQuery<T> {
// -------------------- data grid -------------------- // -------------------- data grid --------------------
public DataGrid<T> dataGrid() { public DataGrid<T> dataGrid() {
return this.dataGrid(Function.identity()); return this.dataGrid(this.wrapper, Function.identity());
}
public DataGrid<T> dataGrid(Wrapper<T> countWrapper) {
return this.dataGrid(countWrapper, Function.identity());
} }
public <R> DataGrid<R> dataGrid(Function<T, R> mapper) { public <R> DataGrid<R> dataGrid(Function<T, R> mapper) {
Valid.notNull(mapper, "convert function is null"); return this.dataGrid(this.wrapper, mapper);
}
public <R> DataGrid<R> dataGrid(Wrapper<T> countWrapper, Function<T, R> mapper) {
Valid.notNull(page, "page is null"); Valid.notNull(page, "page is null");
Valid.notNull(wrapper, "wrapper is null"); Valid.notNull(wrapper, "wrapper is null");
Long count = dao.selectCount(wrapper); Valid.notNull(countWrapper, "count wrapper is null");
Valid.notNull(mapper, "convert function is null");
Long count = dao.selectCount(countWrapper);
Pager<R> pager = new Pager<>(page); Pager<R> pager = new Pager<>(page);
pager.setTotal(count.intValue()); pager.setTotal(count.intValue());
boolean next = pager.hasMoreData(); boolean next = pager.hasMoreData();

View File

@@ -44,7 +44,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/${package.ModuleName}/${typeHyphen}") @RequestMapping("/${package.ModuleName}/${typeHyphen}")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
#if(${superControllerClass}) #if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} { public class ${table.controllerName} extends ${superControllerClass} {
#else #else

View File

@@ -1,65 +0,0 @@
package ${currentPackage};
import com.orion.lang.utils.time.Dates;
import com.orion.office.excel.annotation.ExportField;
import com.orion.office.excel.annotation.ExportSheet;
import com.orion.office.excel.annotation.ExportTitle;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.util.*;
import java.math.*;
/**
* $!{table.comment} 导出对象
*
* @author ${author}
* @version ${version}
* @since ${date}
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ExportTitle(title = ${type}Export.TITLE)
@ExportSheet(name = "$!{table.comment}", filterHeader = true, freezeHeader = true, indexToSort = true)
@Schema(name = "${type}Export", description = "$!{table.comment}导出对象")
public class ${type}Export implements Serializable {
private static final long serialVersionUID = 1L;
public static final String TITLE = "$!{table.comment}导出";
#foreach($field in ${table.fields})
#if("$!field.comment" != "")
@Schema(description = "${field.comment}")
#end
#if("$field.propertyType" == "Date")
@ExportField(index = ${foreach.index}, header = "${field.comment}", width = 16, format = Dates.YMD_HMS)
#else
@ExportField(index = ${foreach.index}, header = "${field.comment}", width = 16)
#end
private ${field.propertyType} ${field.propertyName};
#end
@ExportField(index = $table.fields.size(), header = "创建时间", width = 16, format = Dates.YMD_HMS)
@Schema(description = "创建时间")
private Date createTime;
#set($updateTimeIndex=$table.fields.size() + 1)
@Schema(description = "修改时间")
@ExportField(index = $updateTimeIndex, header = "修改时间", width = 16, format = Dates.YMD_HMS)
private Date updateTime;
#set($creatorIndex=$table.fields.size() + 2)
@Schema(description = "创建人")
@ExportField(index = $creatorIndex, header = "创建人", width = 16)
private String creator;
#set($updaterIndex=$table.fields.size() + 3)
@Schema(description = "修改人")
@ExportField(index = $updaterIndex, header = "修改人", width = 16)
private String updater;
}

View File

@@ -26,7 +26,3 @@ VALUES
(@TMP_SUB_ID, '创建$table.comment', '${package.ModuleName}:${typeHyphen}:create', 3, 20, '1', '1', 0), (@TMP_SUB_ID, '创建$table.comment', '${package.ModuleName}:${typeHyphen}:create', 3, 20, '1', '1', 0),
(@TMP_SUB_ID, '修改$table.comment', '${package.ModuleName}:${typeHyphen}:update', 3, 30, '1', '1', 0), (@TMP_SUB_ID, '修改$table.comment', '${package.ModuleName}:${typeHyphen}:update', 3, 30, '1', '1', 0),
(@TMP_SUB_ID, '删除$table.comment', '${package.ModuleName}:${typeHyphen}:delete', 3, 40, '1', '1', 0); (@TMP_SUB_ID, '删除$table.comment', '${package.ModuleName}:${typeHyphen}:delete', 3, 40, '1', '1', 0);
#if(false)
(@TMP_SUB_ID, '导出$table.comment', '${package.ModuleName}:${typeHyphen}:export', 3, 50, '1', '1', 0),
(@TMP_SUB_ID, '导入$table.comment', '${package.ModuleName}:${typeHyphen}:import', 3, 60, '1', '1', 0);
#end

View File

@@ -3,7 +3,7 @@
search-input-placeholder="输入搜索值" search-input-placeholder="输入搜索值"
create-card-position="head" create-card-position="head"
:loading="loading" :loading="loading"
:fieldConfig="fieldConfig" :field-config="fieldConfig"
:list="list" :list="list"
:pagination="pagination" :pagination="pagination"
:card-layout-cols="cardColLayout" :card-layout-cols="cardColLayout"
@@ -74,15 +74,16 @@
<!-- 修改 --> <!-- 修改 -->
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']" <a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']"
@click="emits('openUpdate', record)"> @click="emits('openUpdate', record)">
<icon-edit /> <span class="more-doption normal">
修改 <icon-edit /> 修改
</span>
</a-doption> </a-doption>
<!-- 删除 --> <!-- 删除 -->
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']" <a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
class="span-red"
@click="deleteRow(record.id)"> @click="deleteRow(record.id)">
<icon-delete /> <span class="more-doption error">
删除 <icon-delete /> 删除
</span>
</a-doption> </a-doption>
</template> </template>
</a-dropdown> </a-dropdown>
@@ -93,15 +94,17 @@
<!-- 修改 --> <!-- 修改 -->
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']" <a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']"
@click="emits('openUpdate', record)"> @click="emits('openUpdate', record)">
<icon-edit /> <span class="more-doption normal">
修改 <icon-edit /> 修改
</span>
</a-doption> </a-doption>
<!-- 删除 --> <!-- 删除 -->
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']" <a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
class="span-red" class="span-red"
@click="deleteRow(record.id)"> @click="deleteRow(record.id)">
<icon-delete /> <span class="more-doption error">
删除 <icon-delete /> 删除
</span>
</a-doption> </a-doption>
</template> </template>
</card-list> </card-list>

View File

@@ -1,6 +1,6 @@
<template> <template>
<a-modal v-model:visible="visible" <a-modal v-model:visible="visible"
body-class="modal-form-large" modal-class="modal-form-large"
title-align="start" title-align="start"
:title="title" :title="title"
:top="80" :top="80"

View File

@@ -94,8 +94,8 @@
:data="tableRenderData" :data="tableRenderData"
:pagination="pagination" :pagination="pagination"
:bordered="false" :bordered="false"
@page-change="(page) => fetchTableData(page, pagination.pageSize)" @page-change="(page: number) => fetchTableData(page, pagination.pageSize)"
@page-size-change="(size) => fetchTableData(1, size)"> @page-size-change="(size: number) => fetchTableData(1, size)">
#foreach($field in ${table.fields}) #foreach($field in ${table.fields})
#if(${dictMap.containsKey(${field.propertyName})}) #if(${dictMap.containsKey(${field.propertyName})})
<!-- $field.comment --> <!-- $field.comment -->

View File

@@ -6,7 +6,7 @@ const columns = [
title: 'id', title: 'id',
dataIndex: 'id', dataIndex: 'id',
slotName: 'id', slotName: 'id',
width: 100, width: 68,
align: 'left', align: 'left',
fixed: 'left', fixed: 'left',
}, #foreach($field in ${table.fields})#if("$!field.propertyName" != "id"){ }, #foreach($field in ${table.fields})#if("$!field.propertyName" != "id"){
@@ -15,6 +15,7 @@ const columns = [
slotName: '${field.propertyName}', slotName: '${field.propertyName}',
align: 'left', align: 'left',
#if(${field.propertyType} == 'String') #if(${field.propertyType} == 'String')
minWidth: 238,
ellipsis: true, ellipsis: true,
tooltip: true, tooltip: true,
#elseif(${field.propertyType} == 'Date') #elseif(${field.propertyType} == 'Date')

View File

@@ -1,12 +0,0 @@
### 查询当前用户已授权的主机
GET {{baseUrl}}/asset/authorized-data/current-host
Authorization: {{token}}
### 查询当前用户已授权的主机密钥
GET {{baseUrl}}/asset/authorized-data/current-host-key
Authorization: {{token}}
### 查询当前用户已授权的主机身份
GET {{baseUrl}}/asset/authorized-data/current-host-identity
Authorization: {{token}}

View File

@@ -1,50 +0,0 @@
### 主机分组授权
PUT {{baseUrl}}/asset/data-grant/grant-host-group
Content-Type: application/json
Authorization: {{token}}
{
"userId": 10,
"idList": [
3,
5
]
}
### 获取已授权的主机分组
GET {{baseUrl}}/asset/data-grant/get-host-group?userId=10
Authorization: {{token}}
### 主机密钥授权
PUT {{baseUrl}}/asset/data-grant/grant-host-key
Content-Type: application/json
Authorization: {{token}}
{
"userId": 10,
"idList": [
2,
3
]
}
### 获取已授权的主机密钥
GET {{baseUrl}}/asset/data-grant/get-host-key?userId=10
Authorization: {{token}}
### 主机身份授权
PUT {{baseUrl}}/asset/data-grant/grant-host-identity
Content-Type: application/json
Authorization: {{token}}
{
"userId": 10,
"idList": [
3,
5
]
}
### 获取已授权的主机身份
GET {{baseUrl}}/asset/data-grant/get-host-identity?userId=10
Authorization: {{token}}

View File

@@ -1,36 +0,0 @@
### 创建命令片段
POST {{baseUrl}}/asset/command-snippet/create
Content-Type: application/json
Authorization: {{token}}
{
"groupId": "",
"name": "",
"command": ""
}
### 更新命令片段
PUT {{baseUrl}}/asset/command-snippet/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"groupId": "",
"name": "",
"command": ""
}
### 查询全部命令片段
GET {{baseUrl}}/asset/command-snippet/list
Authorization: {{token}}
### 删除命令片段
DELETE {{baseUrl}}/asset/command-snippet/delete?id=1
Authorization: {{token}}
###

View File

@@ -29,7 +29,6 @@ import javax.annotation.Resource;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/command-snippet") @RequestMapping("/asset/command-snippet")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class CommandSnippetController { public class CommandSnippetController {
@Resource @Resource

View File

@@ -1,32 +0,0 @@
### 创建命令片段分组
POST {{baseUrl}}/asset/command-snippet-group/create
Content-Type: application/json
Authorization: {{token}}
{
"name": ""
}
### 更新命令片段分组
PUT {{baseUrl}}/asset/command-snippet-group/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": ""
}
### 查询全部命令片段分组
GET {{baseUrl}}/asset/command-snippet-group/list
Authorization: {{token}}
### 删除命令片段分组
DELETE {{baseUrl}}/asset/command-snippet-group/delete?id=1
Authorization: {{token}}
###

View File

@@ -31,7 +31,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/command-snippet-group") @RequestMapping("/asset/command-snippet-group")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class CommandSnippetGroupController { public class CommandSnippetGroupController {
@Resource @Resource

View File

@@ -1,25 +0,0 @@
### 批量执行命令
POST {{baseUrl}}/asset/exec-command/exec
Content-Type: application/json
Authorization: {{token}}
{
"description": 1,
"timeout": 10,
"scriptExec": 0,
"command": "echo 这是日志@{{ hostAddress }}\nsleep 1\necho @{{ hostName }}",
"parameterSchema": "[]",
"hostIdList": [1]
}
### 批量执行命令
POST {{baseUrl}}/asset/exec-command/re-exec
Content-Type: application/json
Authorization: {{token}}
{
"logId": 1
}
###

View File

@@ -33,7 +33,6 @@ import javax.annotation.Resource;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/exec-command") @RequestMapping("/asset/exec-command")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class ExecCommandController { public class ExecCommandController {
@Resource @Resource

View File

@@ -1,58 +0,0 @@
### 查询批量执行日志
GET {{baseUrl}}/asset/exec-command-log/get?id=1
Authorization: {{token}}
### 分页查询批量执行日志
POST {{baseUrl}}/asset/exec-command-log/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"id": "",
"userId": "",
"username": "",
"description": "",
"command": "",
"status": ""
}
### 删除批量执行日志
DELETE {{baseUrl}}/asset/exec-command-log/delete?id=1
Authorization: {{token}}
### 批量删除批量执行日志
DELETE {{baseUrl}}/asset/exec-command-log/batch-delete?idList=1,2,3
Authorization: {{token}}
### 查看执行日志
POST {{baseUrl}}/asset/exec-command-log/tail
Content-Type: application/json
Authorization: {{token}}
{
"execId": 56
}
### 下载批量执行日志文件
GET {{baseUrl}}/asset/exec-command-log/download?id=83
Authorization: {{token}}
### 中断批量执行命令
POST {{baseUrl}}/asset/exec-command-log/interrupt
Content-Type: application/json
Authorization: {{token}}
{
"logId": 7
}
###

View File

@@ -43,7 +43,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/exec-command-log") @RequestMapping("/asset/exec-command-log")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class ExecCommandLogController { public class ExecCommandLogController {
private static final String SOURCE = ExecSourceEnum.BATCH.name(); private static final String SOURCE = ExecSourceEnum.BATCH.name();

View File

@@ -1,74 +0,0 @@
### 创建计划任务
POST {{baseUrl}}/asset/exec-job/create
Content-Type: application/json
Authorization: {{token}}
{
"name": "测试 1",
"expression": "0 */3 * * * ?",
"timeout": 0,
"scriptExec": 0,
"command": "echo 123",
"parameterSchema": "[]",
"hostIdList": [
1
]
}
### 更新计划任务
PUT {{baseUrl}}/asset/exec-job/update
Content-Type: application/json
Authorization: {{token}}
{
"id": 5,
"name": "测试 1",
"expression": "0 */10 * * * ?",
"timeout": 0,
"scriptExec": 0,
"command": "echo 123",
"parameterSchema": "[]",
"hostIdList": [
1
]
}
### 更新计划任务状态
PUT {{baseUrl}}/asset/exec-job/update-status
Content-Type: application/json
Authorization: {{token}}
{
"id": 5,
"status": 0
}
### 查询计划任务
GET {{baseUrl}}/asset/exec-job/get?id=1
Authorization: {{token}}
### 分页查询计划任务
POST {{baseUrl}}/asset/exec-job/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"id": "",
"name": "",
"command": "",
"status": ""
}
### 删除计划任务
DELETE {{baseUrl}}/asset/exec-job/delete?id=1
Authorization: {{token}}
###

View File

@@ -34,7 +34,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/exec-job") @RequestMapping("/asset/exec-job")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class ExecJobController { public class ExecJobController {
@Resource @Resource

View File

@@ -1,57 +0,0 @@
### 查询计划任务日志
GET {{baseUrl}}/asset/exec-job-log/get?id=1
Authorization: {{token}}
### 分页查询计划任务日志
POST {{baseUrl}}/asset/exec-job-log/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"id": "",
"userId": "",
"username": "",
"description": "",
"command": "",
"status": ""
}
### 删除计划任务日志
DELETE {{baseUrl}}/asset/exec-job-log/delete?id=1
Authorization: {{token}}
### 批量删除计划任务日志
DELETE {{baseUrl}}/asset/exec-job-log/batch-delete?idList=1,2,3
Authorization: {{token}}
### 查看计划任务日志
POST {{baseUrl}}/asset/exec-job-log/tail
Content-Type: application/json
Authorization: {{token}}
{
"execId": 56
}
### 下载计划任务日志文件
GET {{baseUrl}}/asset/exec-job-log/download?id=83
Authorization: {{token}}
### 中断计划任务命令
POST {{baseUrl}}/asset/exec-command-log/interrupt
Content-Type: application/json
Authorization: {{token}}
{
"logId": 7
}
###

View File

@@ -42,7 +42,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/exec-job-log") @RequestMapping("/asset/exec-job-log")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class ExecJobLogController { public class ExecJobLogController {
private static final String SOURCE = ExecSourceEnum.JOB.name(); private static final String SOURCE = ExecSourceEnum.JOB.name();

View File

@@ -1,63 +0,0 @@
### 创建执行模板
POST {{baseUrl}}/asset/exec-template/create
Content-Type: application/json
Authorization: {{token}}
{
"name": "",
"command": "",
"timeout": 0,
"scriptExec": 0,
"parameterSchema": ""
}
### 更新执行模板
PUT {{baseUrl}}/asset/exec-template/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": "",
"command": "",
"timeout": 0,
"scriptExec": 0,
"parameterSchema": ""
}
### 查询执行模板
GET {{baseUrl}}/asset/exec-template/get?id=1
Authorization: {{token}}
### 查询全部执行模板
GET {{baseUrl}}/asset/exec-template/list
Content-Type: application/json
Authorization: {{token}}
### 分页查询执行模板
POST {{baseUrl}}/asset/exec-template/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"id": "",
"name": "",
"command": "",
"timeout": 0,
"scriptExec": 0,
"parameterSchema": ""
}
### 删除执行模板
DELETE {{baseUrl}}/asset/exec-template/delete?id=1
Authorization: {{token}}
###

View File

@@ -36,7 +36,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/exec-template") @RequestMapping("/asset/exec-template")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class ExecTemplateController { public class ExecTemplateController {
@Resource @Resource

View File

@@ -1,31 +0,0 @@
### 查询主机配置
GET {{baseUrl}}/asset/host-config/get?hostId=1&type=SSH
Authorization: {{token}}
### 查询全部主机配置
GET {{baseUrl}}/asset/host-config/list?hostId=1
Authorization: {{token}}
### 通过 id 更新主机配置
PUT {{baseUrl}}/asset/host-config/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"config": "",
"version": ""
}
### 通过 id 更新主机配置状态
PUT {{baseUrl}}/asset/host-config/update-status
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"status": "",
"version": ""
}
###

View File

@@ -1,82 +0,0 @@
package com.orion.visor.module.asset.controller;
import com.orion.visor.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.define.operator.HostOperatorType;
import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateRequest;
import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateStatusRequest;
import com.orion.visor.module.asset.entity.vo.HostConfigVO;
import com.orion.visor.module.asset.service.HostConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 主机配置 api
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023-9-11 14:16
*/
@Tag(name = "asset - 主机配置服务")
@Slf4j
@Validated
@RestWrapper
@RestController
@RequestMapping("/asset/host-config")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostConfigController {
@Resource
private HostConfigService hostConfigService;
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/get")
@Operation(summary = "查询主机配置")
@Parameter(name = "hostId", description = "hostId", required = true)
@Parameter(name = "type", description = "配置类型", required = true)
@PreAuthorize("@ss.hasPermission('asset:host:query')")
public HostConfigVO getHostConfig(@RequestParam("hostId") Long hostId,
@RequestParam(name = "type") String type) {
return hostConfigService.getHostConfig(hostId, type);
}
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/list")
@Operation(summary = "查询全部主机配置")
@Parameter(name = "hostId", description = "hostId", required = true)
@PreAuthorize("@ss.hasPermission('asset:host:query')")
public List<HostConfigVO> getHostConfigList(@RequestParam("hostId") Long hostId) {
return hostConfigService.getHostConfigList(hostId);
}
@DemoDisableApi
@OperatorLog(HostOperatorType.UPDATE_CONFIG)
@PutMapping("/update")
@Operation(summary = "更新主机配置")
@PreAuthorize("@ss.hasPermission('asset:host:update-config')")
public Integer updateHostConfig(@Validated @RequestBody HostConfigUpdateRequest request) {
return hostConfigService.updateHostConfig(request);
}
@DemoDisableApi
@OperatorLog(HostOperatorType.UPDATE_CONFIG_STATUS)
@PutMapping("/update-status")
@Operation(summary = "更新主机配置状态/动态初始化配置")
@PreAuthorize("@ss.hasPermission('asset:host:update-config')")
public Integer updateHostConfigStatus(@Validated @RequestBody HostConfigUpdateStatusRequest request) {
return hostConfigService.updateHostConfigStatus(request);
}
}

View File

@@ -1,31 +0,0 @@
### 分页查询主机连接日志
POST {{baseUrl}}/asset/host-connect-log/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"userId": "",
"hostId": "",
"type": "",
"token": "",
"status": "",
"startTimeRange": [
"",
""
]
}
### 查询用户最近连接的 ssh 主机
POST {{baseUrl}}/asset/host-connect-log/latest-connect
Content-Type: application/json
Authorization: {{token}}
{
"limit": 10,
"type": "SSH"
}
###

View File

@@ -36,7 +36,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/host-connect-log") @RequestMapping("/asset/host-connect-log")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostConnectLogController { public class HostConnectLogController {
@Resource @Resource

View File

@@ -1,56 +0,0 @@
### 创建主机
POST {{baseUrl}}/asset/host/create
Content-Type: application/json
Authorization: {{token}}
{
"name": "",
"code": "",
"address": ""
}
### 通过 id 更新主机
PUT {{baseUrl}}/asset/host/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": "",
"code": "",
"address": ""
}
### 通过 id 查询主机
GET {{baseUrl}}/asset/host/get?id=1&extra=true&config=true
Authorization: {{token}}
### 查询主机
GET {{baseUrl}}/asset/host/list
Authorization: {{token}}
### 分页查询主机
POST {{baseUrl}}/asset/host/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"id": "",
"name": "",
"code": "",
"address": ""
}
### 通过 id 删除主机
DELETE {{baseUrl}}/asset/host/delete?id=1
Authorization: {{token}}
###

View File

@@ -8,9 +8,8 @@ import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.DemoDisableApi; import com.orion.visor.framework.web.core.annotation.DemoDisableApi;
import com.orion.visor.framework.web.core.annotation.RestWrapper; import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.define.operator.HostOperatorType; import com.orion.visor.module.asset.define.operator.HostOperatorType;
import com.orion.visor.module.asset.entity.request.host.HostCreateRequest; import com.orion.visor.module.asset.entity.request.host.*;
import com.orion.visor.module.asset.entity.request.host.HostQueryRequest; import com.orion.visor.module.asset.entity.vo.HostConfigVO;
import com.orion.visor.module.asset.entity.request.host.HostUpdateRequest;
import com.orion.visor.module.asset.entity.vo.HostVO; import com.orion.visor.module.asset.entity.vo.HostVO;
import com.orion.visor.module.asset.service.HostService; import com.orion.visor.module.asset.service.HostService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@@ -37,7 +36,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/host") @RequestMapping("/asset/host")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostController { public class HostController {
@Resource @Resource
@@ -61,6 +59,24 @@ public class HostController {
return hostService.updateHostById(request); return hostService.updateHostById(request);
} }
@DemoDisableApi
@OperatorLog(HostOperatorType.UPDATE_STATUS)
@PutMapping("/update-status")
@Operation(summary = "更新主机状态")
@PreAuthorize("@ss.hasPermission('asset:host:update-status')")
public Integer updateHostStatus(@Validated @RequestBody HostUpdateStatusRequest request) {
return hostService.updateHostStatus(request);
}
@DemoDisableApi
@OperatorLog(HostOperatorType.UPDATE_CONFIG)
@PutMapping("/update-config")
@Operation(summary = "更新主机配置")
@PreAuthorize("@ss.hasPermission('asset:host:update-config')")
public Integer updateHostConfig(@Validated @RequestBody HostUpdateConfigRequest request) {
return hostService.updateHostConfig(request);
}
@IgnoreLog(IgnoreLogMode.RET) @IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "通过 id 查询主机") @Operation(summary = "通过 id 查询主机")
@@ -70,12 +86,22 @@ public class HostController {
return hostService.getHostById(id); return hostService.getHostById(id);
} }
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/get-config")
@Operation(summary = "查询主机配置")
@Parameter(name = "id", description = "id", required = true)
@PreAuthorize("@ss.hasPermission('asset:host:query')")
public HostConfigVO getHostConfig(@RequestParam("id") Long id) {
return hostService.getHostConfig(id);
}
@IgnoreLog(IgnoreLogMode.RET) @IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/list") @GetMapping("/list")
@Operation(summary = "查询主机") @Operation(summary = "查询主机")
@Parameter(name = "type", description = "type", required = false)
@PreAuthorize("@ss.hasPermission('asset:host:query')") @PreAuthorize("@ss.hasPermission('asset:host:query')")
public List<HostVO> getHostList() { public List<HostVO> getHostList(@RequestParam(value = "type", required = false) String type) {
return hostService.getHostListByCache(); return hostService.getHostList(type);
} }
@IgnoreLog(IgnoreLogMode.RET) @IgnoreLog(IgnoreLogMode.RET)

View File

@@ -1,28 +0,0 @@
### 获取主机拓展信息
GET {{baseUrl}}/asset/host-extra/get?hostId=1&item=ssh
Authorization: {{token}}
### 获取多个主机拓展信息
POST {{baseUrl}}/asset/host-extra/list
Content-Type: application/json
Authorization: {{token}}
{
"hostId": 1,
"items": [
"ssh"
]
}
### 修改主机拓展信息
PUT {{baseUrl}}/asset/host-extra/update
Content-Type: application/json
Authorization: {{token}}
{
"hostId": 1,
"item": "ssh",
"extra": "{\"authType\":\"DEFAULT\"}"
}
###

View File

@@ -29,7 +29,6 @@ import java.util.Map;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/host-extra") @RequestMapping("/asset/host-extra")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostExtraController { public class HostExtraController {
@Resource @Resource

View File

@@ -1,44 +0,0 @@
### 创建主机分组
POST {{baseUrl}}/asset/host-group/create
Content-Type: application/json
Authorization: {{token}}
{
"parentId": -1,
"name": ""
}
### 查询主机分组
GET {{baseUrl}}/asset/host-group/tree
Authorization: {{token}}
### 修改名称
PUT {{baseUrl}}/asset/host-group/rename
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": ""
}
### 移动位置
PUT {{baseUrl}}/asset/host-group/move
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"targetId": "",
"position": ""
}
### 删除主机分组
DELETE {{baseUrl}}/asset/host-group/delete?id=1
Authorization: {{token}}
###

View File

@@ -37,7 +37,6 @@ import java.util.Set;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/host-group") @RequestMapping("/asset/host-group")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostGroupController { public class HostGroupController {
@Resource @Resource

View File

@@ -1,57 +0,0 @@
### 创建主机身份
POST {{baseUrl}}/asset/host-identity/create
Content-Type: application/json
Authorization: {{token}}
{
"name": "",
"username": "",
"password": "",
"keyId": ""
}
### 通过 id 更新主机身份
PUT {{baseUrl}}/asset/host-identity/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": "",
"username": "",
"password": "",
"keyId": ""
}
### 通过 id 查询主机身份
GET {{baseUrl}}/asset/host-identity/get?id=1
Authorization: {{token}}
### 通过 id 批量查询主机身份
GET {{baseUrl}}/asset/host-identity/list
Authorization: {{token}}
### 分页查询主机身份
POST {{baseUrl}}/asset/host-identity/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"id": "",
"name": "",
"username": "",
"password": "",
"keyId": ""
}
### 通过 id 删除主机身份
DELETE {{baseUrl}}/asset/host-identity/delete?id=1
Authorization: {{token}}

View File

@@ -37,7 +37,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/host-identity") @RequestMapping("/asset/host-identity")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostIdentityController { public class HostIdentityController {
@Resource @Resource

View File

@@ -1,66 +0,0 @@
### 创建主机密钥
POST {{baseUrl}}/asset/host-key/create
Content-Type: application/json
Authorization: {{token}}
{
"name": "",
"publicKey": "",
"privateKey": "",
"password": ""
}
### 通过 id 更新主机密钥
PUT {{baseUrl}}/asset/host-key/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": "",
"publicKey": "",
"privateKey": "",
"password": ""
}
### 通过 id 查询主机密钥
GET {{baseUrl}}/asset/host-key/get?id=1
Authorization: {{token}}
### 查询主机密钥
POST {{baseUrl}}/asset/host-key/list
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": "",
"publicKey": "",
"privateKey": "",
"password": ""
}
### 分页查询主机密钥
POST {{baseUrl}}/asset/host-key/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"id": "",
"name": "",
"publicKey": "",
"privateKey": "",
"password": ""
}
### 通过 id 删除主机密钥
DELETE {{baseUrl}}/asset/host-key/delete?id=1
Authorization: {{token}}
###

View File

@@ -37,7 +37,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/host-key") @RequestMapping("/asset/host-key")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostKeyController { public class HostKeyController {
@Resource @Resource

View File

@@ -1,21 +0,0 @@
### 分页查询 SFTP 操作日志
POST {{baseUrl}}/asset/host-sftp/query-log
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10
}
### 删除 SFTP 操作日志
DELETE {{baseUrl}}/asset/host-sftp/delete-log?idList=1,2,3
Authorization: {{token}}
### 下载文件
GET {{baseUrl}}/asset/host-sftp/download?channelId=123&transferToken=123
###

View File

@@ -38,7 +38,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/host-sftp") @RequestMapping("/asset/host-sftp")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostSftpLogController { public class HostSftpLogController {
@Resource @Resource

View File

@@ -1,11 +0,0 @@
### 获取主机终端主题
GET {{baseUrl}}/asset/host-terminal/themes
Authorization: {{token}}
### 获取主机终端连接 token
GET {{baseUrl}}/asset/host-terminal/access
Authorization: {{token}}
###

View File

@@ -1,9 +1,9 @@
package com.orion.visor.module.asset.controller; package com.orion.visor.module.asset.controller;
import com.alibaba.fastjson.JSONArray;
import com.orion.visor.framework.log.core.annotation.IgnoreLog; import com.orion.visor.framework.log.core.annotation.IgnoreLog;
import com.orion.visor.framework.log.core.enums.IgnoreLogMode; import com.orion.visor.framework.log.core.enums.IgnoreLogMode;
import com.orion.visor.framework.web.core.annotation.RestWrapper; import com.orion.visor.framework.web.core.annotation.RestWrapper;
import com.orion.visor.module.asset.entity.vo.HostTerminalThemeVO;
import com.orion.visor.module.asset.service.HostTerminalService; import com.orion.visor.module.asset.service.HostTerminalService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List;
/** /**
* 主机终端 api * 主机终端 api
@@ -29,7 +30,6 @@ import javax.annotation.Resource;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/host-terminal") @RequestMapping("/asset/host-terminal")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class HostTerminalController { public class HostTerminalController {
@Resource @Resource
@@ -38,7 +38,7 @@ public class HostTerminalController {
@IgnoreLog(IgnoreLogMode.ALL) @IgnoreLog(IgnoreLogMode.ALL)
@GetMapping("/themes") @GetMapping("/themes")
@Operation(summary = "获取主机终端主题") @Operation(summary = "获取主机终端主题")
public JSONArray getTerminalThemes() { public List<HostTerminalThemeVO> getTerminalThemes() {
return hostTerminalService.getTerminalThemes(); return hostTerminalService.getTerminalThemes();
} }

View File

@@ -1,34 +0,0 @@
### 创建路径标签
POST {{baseUrl}}/asset/path-bookmark/create
Content-Type: application/json
Authorization: {{token}}
{
"name": "",
"path": ""
}
### 更新路径标签
PUT {{baseUrl}}/asset/path-bookmark/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": "",
"path": ""
}
### 查询全部路径标签
GET {{baseUrl}}/asset/path-bookmark/list
Authorization: {{token}}
### 删除路径标签
DELETE {{baseUrl}}/asset/path-bookmark/delete?id=1
Authorization: {{token}}
###

View File

@@ -27,7 +27,6 @@ import javax.annotation.Resource;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/path-bookmark") @RequestMapping("/asset/path-bookmark")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class PathBookmarkController { public class PathBookmarkController {
@Resource @Resource

View File

@@ -1,32 +0,0 @@
### 创建路径标签分组
POST {{baseUrl}}/asset/path-bookmark-group/create
Content-Type: application/json
Authorization: {{token}}
{
"name": ""
}
### 更新路径标签分组
PUT {{baseUrl}}/asset/path-bookmark-group/update
Content-Type: application/json
Authorization: {{token}}
{
"id": "",
"name": ""
}
### 查询全部路径标签分组
GET {{baseUrl}}/asset/path-bookmark-group/list
Authorization: {{token}}
### 删除路径标签分组
DELETE {{baseUrl}}/asset/path-bookmark-group/delete?id=1
Authorization: {{token}}
###

View File

@@ -31,7 +31,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/path-bookmark-group") @RequestMapping("/asset/path-bookmark-group")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class PathBookmarkGroupController { public class PathBookmarkGroupController {
@Resource @Resource

View File

@@ -1,68 +0,0 @@
### 创建上传任务
POST {{baseUrl}}/asset/upload-task/create
Content-Type: application/json
Authorization: {{token}}
{
"remotePath": "/root/batch",
"description": "",
"hostIdList": [
1,
7,
8
],
"files": [
{
"fileId": "1",
"filePath": "qr.txt",
"fileSize": 3
},
{
"fileId": "2",
"filePath": "dir/key.txt",
"fileSize": 3
}
]
}
### 开始上传
POST {{baseUrl}}/asset/upload-task/start
Content-Type: application/json
Authorization: {{token}}
{
"id": 1
}
### 查询上传任务
GET {{baseUrl}}/asset/upload-task/get?id=1
Authorization: {{token}}
### 分页查询上传任务
POST {{baseUrl}}/asset/upload-task/query
Content-Type: application/json
Authorization: {{token}}
{
"page": 1,
"limit": 10,
"id": "",
"userId": "",
"description": "",
"status": ""
}
### 删除上传任务
DELETE {{baseUrl}}/asset/upload-task/delete?id=1
Authorization: {{token}}
### 批量删除上传任务
DELETE {{baseUrl}}/asset/upload-task/batch-delete?idList=1,2,3
Authorization: {{token}}
###

View File

@@ -38,7 +38,6 @@ import java.util.List;
@RestWrapper @RestWrapper
@RestController @RestController
@RequestMapping("/asset/upload-task") @RequestMapping("/asset/upload-task")
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
public class UploadTaskController { public class UploadTaskController {
@Resource @Resource

View File

@@ -1,27 +0,0 @@
package com.orion.visor.module.asset.convert;
import com.orion.visor.module.asset.entity.domain.HostConfigDO;
import com.orion.visor.module.asset.entity.request.host.HostConfigUpdateRequest;
import com.orion.visor.module.asset.entity.vo.HostConfigVO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
/**
* 主机配置 内部对象转换器
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023-9-11 14:16
*/
@Mapper
public interface HostConfigConvert {
HostConfigConvert MAPPER = Mappers.getMapper(HostConfigConvert.class);
@Mapping(target = "config", ignore = true)
HostConfigVO to(HostConfigDO domain);
HostConfigDO to(HostConfigUpdateRequest request);
}

View File

@@ -1,111 +0,0 @@
package com.orion.visor.module.asset.dao;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.visor.framework.mybatis.core.mapper.IMapper;
import com.orion.visor.module.asset.entity.domain.HostConfigDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 主机配置 Mapper 接口
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023-9-11 14:16
*/
@Mapper
public interface HostConfigDAO extends IMapper<HostConfigDO> {
/**
* 通过 hostId 查询主机配置
*
* @param hostId hostId
* @param type type
* @return row
*/
default HostConfigDO getHostConfigByHostId(Long hostId, String type) {
// 条件
LambdaQueryWrapper<HostConfigDO> wrapper = this.lambda()
.eq(HostConfigDO::getHostId, hostId)
.eq(HostConfigDO::getType, type);
// 查询
return this.of(wrapper).getOne();
}
/**
* 通过 hostId 查询主机配置
*
* @param hostId hostId
* @return rows
*/
default List<HostConfigDO> getHostConfigByHostId(Long hostId) {
// 条件
LambdaQueryWrapper<HostConfigDO> wrapper = this.lambda()
.eq(HostConfigDO::getHostId, hostId);
// 查询
return this.of(wrapper).list();
}
/**
* 通过 hostId 批量查询主机配置
*
* @param hostIdList hostIdList
* @param type type
* @return rows
*/
default List<HostConfigDO> getHostConfigByHostIdList(List<Long> hostIdList, String type) {
// 条件
LambdaQueryWrapper<HostConfigDO> wrapper = this.wrapper()
.eq(HostConfigDO::getType, type)
.in(HostConfigDO::getHostId, hostIdList);
// 查询
return this.of(wrapper).list();
}
/**
* 通过 hostId 删除主机配置
*
* @param hostId hostId
* @return effect
*/
default Integer deleteByHostId(Long hostId) {
// 条件
LambdaQueryWrapper<HostConfigDO> wrapper = this.lambda()
.eq(HostConfigDO::getHostId, hostId);
// 删除
return this.delete(wrapper);
}
/**
* 通过 hostId 批量删除主机配置
*
* @param hostIdList hostIdList
* @return effect
*/
default Integer deleteByHostIdList(List<Long> hostIdList) {
// 条件
LambdaQueryWrapper<HostConfigDO> wrapper = this.lambda()
.in(HostConfigDO::getHostId, hostIdList);
// 删除
return this.delete(wrapper);
}
/**
* 设置 keyId 为 NULL
*
* @param keyIdList keyIdList
* @return effect
*/
int setKeyIdWithNull(@Param("keyIdList") List<Long> keyIdList);
/**
* 设置 identityId 为 NULL
*
* @param identityIdList identityIdList
* @return effect
*/
int setIdentityIdWithNull(@Param("identityIdList") List<Long> identityIdList);
}

View File

@@ -1,8 +1,13 @@
package com.orion.visor.module.asset.dao; package com.orion.visor.module.asset.dao;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.orion.visor.framework.mybatis.core.mapper.IMapper; import com.orion.visor.framework.mybatis.core.mapper.IMapper;
import com.orion.visor.module.asset.entity.domain.HostDO; import com.orion.visor.module.asset.entity.domain.HostDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Arrays;
import java.util.List;
/** /**
* 主机 Mapper 接口 * 主机 Mapper 接口
@@ -14,4 +19,83 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper @Mapper
public interface HostDAO extends IMapper<HostDO> { public interface HostDAO extends IMapper<HostDO> {
List<SFunction<HostDO, ?>> BASE_COLUMN = Arrays.asList(
HostDO::getId,
HostDO::getType,
HostDO::getName,
HostDO::getCode,
HostDO::getAddress,
HostDO::getPort,
HostDO::getStatus,
HostDO::getCreateTime,
HostDO::getUpdateTime,
HostDO::getCreator,
HostDO::getUpdater
);
/**
* 通过 id 查询基本信息
*
* @param id id
* @return id
*/
default HostDO selectBaseById(Long id) {
return this.of()
.createWrapper()
.select(BASE_COLUMN)
.eq(HostDO::getId, id)
.then()
.getOne();
}
/**
* 通过 id 查询基本信息
*
* @param idList idList
* @return id
*/
default List<HostDO> selectBaseByIdList(List<Long> idList) {
return this.of()
.createWrapper()
.select(BASE_COLUMN)
.in(HostDO::getId, idList)
.then()
.list();
}
/**
* 获取的 hostId
*
* @param hostIdList hostIdList
* @param type type
* @param status status
* @return hostId
*/
default List<Long> getHostIdList(List<Long> hostIdList, String type, String status) {
return this.of()
.createWrapper(true)
.select(HostDO::getId)
.in(HostDO::getId, hostIdList)
.eq(HostDO::getType, type)
.eq(HostDO::getStatus, status)
.then()
.list(HostDO::getId);
}
/**
* 设置 keyId 为 NULL
*
* @param keyIdList keyIdList
* @return effect
*/
int setKeyIdWithNull(@Param("keyIdList") List<Long> keyIdList);
/**
* 设置 identityId 为 NULL
*
* @param identityIdList identityIdList
* @return effect
*/
int setIdentityIdWithNull(@Param("identityIdList") List<Long> identityIdList);
} }

View File

@@ -19,8 +19,8 @@ import java.util.concurrent.TimeUnit;
public interface HostCacheKeyDefine { public interface HostCacheKeyDefine {
CacheKeyDefine HOST_INFO = new CacheKeyBuilder() CacheKeyDefine HOST_INFO = new CacheKeyBuilder()
.key("host:info:list") .key("host:info:list:{}")
.desc("主机列表") .desc("主机列表 ${type}")
.type(HostCacheDTO.class) .type(HostCacheDTO.class)
.struct(RedisCacheStruct.HASH) .struct(RedisCacheStruct.HASH)
.timeout(8, TimeUnit.HOURS) .timeout(8, TimeUnit.HOURS)

View File

@@ -22,9 +22,9 @@ public class HostOperatorType extends InitializingOperatorTypes {
public static final String DELETE = "host:delete"; public static final String DELETE = "host:delete";
public static final String UPDATE_CONFIG = "host:update-config"; public static final String UPDATE_STATUS = "host:update-status";
public static final String UPDATE_CONFIG_STATUS = "host:update-config-status"; public static final String UPDATE_CONFIG = "host:update-config";
@Override @Override
public OperatorType[] types() { public OperatorType[] types() {
@@ -32,8 +32,8 @@ public class HostOperatorType extends InitializingOperatorTypes {
new OperatorType(L, CREATE, "创建主机 <sb>${name}</sb>"), new OperatorType(L, CREATE, "创建主机 <sb>${name}</sb>"),
new OperatorType(L, UPDATE, "修改主机 <sb>${name}</sb>"), new OperatorType(L, UPDATE, "修改主机 <sb>${name}</sb>"),
new OperatorType(H, DELETE, "删除主机 <sb>${name}</sb>"), new OperatorType(H, DELETE, "删除主机 <sb>${name}</sb>"),
new OperatorType(M, UPDATE_CONFIG, "修改主机配置 <sb>${name}</sb> | <sb>${type}</sb>"), new OperatorType(M, UPDATE_STATUS, "修改主机状态 <sb>${name}</sb> - <sb>${status}</sb>"),
new OperatorType(M, UPDATE_CONFIG_STATUS, "修改主机配置状态 <sb>${name}</sb> | <sb>${type}</sb> - <sb>${statusName}</sb>"), new OperatorType(M, UPDATE_CONFIG, "修改主机配置 <sb>${name}</sb>"),
}; };
} }

View File

@@ -1,51 +0,0 @@
package com.orion.visor.module.asset.entity.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.orion.visor.framework.mybatis.core.domain.BaseDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
/**
* 主机配置 实体对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023-9-11 14:16
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName(value = "host_config", autoResultMap = true)
@Schema(name = "HostConfigDO", description = "主机配置 实体对象")
public class HostConfigDO extends BaseDO {
private static final long serialVersionUID = 1L;
@Schema(description = "id")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@Schema(description = "主机id")
@TableField("host_id")
private Long hostId;
@Schema(description = "配置类型")
@TableField("type")
private String type;
@Schema(description = "状态 0停用 1启用")
@TableField("status")
private Integer status;
@Schema(description = "配置详情")
@TableField("config")
private String config;
@Schema(description = "配置版本号")
@TableField("version")
@Version
private Integer version;
}

View File

@@ -30,6 +30,10 @@ public class HostDO extends BaseDO {
@TableId(value = "id", type = IdType.AUTO) @TableId(value = "id", type = IdType.AUTO)
private Long id; private Long id;
@Schema(description = "主机类型")
@TableField("type")
private String type;
@Schema(description = "主机名称") @Schema(description = "主机名称")
@TableField("name") @TableField("name")
private String name; private String name;
@@ -42,4 +46,16 @@ public class HostDO extends BaseDO {
@TableField("address") @TableField("address")
private String address; private String address;
@Schema(description = "主机端口")
@TableField("port")
private Integer port;
@Schema(description = "主机状态")
@TableField("status")
private String status;
@Schema(description = "主机配置")
@TableField("config")
private String config;
} }

View File

@@ -20,16 +20,13 @@ import lombok.NoArgsConstructor;
@Schema(name = "ExecParameterSchemaDTO", description = "命令执行参数 schema 对象") @Schema(name = "ExecParameterSchemaDTO", description = "命令执行参数 schema 对象")
public class ExecParameterSchemaDTO { public class ExecParameterSchemaDTO {
@Schema(description = "参数名") @Schema(description = "参数名")
private String name; private String name;
@Schema(description = "参数描述") @Schema(description = "参数描述")
private String desc; private String desc;
@Schema(description = "默认") @Schema(description = "参数")
private Object defaultValue;
@Schema(description = "")
private Object value; private Object value;
} }

View File

@@ -26,6 +26,9 @@ public class HostCacheDTO implements LongCacheIdModel, Serializable {
@Schema(description = "id") @Schema(description = "id")
private Long id; private Long id;
@Schema(description = "主机类型")
private String type;
@Schema(description = "主机名称") @Schema(description = "主机名称")
private String name; private String name;
@@ -35,4 +38,10 @@ public class HostCacheDTO implements LongCacheIdModel, Serializable {
@Schema(description = "主机地址") @Schema(description = "主机地址")
private String address; private String address;
@Schema(description = "主机端口")
private Integer port;
@Schema(description = "主机状态")
private String status;
} }

View File

@@ -38,12 +38,12 @@ public class HostTerminalConnectDTO {
@Schema(description = "主机地址") @Schema(description = "主机地址")
private String hostAddress; private String hostAddress;
@Schema(description = "主机端口")
private Integer hostPort;
@Schema(description = "系统类型") @Schema(description = "系统类型")
private String osType; private String osType;
@Schema(description = "端口")
private Integer port;
@Schema(description = "超时时间") @Schema(description = "超时时间")
private Integer timeout; private Integer timeout;

View File

@@ -1,31 +0,0 @@
package com.orion.visor.module.asset.entity.request.host;
import com.orion.visor.framework.common.entity.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.Size;
/**
* 主机配置 查询请求对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023-9-13 14:31
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(name = "HostConfigQueryRequest", description = "主机配置 查询请求对象")
public class HostConfigQueryRequest extends PageRequest {
@Schema(description = "主机id")
private Long hostId;
@Size(max = 32)
@Schema(description = "配置类型")
private String type;
}

View File

@@ -1,43 +0,0 @@
package com.orion.visor.module.asset.entity.request.host;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
/**
* 主机配置 更新请求对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023-9-13 14:31
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "HostConfigUpdateRequest", description = "主机配置 更新请求对象")
public class HostConfigUpdateStatusRequest implements Serializable {
@NotNull
@Schema(description = "主机id")
private Long hostId;
@NotNull
@Size(max = 32)
@Schema(description = "配置类型")
private String type;
@NotNull
@Schema(description = "状态 0停用 1启用")
private Integer status;
@Schema(description = "配置版本号")
private Integer version;
}

View File

@@ -5,6 +5,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
@@ -25,6 +26,10 @@ import java.util.List;
@Schema(name = "HostCreateRequest", description = "主机 创建请求对象") @Schema(name = "HostCreateRequest", description = "主机 创建请求对象")
public class HostCreateRequest implements Serializable { public class HostCreateRequest implements Serializable {
@NotBlank
@Schema(description = "主机类型")
private String type;
@NotBlank @NotBlank
@Size(max = 64) @Size(max = 64)
@Schema(description = "主机名称") @Schema(description = "主机名称")
@@ -40,6 +45,10 @@ public class HostCreateRequest implements Serializable {
@Schema(description = "主机地址") @Schema(description = "主机地址")
private String address; private String address;
@Range(min = 1, max = 65535)
@Schema(description = "主机端口")
private Integer port;
@Schema(description = "主机分组") @Schema(description = "主机分组")
private List<Long> groupIdList; private List<Long> groupIdList;

View File

@@ -40,13 +40,18 @@ public class HostQueryRequest extends PageRequest {
@Schema(description = "主机地址") @Schema(description = "主机地址")
private String address; private String address;
@Size(max = 8)
@Schema(description = "主机类型")
private String type;
@Size(max = 8)
@Schema(description = "主机状态")
private String status;
@Schema(description = "tag") @Schema(description = "tag")
private List<Long> tags; private List<Long> tags;
@Schema(description = "是否查询 tag 信息") @Schema(description = "是否查询 tag 信息")
private Boolean queryTag; private Boolean queryTag;
@Schema(description = "是否查询配置信息")
private Boolean queryConfig;
} }

View File

@@ -8,11 +8,10 @@ import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
/** /**
* 主机配置 更新请求对象 * 主机 更新配置请求对象
* *
* @author Jiahang Li * @author Jiahang Li
* @version 1.0.0 * @version 1.0.0
@@ -22,24 +21,15 @@ import java.io.Serializable;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Schema(name = "HostConfigUpdateRequest", description = "主机配置 更新请求对象") @Schema(name = "HostUpdateConfigRequest", description = "主机 更新配置请求对象")
public class HostConfigUpdateRequest implements Serializable { public class HostUpdateConfigRequest implements Serializable {
@NotNull @NotNull
@Schema(description = "主机id") @Schema(description = "id")
private Long hostId; private Long id;
@NotNull
@Size(max = 32)
@Schema(description = "配置类型")
private String type;
@NotBlank @NotBlank
@Schema(description = "配置详情") @Schema(description = "配置详情")
private String config; private String config;
@NotNull
@Schema(description = "配置版本号")
private Integer version;
} }

View File

@@ -5,6 +5,7 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
@@ -45,6 +46,10 @@ public class HostUpdateRequest implements Serializable {
@Schema(description = "主机地址") @Schema(description = "主机地址")
private String address; private String address;
@Range(min = 1, max = 65535)
@Schema(description = "主机端口")
private Integer port;
@Schema(description = "主机分组") @Schema(description = "主机分组")
private List<Long> groupIdList; private List<Long> groupIdList;

View File

@@ -0,0 +1,34 @@
package com.orion.visor.module.asset.entity.request.host;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 主机 更新状态请求对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023-9-13 14:31
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "HostUpdateStatusRequest", description = "主机 更新状态请求对象")
public class HostUpdateStatusRequest implements Serializable {
@NotNull
@Schema(description = "id")
private Long id;
@NotNull
@Schema(description = "状态")
private String status;
}

View File

@@ -69,6 +69,6 @@ public class ExecJobVO implements Serializable {
private List<Long> hostIdList; private List<Long> hostIdList;
@Schema(description = "执行主机") @Schema(description = "执行主机")
private List<HostVO> hostList; private List<HostBaseVO> hostList;
} }

View File

@@ -27,6 +27,9 @@ public class HostBaseVO implements Serializable {
@Schema(description = "id") @Schema(description = "id")
private Long id; private Long id;
@Schema(description = "主机类型")
private String type;
@Schema(description = "主机名称") @Schema(description = "主机名称")
private String name; private String name;
@@ -36,4 +39,7 @@ public class HostBaseVO implements Serializable {
@Schema(description = "主机地址") @Schema(description = "主机地址")
private String address; private String address;
@Schema(description = "主机端口")
private Integer port;
} }

View File

@@ -25,18 +25,9 @@ public class HostConfigVO {
@Schema(description = "id") @Schema(description = "id")
private Long id; private Long id;
@Schema(description = "hostId") @Schema(description = "type")
private Long hostId;
@Schema(description = "version")
private Integer version;
@Schema(description = "配置类型")
private String type; private String type;
@Schema(description = "状态 0停用 1启用")
private Integer status;
@Schema(description = "config") @Schema(description = "config")
private Map<String, Object> config; private Map<String, Object> config;

View File

@@ -0,0 +1,33 @@
package com.orion.visor.module.asset.entity.vo;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 主机终端主题 视图响应对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/7/4 19:27
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "HostTerminalThemeVO", description = "主机终端主题 视图响应对象")
public class HostTerminalThemeVO {
@Schema(description = "主题名称")
private String name;
@Schema(description = "是否为暗色")
private Boolean dark;
@Schema(description = "主题 schema")
private JSONObject schema;
}

View File

@@ -31,6 +31,9 @@ public class HostVO implements Serializable {
@Schema(description = "id") @Schema(description = "id")
private Long id; private Long id;
@Schema(description = "主机类型")
private String type;
@Schema(description = "主机名称") @Schema(description = "主机名称")
private String name; private String name;
@@ -40,6 +43,12 @@ public class HostVO implements Serializable {
@Schema(description = "主机地址") @Schema(description = "主机地址")
private String address; private String address;
@Schema(description = "主机端口")
private Integer port;
@Schema(description = "主机状态")
private String status;
@Schema(description = "创建时间") @Schema(description = "创建时间")
private Date createTime; private Date createTime;

View File

@@ -22,25 +22,23 @@ public enum HostExtraItemEnum implements GenericsDataDefinition {
/** /**
* SSH 额外配置 * SSH 额外配置
*/ */
SSH("ssh", HostSshExtraStrategy.class), SSH(HostSshExtraStrategy.class),
/** /**
* 标签额外配置 * 标签额外配置
*/ */
LABEL("label", HostLabelExtraStrategy.class), LABEL(HostLabelExtraStrategy.class),
; ;
private final String item;
private final Class<? extends GenericsDataStrategy<? extends GenericsDataModel>> strategyClass; private final Class<? extends GenericsDataStrategy<? extends GenericsDataModel>> strategyClass;
public static HostExtraItemEnum of(String type) { public static HostExtraItemEnum of(String item) {
if (type == null) { if (item == null) {
return null; return null;
} }
for (HostExtraItemEnum value : values()) { for (HostExtraItemEnum value : values()) {
if (value.item.equals(type)) { if (value.name().equals(item)) {
return value; return value;
} }
} }

View File

@@ -0,0 +1,36 @@
package com.orion.visor.module.asset.enums;
/**
* 主机状态
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/7/17 16:07
*/
public enum HostStatusEnum {
/**
* 停用
*/
DISABLED,
/**
* 启用
*/
ENABLED,
;
public static HostStatusEnum of(String name) {
if (name == null) {
return null;
}
for (HostStatusEnum value : values()) {
if (value.name().equals(name)) {
return value;
}
}
return null;
}
}

View File

@@ -1,6 +1,5 @@
package com.orion.visor.module.asset.enums; package com.orion.visor.module.asset.enums;
import com.orion.visor.framework.common.enums.EnableStatus;
import com.orion.visor.framework.common.handler.data.GenericsDataDefinition; import com.orion.visor.framework.common.handler.data.GenericsDataDefinition;
import com.orion.visor.framework.common.handler.data.model.GenericsDataModel; import com.orion.visor.framework.common.handler.data.model.GenericsDataModel;
import com.orion.visor.framework.common.handler.data.strategy.GenericsDataStrategy; import com.orion.visor.framework.common.handler.data.strategy.GenericsDataStrategy;
@@ -17,29 +16,23 @@ import lombok.Getter;
*/ */
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum HostConfigTypeEnum implements GenericsDataDefinition { public enum HostTypeEnum implements GenericsDataDefinition {
/** /**
* SSH 配置 * SSH
*/ */
SSH("ssh", SSH(HostSshConfigStrategy.class),
HostSshConfigStrategy.class,
EnableStatus.ENABLED.getValue()),
; ;
private final String type;
private final Class<? extends GenericsDataStrategy<? extends GenericsDataModel>> strategyClass; private final Class<? extends GenericsDataStrategy<? extends GenericsDataModel>> strategyClass;
private final Integer defaultStatus; public static HostTypeEnum of(String type) {
public static HostConfigTypeEnum of(String type) {
if (type == null) { if (type == null) {
return null; return null;
} }
for (HostConfigTypeEnum value : values()) { for (HostTypeEnum value : values()) {
if (value.type.equalsIgnoreCase(type)) { if (value.name().equals(type)) {
return value; return value;
} }
} }

View File

@@ -25,13 +25,6 @@ import javax.validation.constraints.Size;
@AllArgsConstructor @AllArgsConstructor
public class HostSshConfigModel implements GenericsDataModel, UpdatePasswordAction { public class HostSshConfigModel implements GenericsDataModel, UpdatePasswordAction {
/**
* ssh 端口
*/
@NotNull
@Range(min = 1, max = 65535)
private Integer port;
/** /**
* 用户名 * 用户名
*/ */

View File

@@ -34,8 +34,6 @@ public class HostSshConfigStrategy extends AbstractGenericsDataStrategy<HostSshC
@Resource @Resource
private HostIdentityDAO hostIdentityDAO; private HostIdentityDAO hostIdentityDAO;
private static final int SSH_PORT = 22;
private static final String USERNAME = "root"; private static final String USERNAME = "root";
public HostSshConfigStrategy() { public HostSshConfigStrategy() {
@@ -45,7 +43,6 @@ public class HostSshConfigStrategy extends AbstractGenericsDataStrategy<HostSshC
@Override @Override
public HostSshConfigModel getDefault() { public HostSshConfigModel getDefault() {
return HostSshConfigModel.builder() return HostSshConfigModel.builder()
.port(SSH_PORT)
.username(USERNAME) .username(USERNAME)
.authType(HostSshAuthTypeEnum.PASSWORD.name()) .authType(HostSshAuthTypeEnum.PASSWORD.name())
.osType(HostSshOsTypeEnum.LINUX.name()) .osType(HostSshOsTypeEnum.LINUX.name())

View File

@@ -19,10 +19,12 @@ import com.orion.spring.SpringHolder;
import com.orion.visor.framework.common.file.FileClient; import com.orion.visor.framework.common.file.FileClient;
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.enums.ExecHostStatusEnum; import com.orion.visor.module.asset.enums.ExecHostStatusEnum;
import com.orion.visor.module.asset.handler.host.exec.command.model.ExecCommandDTO; import com.orion.visor.module.asset.handler.host.exec.command.model.ExecCommandDTO;
import com.orion.visor.module.asset.handler.host.exec.command.model.ExecCommandHostDTO; import com.orion.visor.module.asset.handler.host.exec.command.model.ExecCommandHostDTO;
import com.orion.visor.module.asset.handler.host.exec.log.manager.ExecLogManager; import com.orion.visor.module.asset.handler.host.exec.log.manager.ExecLogManager;
import com.orion.visor.module.asset.handler.host.jsch.SessionStores;
import com.orion.visor.module.asset.service.HostTerminalService; import com.orion.visor.module.asset.service.HostTerminalService;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -128,7 +130,8 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler {
// 初始化日志 // 初始化日志
this.initLogOutputStream(); this.initLogOutputStream();
// 打开会话 // 打开会话
this.sessionStore = hostTerminalService.openSessionStore(execHostCommand.getHostId()); HostTerminalConnectDTO connect = hostTerminalService.getTerminalConnectInfo(execHostCommand.getHostId());
this.sessionStore = SessionStores.openSessionStore(connect);
if (Booleans.isTrue(execCommand.getScriptExec())) { if (Booleans.isTrue(execCommand.getScriptExec())) {
// 上传脚本文件 // 上传脚本文件
this.uploadScriptFile(); this.uploadScriptFile();
@@ -287,7 +290,7 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler {
*/ */
protected String getErrorMessage(Exception ex) { protected String getErrorMessage(Exception ex) {
String message; String message;
if (ex instanceof InvalidArgumentException) { if (ex instanceof InvalidArgumentException || ex instanceof IllegalArgumentException) {
message = ex.getMessage(); message = ex.getMessage();
} else if (ex instanceof ConnectionRuntimeException) { } else if (ex instanceof ConnectionRuntimeException) {
message = "连接失败"; message = "连接失败";

View File

@@ -0,0 +1,18 @@
package com.orion.visor.module.asset.handler.host.jsch;
/**
* 连接消息
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/7/11 16:30
*/
public interface SessionMessage {
String AUTHENTICATION_FAILURE = "authentication failed. please check the configuration. - {}";
String SERVER_UNREACHABLE = "remote server unreachable. please check the configuration. - {}";
String CONNECTION_TIMEOUT = "connection timeout. - {}";
}

View File

@@ -0,0 +1,125 @@
package com.orion.visor.module.asset.handler.host.jsch;
import com.orion.lang.exception.AuthenticationException;
import com.orion.lang.exception.argument.InvalidArgumentException;
import com.orion.lang.utils.Exceptions;
import com.orion.lang.utils.Strings;
import com.orion.net.host.SessionHolder;
import com.orion.net.host.SessionStore;
import com.orion.visor.framework.common.constant.Const;
import com.orion.visor.framework.common.utils.CryptoUtils;
import com.orion.visor.module.asset.entity.dto.HostTerminalConnectDTO;
import lombok.extern.slf4j.Slf4j;
import java.util.Optional;
/**
* sessionStore 工具类
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/7/11 16:58
*/
@Slf4j
public class SessionStores {
protected static final ThreadLocal<String> CURRENT_ADDRESS = new ThreadLocal<>();
/**
* 打开 sessionStore
*
* @param conn conn
* @return sessionStore
*/
public static SessionStore openSessionStore(HostTerminalConnectDTO conn) {
Long hostId = conn.getHostId();
String address = conn.getHostAddress();
String username = conn.getUsername();
log.info("SessionStores-open-start hostId: {}, address: {}, username: {}", hostId, address, username);
try {
CURRENT_ADDRESS.set(address);
// 创建会话
SessionHolder sessionHolder = SessionHolder.create();
SessionStore session = createSessionStore(conn, sessionHolder);
// 连接
session.connect();
log.info("SessionStores-open-success hostId: {}, address: {}, username: {}", hostId, address, username);
return session;
} catch (Exception e) {
String message = e.getMessage();
log.error("SessionStores-open-error hostId: {}, address: {}, username: {}, message: {}", hostId, address, username, message, e);
throw Exceptions.runtime(getErrorMessage(e), e);
} finally {
CURRENT_ADDRESS.remove();
}
}
/**
* 创建 sessionStore
*
* @param conn conn
* @param sessionHolder sessionHolder
* @return sessionStore
*/
private static SessionStore createSessionStore(HostTerminalConnectDTO conn, SessionHolder sessionHolder) {
final boolean useKey = conn.getKeyId() != null;
// 使用密钥认证
if (useKey) {
// 加载密钥
String publicKey = Optional.ofNullable(conn.getPublicKey())
.map(CryptoUtils::decryptAsString)
.orElse(null);
String privateKey = Optional.ofNullable(conn.getPrivateKey())
.map(CryptoUtils::decryptAsString)
.orElse(null);
String password = Optional.ofNullable(conn.getPrivateKeyPassword())
.map(CryptoUtils::decryptAsString)
.orElse(null);
sessionHolder.addIdentityValue(String.valueOf(conn.getKeyId()),
privateKey,
publicKey,
password);
}
// 获取会话
SessionStore session = sessionHolder.getSession(conn.getHostAddress(), conn.getHostPort(), conn.getUsername());
// 使用密码认证
if (!useKey) {
session.password(CryptoUtils.decryptAsString(conn.getPassword()));
}
// 超时时间
session.timeout(conn.getTimeout());
return session;
}
/**
* 获取错误信息
*
* @param e e
* @return errorMessage
*/
private static String getErrorMessage(Exception e) {
if (e == null) {
return null;
}
String host = CURRENT_ADDRESS.get();
String message = e.getMessage();
if (Strings.contains(message, Const.TIMEOUT)) {
// 连接超时
return Strings.format(SessionMessage.CONNECTION_TIMEOUT, host);
} else if (Exceptions.isCausedBy(e, AuthenticationException.class)) {
// 认证失败
return Strings.format(SessionMessage.AUTHENTICATION_FAILURE, host);
} else if (Exceptions.isCausedBy(e, InvalidArgumentException.class)) {
// 参数错误
if (Strings.isBlank(message)) {
return Strings.format(SessionMessage.SERVER_UNREACHABLE, host);
} else {
return message;
}
} else {
// 其他错误
return Strings.format(SessionMessage.SERVER_UNREACHABLE, host);
}
}
}

View File

@@ -43,7 +43,7 @@ public enum OutputTypeEnum {
/** /**
* SFTP 文件列表 * SFTP 文件列表
*/ */
SFTP_LIST("ls", "${type}|${sessionId}|${path}|${result}|${body}"), SFTP_LIST("ls", "${type}|${sessionId}|${path}|${result}|${msg}|${body}"),
/** /**
* SFTP 创建文件夹 * SFTP 创建文件夹
@@ -78,12 +78,12 @@ public enum OutputTypeEnum {
/** /**
* SFTP 下载文件夹展开文件 * SFTP 下载文件夹展开文件
*/ */
SFTP_DOWNLOAD_FLAT_DIRECTORY("df", "${type}|${sessionId}|${currentPath}|${body}"), SFTP_DOWNLOAD_FLAT_DIRECTORY("df", "${type}|${sessionId}|${currentPath}|${result}|${msg}|${body}"),
/** /**
* SFTP 获取文件内容 * SFTP 获取文件内容
*/ */
SFTP_GET_CONTENT("gc", "${type}|${sessionId}|${path}|${result}|${content}"), SFTP_GET_CONTENT("gc", "${type}|${sessionId}|${path}|${result}|${msg}|${content}"),
/** /**
* SFTP 修改文件内容 * SFTP 修改文件内容

View File

@@ -100,7 +100,7 @@ public abstract class AbstractTerminalHandler<T extends TerminalBasePayload> imp
if (ex == null) { if (ex == null) {
return null; return null;
} }
if (ex instanceof InvalidArgumentException) { if (ex instanceof InvalidArgumentException || ex instanceof IllegalArgumentException) {
return ex.getMessage(); return ex.getMessage();
} }
return ErrorMessage.OPERATE_ERROR; return ErrorMessage.OPERATE_ERROR;

Some files were not shown because too many files have changed in this diff Show More