mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 20:08:40 +08:00
feat(fix) 脚本模版补充权限
This commit is contained in:
parent
502fadf8de
commit
f4b9a3eb21
@ -15,6 +15,8 @@
|
||||
5. 【server】日志弹窗新增行号
|
||||
6. 【server】在线升级执行脚本、脚本模版等兼容 `debian` (感谢@wxyShine [Gitee issues I4UQBD](https://gitee.com/dromara/Jpom/issues/I4UQBD) )
|
||||
7. 【agent】修复 windows 环境,节点首页进程列表切换不生效问题(感谢@neoch [Gitee issues I4UZA7](https://gitee.com/dromara/Jpom/issues/I4UZA7) )
|
||||
8. 【server】脚本模版补充权限
|
||||
|
||||
|
||||
------
|
||||
|
||||
|
@ -37,6 +37,7 @@ import io.jpom.model.data.UserModel;
|
||||
import io.jpom.model.script.ScriptModel;
|
||||
import io.jpom.plugin.ClassFeature;
|
||||
import io.jpom.plugin.Feature;
|
||||
import io.jpom.plugin.MethodFeature;
|
||||
import io.jpom.service.node.script.NodeScriptServer;
|
||||
import io.jpom.service.script.ScriptExecuteLogServer;
|
||||
import io.jpom.service.script.ScriptServer;
|
||||
@ -60,114 +61,117 @@ import java.util.List;
|
||||
@Feature(cls = ClassFeature.SCRIPT)
|
||||
public class ScriptController extends BaseServerController {
|
||||
|
||||
private final ScriptServer scriptServer;
|
||||
private final NodeScriptServer nodeScriptServer;
|
||||
private final ScriptExecuteLogServer scriptExecuteLogServer;
|
||||
private final ScriptServer scriptServer;
|
||||
private final NodeScriptServer nodeScriptServer;
|
||||
private final ScriptExecuteLogServer scriptExecuteLogServer;
|
||||
|
||||
public ScriptController(ScriptServer scriptServer,
|
||||
NodeScriptServer nodeScriptServer,
|
||||
ScriptExecuteLogServer scriptExecuteLogServer) {
|
||||
this.scriptServer = scriptServer;
|
||||
this.nodeScriptServer = nodeScriptServer;
|
||||
this.scriptExecuteLogServer = scriptExecuteLogServer;
|
||||
}
|
||||
public ScriptController(ScriptServer scriptServer,
|
||||
NodeScriptServer nodeScriptServer,
|
||||
ScriptExecuteLogServer scriptExecuteLogServer) {
|
||||
this.scriptServer = scriptServer;
|
||||
this.nodeScriptServer = nodeScriptServer;
|
||||
this.scriptExecuteLogServer = scriptExecuteLogServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* get script list
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String scriptList() {
|
||||
PageResultDto<ScriptModel> pageResultDto = scriptServer.listPage(getRequest());
|
||||
return JsonMessage.getString(200, "success", pageResultDto);
|
||||
}
|
||||
/**
|
||||
* get script list
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.LIST)
|
||||
public String scriptList() {
|
||||
PageResultDto<ScriptModel> pageResultDto = scriptServer.listPage(getRequest());
|
||||
return JsonMessage.getString(200, "success", pageResultDto);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "save.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String save(String id,
|
||||
@ValidatorItem String context,
|
||||
@ValidatorItem String name,
|
||||
String autoExecCron,
|
||||
String defArgs,
|
||||
String description, String nodeIds) {
|
||||
ScriptModel scriptModel = new ScriptModel();
|
||||
scriptModel.setId(id);
|
||||
scriptModel.setContext(context);
|
||||
scriptModel.setName(name);
|
||||
scriptModel.setNodeIds(nodeIds);
|
||||
scriptModel.setDescription(description);
|
||||
scriptModel.setDefArgs(defArgs);
|
||||
@RequestMapping(value = "save.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.EDIT)
|
||||
public String save(String id,
|
||||
@ValidatorItem String context,
|
||||
@ValidatorItem String name,
|
||||
String autoExecCron,
|
||||
String defArgs,
|
||||
String description, String nodeIds) {
|
||||
ScriptModel scriptModel = new ScriptModel();
|
||||
scriptModel.setId(id);
|
||||
scriptModel.setContext(context);
|
||||
scriptModel.setName(name);
|
||||
scriptModel.setNodeIds(nodeIds);
|
||||
scriptModel.setDescription(description);
|
||||
scriptModel.setDefArgs(defArgs);
|
||||
|
||||
Assert.hasText(scriptModel.getContext(), "内容为空");
|
||||
//
|
||||
scriptModel.setAutoExecCron(this.checkCron(autoExecCron));
|
||||
//
|
||||
String oldNodeIds = null;
|
||||
if (StrUtil.isEmpty(id)) {
|
||||
scriptServer.insert(scriptModel);
|
||||
} else {
|
||||
HttpServletRequest request = getRequest();
|
||||
ScriptModel byKey = scriptServer.getByKey(id, request);
|
||||
Assert.notNull(byKey, "没有对应的数据");
|
||||
oldNodeIds = byKey.getNodeIds();
|
||||
scriptServer.updateById(scriptModel, request);
|
||||
}
|
||||
this.syncNodeScript(scriptModel, oldNodeIds);
|
||||
return JsonMessage.getString(200, "修改成功");
|
||||
}
|
||||
Assert.hasText(scriptModel.getContext(), "内容为空");
|
||||
//
|
||||
scriptModel.setAutoExecCron(this.checkCron(autoExecCron));
|
||||
//
|
||||
String oldNodeIds = null;
|
||||
if (StrUtil.isEmpty(id)) {
|
||||
scriptServer.insert(scriptModel);
|
||||
} else {
|
||||
HttpServletRequest request = getRequest();
|
||||
ScriptModel byKey = scriptServer.getByKey(id, request);
|
||||
Assert.notNull(byKey, "没有对应的数据");
|
||||
oldNodeIds = byKey.getNodeIds();
|
||||
scriptServer.updateById(scriptModel, request);
|
||||
}
|
||||
this.syncNodeScript(scriptModel, oldNodeIds);
|
||||
return JsonMessage.getString(200, "修改成功");
|
||||
}
|
||||
|
||||
private void syncDelNodeScript(ScriptModel scriptModel, UserModel user, Collection<String> delNode) {
|
||||
for (String s : delNode) {
|
||||
NodeModel byKey = nodeService.getByKey(s, getRequest());
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", scriptModel.getId());
|
||||
JsonMessage<String> request = NodeForward.request(byKey, NodeUrl.Script_Del, user, jsonObject);
|
||||
Assert.state(request.getCode() == 200, "处理 " + byKey.getName() + " 节点删除脚本失败" + request.getMsg());
|
||||
nodeScriptServer.syncNode(byKey);
|
||||
}
|
||||
}
|
||||
private void syncDelNodeScript(ScriptModel scriptModel, UserModel user, Collection<String> delNode) {
|
||||
for (String s : delNode) {
|
||||
NodeModel byKey = nodeService.getByKey(s, getRequest());
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", scriptModel.getId());
|
||||
JsonMessage<String> request = NodeForward.request(byKey, NodeUrl.Script_Del, user, jsonObject);
|
||||
Assert.state(request.getCode() == 200, "处理 " + byKey.getName() + " 节点删除脚本失败" + request.getMsg());
|
||||
nodeScriptServer.syncNode(byKey);
|
||||
}
|
||||
}
|
||||
|
||||
private void syncNodeScript(ScriptModel scriptModel, String oldNode) {
|
||||
List<String> oldNodeIds = StrUtil.splitTrim(oldNode, StrUtil.COMMA);
|
||||
List<String> newNodeIds = StrUtil.splitTrim(scriptModel.getNodeIds(), StrUtil.COMMA);
|
||||
Collection<String> delNode = CollUtil.subtract(oldNodeIds, newNodeIds);
|
||||
UserModel user = getUser();
|
||||
// 删除
|
||||
this.syncDelNodeScript(scriptModel, user, delNode);
|
||||
// 更新
|
||||
for (String newNodeId : newNodeIds) {
|
||||
NodeModel byKey = nodeService.getByKey(newNodeId, getRequest());
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", scriptModel.getId());
|
||||
jsonObject.put("type", "sync");
|
||||
jsonObject.put("context", scriptModel.getContext());
|
||||
jsonObject.put("autoExecCron", scriptModel.getAutoExecCron());
|
||||
jsonObject.put("defArgs", scriptModel.getDefArgs());
|
||||
jsonObject.put("description", scriptModel.getDescription());
|
||||
jsonObject.put("name", scriptModel.getName());
|
||||
jsonObject.put("workspaceId", scriptModel.getWorkspaceId());
|
||||
JsonMessage<String> request = NodeForward.request(byKey, NodeUrl.Script_Save, user, jsonObject);
|
||||
Assert.state(request.getCode() == 200, "处理 " + byKey.getName() + " 节点同步脚本失败" + request.getMsg());
|
||||
nodeScriptServer.syncNode(byKey);
|
||||
}
|
||||
}
|
||||
private void syncNodeScript(ScriptModel scriptModel, String oldNode) {
|
||||
List<String> oldNodeIds = StrUtil.splitTrim(oldNode, StrUtil.COMMA);
|
||||
List<String> newNodeIds = StrUtil.splitTrim(scriptModel.getNodeIds(), StrUtil.COMMA);
|
||||
Collection<String> delNode = CollUtil.subtract(oldNodeIds, newNodeIds);
|
||||
UserModel user = getUser();
|
||||
// 删除
|
||||
this.syncDelNodeScript(scriptModel, user, delNode);
|
||||
// 更新
|
||||
for (String newNodeId : newNodeIds) {
|
||||
NodeModel byKey = nodeService.getByKey(newNodeId, getRequest());
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", scriptModel.getId());
|
||||
jsonObject.put("type", "sync");
|
||||
jsonObject.put("context", scriptModel.getContext());
|
||||
jsonObject.put("autoExecCron", scriptModel.getAutoExecCron());
|
||||
jsonObject.put("defArgs", scriptModel.getDefArgs());
|
||||
jsonObject.put("description", scriptModel.getDescription());
|
||||
jsonObject.put("name", scriptModel.getName());
|
||||
jsonObject.put("workspaceId", scriptModel.getWorkspaceId());
|
||||
JsonMessage<String> request = NodeForward.request(byKey, NodeUrl.Script_Save, user, jsonObject);
|
||||
Assert.state(request.getCode() == 200, "处理 " + byKey.getName() + " 节点同步脚本失败" + request.getMsg());
|
||||
nodeScriptServer.syncNode(byKey);
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "del.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String del(String id) {
|
||||
HttpServletRequest request = getRequest();
|
||||
ScriptModel server = scriptServer.getByKey(id, request);
|
||||
if (server != null) {
|
||||
File file = server.scriptPath();
|
||||
boolean del = FileUtil.del(file);
|
||||
Assert.state(del, "清理脚本文件失败");
|
||||
// 删除节点中的脚本
|
||||
String nodeIds = server.getNodeIds();
|
||||
List<String> delNode = StrUtil.splitTrim(nodeIds, StrUtil.COMMA);
|
||||
this.syncDelNodeScript(server, getUser(), delNode);
|
||||
scriptServer.delByKey(id, request);
|
||||
//
|
||||
scriptExecuteLogServer.delByWorkspace(request, entity -> entity.set("scriptId", id));
|
||||
}
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
}
|
||||
@RequestMapping(value = "del.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.DEL)
|
||||
public String del(String id) {
|
||||
HttpServletRequest request = getRequest();
|
||||
ScriptModel server = scriptServer.getByKey(id, request);
|
||||
if (server != null) {
|
||||
File file = server.scriptPath();
|
||||
boolean del = FileUtil.del(file);
|
||||
Assert.state(del, "清理脚本文件失败");
|
||||
// 删除节点中的脚本
|
||||
String nodeIds = server.getNodeIds();
|
||||
List<String> delNode = StrUtil.splitTrim(nodeIds, StrUtil.COMMA);
|
||||
this.syncDelNodeScript(server, getUser(), delNode);
|
||||
scriptServer.delByKey(id, request);
|
||||
//
|
||||
scriptExecuteLogServer.delByWorkspace(request, entity -> entity.set("scriptId", id));
|
||||
}
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ import io.jpom.model.script.ScriptExecuteLogModel;
|
||||
import io.jpom.model.script.ScriptModel;
|
||||
import io.jpom.plugin.ClassFeature;
|
||||
import io.jpom.plugin.Feature;
|
||||
import io.jpom.plugin.MethodFeature;
|
||||
import io.jpom.service.script.ScriptExecuteLogServer;
|
||||
import io.jpom.service.script.ScriptServer;
|
||||
import io.jpom.socket.ScriptProcessBuilder;
|
||||
@ -56,64 +57,67 @@ import java.io.File;
|
||||
@Feature(cls = ClassFeature.SCRIPT_LOG)
|
||||
public class ScriptLogController extends BaseServerController {
|
||||
|
||||
private final ScriptExecuteLogServer scriptExecuteLogServer;
|
||||
private final ScriptServer scriptServer;
|
||||
private final ScriptExecuteLogServer scriptExecuteLogServer;
|
||||
private final ScriptServer scriptServer;
|
||||
|
||||
public ScriptLogController(ScriptExecuteLogServer scriptExecuteLogServer,
|
||||
ScriptServer scriptServer) {
|
||||
this.scriptExecuteLogServer = scriptExecuteLogServer;
|
||||
this.scriptServer = scriptServer;
|
||||
}
|
||||
public ScriptLogController(ScriptExecuteLogServer scriptExecuteLogServer,
|
||||
ScriptServer scriptServer) {
|
||||
this.scriptExecuteLogServer = scriptExecuteLogServer;
|
||||
this.scriptServer = scriptServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* get script log list
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String scriptList() {
|
||||
PageResultDto<ScriptExecuteLogModel> pageResultDto = scriptExecuteLogServer.listPage(getRequest());
|
||||
return JsonMessage.getString(200, "success", pageResultDto);
|
||||
}
|
||||
/**
|
||||
* get script log list
|
||||
*
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.LIST)
|
||||
public String scriptList() {
|
||||
PageResultDto<ScriptExecuteLogModel> pageResultDto = scriptExecuteLogServer.listPage(getRequest());
|
||||
return JsonMessage.getString(200, "success", pageResultDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除日志
|
||||
*
|
||||
* @param id id
|
||||
* @param executeId 执行ID
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "del_log", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String delLog(@ValidatorItem() String id,
|
||||
@ValidatorItem() String executeId) {
|
||||
ScriptModel item = scriptServer.getByKey(id, getRequest());
|
||||
Assert.notNull(item, "没有对应数据");
|
||||
File logFile = item.logFile(executeId);
|
||||
boolean fastDel = CommandUtil.systemFastDel(logFile);
|
||||
Assert.state(!fastDel, "删除日志文件失败");
|
||||
scriptExecuteLogServer.delByKey(executeId);
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
}
|
||||
/**
|
||||
* 删除日志
|
||||
*
|
||||
* @param id id
|
||||
* @param executeId 执行ID
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "del_log", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.DEL)
|
||||
public String delLog(@ValidatorItem() String id,
|
||||
@ValidatorItem() String executeId) {
|
||||
ScriptModel item = scriptServer.getByKey(id, getRequest());
|
||||
Assert.notNull(item, "没有对应数据");
|
||||
File logFile = item.logFile(executeId);
|
||||
boolean fastDel = CommandUtil.systemFastDel(logFile);
|
||||
Assert.state(!fastDel, "删除日志文件失败");
|
||||
scriptExecuteLogServer.delByKey(executeId);
|
||||
return JsonMessage.getString(200, "删除成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取的日志
|
||||
*
|
||||
* @param id id
|
||||
* @param executeId 执行ID
|
||||
* @param line 需要获取的行号
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "log", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public String getNowLog(@ValidatorItem() String id,
|
||||
@ValidatorItem() String executeId,
|
||||
@ValidatorItem(value = ValidatorRule.POSITIVE_INTEGER, msg = "line") int line) {
|
||||
ScriptModel item = scriptServer.getByKey(id, getRequest());
|
||||
Assert.notNull(item, "没有对应数据");
|
||||
File logFile = item.logFile(executeId);
|
||||
Assert.state(FileUtil.isFile(logFile), "日志文件错误");
|
||||
JSONObject data = FileUtils.readLogFile(logFile, line);
|
||||
// 运行中
|
||||
data.put("run", ScriptProcessBuilder.isRun(executeId));
|
||||
return JsonMessage.getString(200, "ok", data);
|
||||
}
|
||||
/**
|
||||
* 获取的日志
|
||||
*
|
||||
* @param id id
|
||||
* @param executeId 执行ID
|
||||
* @param line 需要获取的行号
|
||||
* @return json
|
||||
*/
|
||||
@RequestMapping(value = "log", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.LIST)
|
||||
public String getNowLog(@ValidatorItem() String id,
|
||||
@ValidatorItem() String executeId,
|
||||
@ValidatorItem(value = ValidatorRule.POSITIVE_INTEGER, msg = "line") int line) {
|
||||
ScriptModel item = scriptServer.getByKey(id, getRequest());
|
||||
Assert.notNull(item, "没有对应数据");
|
||||
File logFile = item.logFile(executeId);
|
||||
Assert.state(FileUtil.isFile(logFile), "日志文件错误");
|
||||
JSONObject data = FileUtils.readLogFile(logFile, line);
|
||||
// 运行中
|
||||
data.put("run", ScriptProcessBuilder.isRun(executeId));
|
||||
return JsonMessage.getString(200, "ok", data);
|
||||
}
|
||||
}
|
||||
|
@ -67,151 +67,151 @@ import java.util.Map;
|
||||
@Service
|
||||
public class DbUserOperateLogService extends BaseWorkspaceService<UserOperateLogV1> {
|
||||
|
||||
private static final Map<ClassFeature, Class<? extends BaseDbCommonService<?>>> CLASS_FEATURE_SERVICE = new HashMap<>();
|
||||
private static final Map<ClassFeature, Class<? extends BaseDbCommonService<?>>> CLASS_FEATURE_SERVICE = new HashMap<>();
|
||||
|
||||
static {
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.NODE, NodeService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.SSH, SshService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.OUTGIVING, SshService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.MONITOR, MonitorService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.OPT_MONITOR, MonitorUserOptService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.PROJECT, ProjectInfoCacheService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.BUILD_REPOSITORY, RepositoryService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.BUILD, BuildInfoService.class);
|
||||
}
|
||||
static {
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.NODE, NodeService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.SSH, SshService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.OUTGIVING, SshService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.MONITOR, MonitorService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.OPT_MONITOR, MonitorUserOptService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.PROJECT, ProjectInfoCacheService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.BUILD_REPOSITORY, RepositoryService.class);
|
||||
CLASS_FEATURE_SERVICE.put(ClassFeature.BUILD, BuildInfoService.class);
|
||||
}
|
||||
|
||||
private final MonitorUserOptService monitorUserOptService;
|
||||
private final UserService userService;
|
||||
private final WorkspaceService workspaceService;
|
||||
private final MonitorUserOptService monitorUserOptService;
|
||||
private final UserService userService;
|
||||
private final WorkspaceService workspaceService;
|
||||
|
||||
public DbUserOperateLogService(MonitorUserOptService monitorUserOptService,
|
||||
UserService userService,
|
||||
WorkspaceService workspaceService) {
|
||||
this.monitorUserOptService = monitorUserOptService;
|
||||
this.userService = userService;
|
||||
this.workspaceService = workspaceService;
|
||||
}
|
||||
public DbUserOperateLogService(MonitorUserOptService monitorUserOptService,
|
||||
UserService userService,
|
||||
WorkspaceService workspaceService) {
|
||||
this.monitorUserOptService = monitorUserOptService;
|
||||
this.userService = userService;
|
||||
this.workspaceService = workspaceService;
|
||||
}
|
||||
|
||||
private void checkMonitor(UserOperateLogV1 userOperateLogV1) {
|
||||
ClassFeature classFeature = EnumUtil.fromString(ClassFeature.class, userOperateLogV1.getClassFeature(), null);
|
||||
MethodFeature methodFeature = EnumUtil.fromString(MethodFeature.class, userOperateLogV1.getMethodFeature(), null);
|
||||
UserModel optUserItem = userService.getByKey(userOperateLogV1.getUserId());
|
||||
if (classFeature == null || methodFeature == null || optUserItem == null) {
|
||||
return;
|
||||
}
|
||||
String otherMsg = "";
|
||||
Class<? extends BaseDbCommonService<?>> aClass = CLASS_FEATURE_SERVICE.get(classFeature);
|
||||
if (aClass != null) {
|
||||
BaseDbCommonService<?> baseDbCommonService = SpringUtil.getBean(aClass);
|
||||
Object data = baseDbCommonService.getByKey(userOperateLogV1.getNodeId());
|
||||
if (data != null) {
|
||||
Object name = BeanUtil.getProperty(data, "name");
|
||||
otherMsg = name == null ? StrUtil.EMPTY : StrUtil.format("操作的数据名称:{}\n", name);
|
||||
}
|
||||
}
|
||||
WorkspaceModel workspaceModel = workspaceService.getByKey(userOperateLogV1.getWorkspaceId());
|
||||
private void checkMonitor(UserOperateLogV1 userOperateLogV1) {
|
||||
ClassFeature classFeature = EnumUtil.fromString(ClassFeature.class, userOperateLogV1.getClassFeature(), null);
|
||||
MethodFeature methodFeature = EnumUtil.fromString(MethodFeature.class, userOperateLogV1.getMethodFeature(), null);
|
||||
UserModel optUserItem = userService.getByKey(userOperateLogV1.getUserId());
|
||||
if (classFeature == null || methodFeature == null || optUserItem == null) {
|
||||
return;
|
||||
}
|
||||
String otherMsg = "";
|
||||
Class<? extends BaseDbCommonService<?>> aClass = CLASS_FEATURE_SERVICE.get(classFeature);
|
||||
if (aClass != null) {
|
||||
BaseDbCommonService<?> baseDbCommonService = SpringUtil.getBean(aClass);
|
||||
Object data = baseDbCommonService.getByKey(userOperateLogV1.getNodeId());
|
||||
if (data != null) {
|
||||
Object name = BeanUtil.getProperty(data, "name");
|
||||
otherMsg = name == null ? StrUtil.EMPTY : StrUtil.format("操作的数据名称:{}\n", name);
|
||||
}
|
||||
}
|
||||
WorkspaceModel workspaceModel = workspaceService.getByKey(userOperateLogV1.getWorkspaceId());
|
||||
|
||||
String optTypeMsg = StrUtil.format(" 【{}】->【{}】", classFeature.getName(), methodFeature.getName());
|
||||
List<MonitorUserOptModel> monitorUserOptModels = monitorUserOptService.listByType(userOperateLogV1.getWorkspaceId(),
|
||||
classFeature,
|
||||
methodFeature,
|
||||
userOperateLogV1.getUserId());
|
||||
if (CollUtil.isEmpty(monitorUserOptModels)) {
|
||||
return;
|
||||
}
|
||||
for (MonitorUserOptModel monitorUserOptModel : monitorUserOptModels) {
|
||||
List<String> notifyUser = monitorUserOptModel.notifyUser();
|
||||
if (CollUtil.isEmpty(notifyUser)) {
|
||||
continue;
|
||||
}
|
||||
for (String userId : notifyUser) {
|
||||
UserModel item = userService.getByKey(userId);
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
String context = StrUtil.format("操作用户:{}\n操作状态:{}\n操作类型:{}\n所属工作空间:{}\n操作节点:{}\n 操作数据id: {}\n操作IP: {}\n{}",
|
||||
optUserItem.getName(),
|
||||
userOperateLogV1.getOptStatusMsg(),
|
||||
optTypeMsg,
|
||||
workspaceModel.getName(),
|
||||
userOperateLogV1.getNodeId(), userOperateLogV1.getDataId(), userOperateLogV1.getIp(), otherMsg);
|
||||
// 邮箱
|
||||
String email = item.getEmail();
|
||||
if (StrUtil.isNotEmpty(email)) {
|
||||
MonitorModel.Notify notify1 = new MonitorModel.Notify(MonitorModel.NotifyType.mail, email);
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
NotifyUtil.send(notify1, "用户操作报警", context);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("发送报警信息错误", e);
|
||||
}
|
||||
});
|
||||
String optTypeMsg = StrUtil.format(" 【{}】->【{}】", classFeature.getName(), methodFeature.getName());
|
||||
List<MonitorUserOptModel> monitorUserOptModels = monitorUserOptService.listByType(userOperateLogV1.getWorkspaceId(),
|
||||
classFeature,
|
||||
methodFeature,
|
||||
userOperateLogV1.getUserId());
|
||||
if (CollUtil.isEmpty(monitorUserOptModels)) {
|
||||
return;
|
||||
}
|
||||
for (MonitorUserOptModel monitorUserOptModel : monitorUserOptModels) {
|
||||
List<String> notifyUser = monitorUserOptModel.notifyUser();
|
||||
if (CollUtil.isEmpty(notifyUser)) {
|
||||
continue;
|
||||
}
|
||||
for (String userId : notifyUser) {
|
||||
UserModel item = userService.getByKey(userId);
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
String context = StrUtil.format("操作用户:{}\n操作状态:{}\n操作类型:{}\n所属工作空间:{}\n操作节点:{}\n 操作数据id: {}\n操作IP: {}\n{}",
|
||||
optUserItem.getName(),
|
||||
userOperateLogV1.getOptStatusMsg(),
|
||||
optTypeMsg,
|
||||
workspaceModel == null ? StrUtil.EMPTY : workspaceModel.getName(),
|
||||
userOperateLogV1.getNodeId(), userOperateLogV1.getDataId(), userOperateLogV1.getIp(), otherMsg);
|
||||
// 邮箱
|
||||
String email = item.getEmail();
|
||||
if (StrUtil.isNotEmpty(email)) {
|
||||
MonitorModel.Notify notify1 = new MonitorModel.Notify(MonitorModel.NotifyType.mail, email);
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
NotifyUtil.send(notify1, "用户操作报警", context);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("发送报警信息错误", e);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
// dingding
|
||||
String dingDing = item.getDingDing();
|
||||
if (StrUtil.isNotEmpty(dingDing)) {
|
||||
MonitorModel.Notify notify1 = new MonitorModel.Notify(MonitorModel.NotifyType.dingding, dingDing);
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
NotifyUtil.send(notify1, "用户操作报警", context);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("发送报警信息错误", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
// 企业微信
|
||||
String workWx = item.getWorkWx();
|
||||
if (StrUtil.isNotEmpty(workWx)) {
|
||||
MonitorModel.Notify notify1 = new MonitorModel.Notify(MonitorModel.NotifyType.workWx, workWx);
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
NotifyUtil.send(notify1, "用户操作报警", context);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("发送报警信息错误", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// dingding
|
||||
String dingDing = item.getDingDing();
|
||||
if (StrUtil.isNotEmpty(dingDing)) {
|
||||
MonitorModel.Notify notify1 = new MonitorModel.Notify(MonitorModel.NotifyType.dingding, dingDing);
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
NotifyUtil.send(notify1, "用户操作报警", context);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("发送报警信息错误", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
// 企业微信
|
||||
String workWx = item.getWorkWx();
|
||||
if (StrUtil.isNotEmpty(workWx)) {
|
||||
MonitorModel.Notify notify1 = new MonitorModel.Notify(MonitorModel.NotifyType.workWx, workWx);
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
NotifyUtil.send(notify1, "用户操作报警", context);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("发送报警信息错误", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insert(UserOperateLogV1 userOperateLogV1) {
|
||||
super.insert(userOperateLogV1);
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
this.checkMonitor(userOperateLogV1);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("执行操作监控错误", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void insert(UserOperateLogV1 userOperateLogV1) {
|
||||
super.insert(userOperateLogV1);
|
||||
ThreadUtil.execute(() -> {
|
||||
try {
|
||||
this.checkMonitor(userOperateLogV1);
|
||||
} catch (Exception e) {
|
||||
DefaultSystemLog.getLog().error("执行操作监控错误", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResultDto<UserOperateLogV1> listPage(HttpServletRequest request) {
|
||||
// 验证工作空间权限
|
||||
Map<String, String> paramMap = ServletUtil.getParamMap(request);
|
||||
String workspaceId = this.getCheckUserWorkspace(request);
|
||||
paramMap.put("workspaceId:in", workspaceId + StrUtil.COMMA + StrUtil.EMPTY);
|
||||
return super.listPage(paramMap);
|
||||
}
|
||||
@Override
|
||||
public PageResultDto<UserOperateLogV1> listPage(HttpServletRequest request) {
|
||||
// 验证工作空间权限
|
||||
Map<String, String> paramMap = ServletUtil.getParamMap(request);
|
||||
String workspaceId = this.getCheckUserWorkspace(request);
|
||||
paramMap.put("workspaceId:in", workspaceId + StrUtil.COMMA + StrUtil.EMPTY);
|
||||
return super.listPage(paramMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCheckUserWorkspace(HttpServletRequest request) {
|
||||
// 忽略检查
|
||||
String header = ServletUtil.getHeader(request, Const.WORKSPACEID_REQ_HEADER, CharsetUtil.CHARSET_UTF_8);
|
||||
return ObjectUtil.defaultIfNull(header, StrUtil.EMPTY);
|
||||
}
|
||||
@Override
|
||||
public String getCheckUserWorkspace(HttpServletRequest request) {
|
||||
// 忽略检查
|
||||
String header = ServletUtil.getHeader(request, Const.WORKSPACEID_REQ_HEADER, CharsetUtil.CHARSET_UTF_8);
|
||||
return ObjectUtil.defaultIfNull(header, StrUtil.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkUserWorkspace(String workspaceId, UserModel userModel) {
|
||||
// 忽略检查
|
||||
}
|
||||
@Override
|
||||
protected void checkUserWorkspace(String workspaceId, UserModel userModel) {
|
||||
// 忽略检查
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] clearTimeColumns() {
|
||||
return new String[]{"optTime", "createTimeMillis"};
|
||||
}
|
||||
@Override
|
||||
protected String[] clearTimeColumns() {
|
||||
return new String[]{"optTime", "createTimeMillis"};
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
package io.jpom.service.monitor;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import io.jpom.model.data.MonitorUserOptModel;
|
||||
import io.jpom.plugin.ClassFeature;
|
||||
import io.jpom.plugin.MethodFeature;
|
||||
@ -50,7 +51,10 @@ public class MonitorUserOptService extends BaseWorkspaceService<MonitorUserOptMo
|
||||
*/
|
||||
public List<MonitorUserOptModel> listByType(String workspaceId, ClassFeature classFeature, MethodFeature methodFeature, String userId) {
|
||||
MonitorUserOptModel where = new MonitorUserOptModel();
|
||||
where.setWorkspaceId(workspaceId);
|
||||
if (StrUtil.isNotEmpty(workspaceId)) {
|
||||
// 没有工作空间查询全部
|
||||
where.setWorkspaceId(workspaceId);
|
||||
}
|
||||
where.setStatus(true);
|
||||
List<MonitorUserOptModel> list = super.listByBean(where);
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
|
@ -26,7 +26,6 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.io.LineHandler;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.core.util.*;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
@ -34,17 +33,18 @@ import cn.hutool.extra.ssh.ChannelType;
|
||||
import cn.hutool.extra.ssh.JschUtil;
|
||||
import cn.hutool.extra.ssh.Sftp;
|
||||
import cn.jiangzeyin.common.spring.SpringUtil;
|
||||
import com.jcraft.jsch.*;
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.Session;
|
||||
import com.jcraft.jsch.SftpException;
|
||||
import io.jpom.model.data.SshModel;
|
||||
import io.jpom.service.h2db.BaseWorkspaceService;
|
||||
import io.jpom.system.ConfigBean;
|
||||
import io.jpom.system.ServerExtConfigBean;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -57,314 +57,313 @@ import java.util.function.BiFunction;
|
||||
@Service
|
||||
public class SshService extends BaseWorkspaceService<SshModel> {
|
||||
|
||||
@Override
|
||||
protected void fillSelectResult(SshModel data) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
data.setPassword(null);
|
||||
data.setPrivateKey(null);
|
||||
}
|
||||
@Override
|
||||
protected void fillSelectResult(SshModel data) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
data.setPassword(null);
|
||||
data.setPrivateKey(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ssh 回话
|
||||
*
|
||||
* @param sshId id
|
||||
* @return session
|
||||
*/
|
||||
public static Session getSession(String sshId) {
|
||||
SshModel sshModel = SpringUtil.getBean(SshService.class).getByKey(sshId, false);
|
||||
return getSessionByModel(sshModel);
|
||||
}
|
||||
/**
|
||||
* 获取 ssh 回话
|
||||
*
|
||||
* @param sshId id
|
||||
* @return session
|
||||
*/
|
||||
public static Session getSession(String sshId) {
|
||||
SshModel sshModel = SpringUtil.getBean(SshService.class).getByKey(sshId, false);
|
||||
return getSessionByModel(sshModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ssh 回话
|
||||
*
|
||||
* @param sshModel sshModel
|
||||
* @return session
|
||||
*/
|
||||
public static Session getSessionByModel(SshModel sshModel) {
|
||||
Session session;
|
||||
SshModel.ConnectType connectType = sshModel.connectType();
|
||||
if (connectType == SshModel.ConnectType.PASS) {
|
||||
session = JschUtil.openSession(sshModel.getHost(), sshModel.getPort(), sshModel.getUser(), sshModel.getPassword());
|
||||
/**
|
||||
* 获取 ssh 回话
|
||||
*
|
||||
* @param sshModel sshModel
|
||||
* @return session
|
||||
*/
|
||||
public static Session getSessionByModel(SshModel sshModel) {
|
||||
Session session;
|
||||
SshModel.ConnectType connectType = sshModel.connectType();
|
||||
if (connectType == SshModel.ConnectType.PASS) {
|
||||
session = JschUtil.openSession(sshModel.getHost(), sshModel.getPort(), sshModel.getUser(), sshModel.getPassword());
|
||||
|
||||
} else if (connectType == SshModel.ConnectType.PUBKEY) {
|
||||
File rsaFile;
|
||||
String privateKey = sshModel.getPrivateKey();
|
||||
if (StrUtil.startWith(privateKey, URLUtil.FILE_URL_PREFIX)) {
|
||||
String rsaPath = StrUtil.removePrefix(privateKey, URLUtil.FILE_URL_PREFIX);
|
||||
rsaFile = FileUtil.file(rsaPath);
|
||||
} else if (StrUtil.isEmpty(privateKey)) {
|
||||
File home = FileUtil.getUserHomeDir();
|
||||
Assert.notNull(home, "用户目录没有找到");
|
||||
File identity = FileUtil.file(home, ".ssh", "identity");
|
||||
rsaFile = FileUtil.isFile(identity) ? identity : null;
|
||||
File idRsa = FileUtil.file(home, ".ssh", "id_rsa");
|
||||
rsaFile = FileUtil.isFile(idRsa) ? idRsa : rsaFile;
|
||||
File idDsa = FileUtil.file(home, ".ssh", "id_dsa");
|
||||
rsaFile = FileUtil.isFile(idDsa) ? idDsa : rsaFile;
|
||||
Assert.notNull(rsaFile, "用户目录没有找到私钥信息");
|
||||
} else {
|
||||
File tempPath = ConfigBean.getInstance().getTempPath();
|
||||
String sshFile = StrUtil.emptyToDefault(sshModel.getId(), IdUtil.fastSimpleUUID());
|
||||
rsaFile = FileUtil.file(tempPath, "ssh", sshFile);
|
||||
FileUtil.writeString(privateKey, rsaFile, CharsetUtil.UTF_8);
|
||||
}
|
||||
Assert.state(FileUtil.isFile(rsaFile), "私钥文件不存在:" + FileUtil.getAbsolutePath(rsaFile));
|
||||
byte[] pas = null;
|
||||
if (StrUtil.isNotEmpty(sshModel.getPassword())) {
|
||||
pas = sshModel.getPassword().getBytes();
|
||||
}
|
||||
session = JschUtil.openSession(sshModel.getHost(), sshModel.getPort(), sshModel.getUser(), FileUtil.getAbsolutePath(rsaFile), pas);
|
||||
} else {
|
||||
throw new IllegalArgumentException("不支持的模式");
|
||||
}
|
||||
try {
|
||||
session.setServerAliveInterval((int) TimeUnit.SECONDS.toMillis(5));
|
||||
session.setServerAliveCountMax(5);
|
||||
} catch (JSchException ignored) {
|
||||
}
|
||||
return session;
|
||||
}
|
||||
} else if (connectType == SshModel.ConnectType.PUBKEY) {
|
||||
File rsaFile;
|
||||
String privateKey = sshModel.getPrivateKey();
|
||||
if (StrUtil.startWith(privateKey, URLUtil.FILE_URL_PREFIX)) {
|
||||
String rsaPath = StrUtil.removePrefix(privateKey, URLUtil.FILE_URL_PREFIX);
|
||||
rsaFile = FileUtil.file(rsaPath);
|
||||
} else if (StrUtil.isEmpty(privateKey)) {
|
||||
File home = FileUtil.getUserHomeDir();
|
||||
Assert.notNull(home, "用户目录没有找到");
|
||||
File identity = FileUtil.file(home, ".ssh", "identity");
|
||||
rsaFile = FileUtil.isFile(identity) ? identity : null;
|
||||
File idRsa = FileUtil.file(home, ".ssh", "id_rsa");
|
||||
rsaFile = FileUtil.isFile(idRsa) ? idRsa : rsaFile;
|
||||
File idDsa = FileUtil.file(home, ".ssh", "id_dsa");
|
||||
rsaFile = FileUtil.isFile(idDsa) ? idDsa : rsaFile;
|
||||
Assert.notNull(rsaFile, "用户目录没有找到私钥信息");
|
||||
} else {
|
||||
File tempPath = ConfigBean.getInstance().getTempPath();
|
||||
String sshFile = StrUtil.emptyToDefault(sshModel.getId(), IdUtil.fastSimpleUUID());
|
||||
rsaFile = FileUtil.file(tempPath, "ssh", sshFile);
|
||||
FileUtil.writeString(privateKey, rsaFile, CharsetUtil.UTF_8);
|
||||
}
|
||||
Assert.state(FileUtil.isFile(rsaFile), "私钥文件不存在:" + FileUtil.getAbsolutePath(rsaFile));
|
||||
byte[] pas = null;
|
||||
if (StrUtil.isNotEmpty(sshModel.getPassword())) {
|
||||
pas = sshModel.getPassword().getBytes();
|
||||
}
|
||||
session = JschUtil.openSession(sshModel.getHost(), sshModel.getPort(), sshModel.getUser(), FileUtil.getAbsolutePath(rsaFile), pas);
|
||||
} else {
|
||||
throw new IllegalArgumentException("不支持的模式");
|
||||
}
|
||||
try {
|
||||
session.setServerAliveInterval((int) TimeUnit.SECONDS.toMillis(5));
|
||||
session.setServerAliveCountMax(5);
|
||||
} catch (JSchException ignored) {
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否存在正在运行的进程
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param tag 标识
|
||||
* @return true 存在运行中的
|
||||
* @throws IOException IO
|
||||
* @throws JSchException jsch
|
||||
*/
|
||||
public boolean checkSshRun(SshModel sshModel, String tag) throws IOException, JSchException {
|
||||
return this.checkSshRunPid(sshModel, tag) != null;
|
||||
}
|
||||
/**
|
||||
* 检查是否存在正在运行的进程
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param tag 标识
|
||||
* @return true 存在运行中的
|
||||
* @throws IOException IO
|
||||
* @throws JSchException jsch
|
||||
*/
|
||||
public boolean checkSshRun(SshModel sshModel, String tag) throws IOException, JSchException {
|
||||
return this.checkSshRunPid(sshModel, tag) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 ssh 中的 环境 版本
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @return 返回
|
||||
* @throws IOException IO
|
||||
* @throws JSchException jsch
|
||||
*/
|
||||
public String checkCommand(SshModel sshModel, String command) throws IOException, JSchException {
|
||||
// 检查 环境
|
||||
List<String> commandResult = this.execCommand(sshModel, "command -v " + command);
|
||||
return CollUtil.join(commandResult, StrUtil.COMMA);
|
||||
}
|
||||
/**
|
||||
* 获取 ssh 中的 环境 版本
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @return 返回
|
||||
* @throws IOException IO
|
||||
*/
|
||||
public String checkCommand(SshModel sshModel, String command) throws IOException {
|
||||
// 检查 环境
|
||||
return this.exec(sshModel, "command -v " + command);
|
||||
// return CollUtil.join(commandResult, StrUtil.COMMA);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否存在正在运行的进程
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param tag 标识
|
||||
* @return true 存在运行中的
|
||||
* @throws IOException IO
|
||||
* @throws JSchException jsch
|
||||
*/
|
||||
public Integer checkSshRunPid(SshModel sshModel, String tag) throws IOException, JSchException {
|
||||
String ps = StrUtil.format("ps -ef | grep -v 'grep' | egrep {}", tag);
|
||||
// 运行中
|
||||
List<String> result = this.execCommand(sshModel, ps);
|
||||
return result.stream().map(s -> {
|
||||
List<String> split = StrUtil.splitTrim(s, StrUtil.SPACE);
|
||||
return Convert.toInt(CollUtil.get(split, 1));
|
||||
}).filter(Objects::nonNull).findAny().orElse(null);
|
||||
}
|
||||
/**
|
||||
* 检查是否存在正在运行的进程
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param tag 标识
|
||||
* @return true 存在运行中的
|
||||
* @throws IOException IO
|
||||
*/
|
||||
public Integer checkSshRunPid(SshModel sshModel, String tag) throws IOException {
|
||||
String ps = StrUtil.format("ps -ef | grep -v 'grep' | egrep {}", tag);
|
||||
// 运行中
|
||||
String exec = this.exec(sshModel, ps);
|
||||
List<String> result = StrUtil.splitTrim(exec, StrUtil.LF);
|
||||
return result.stream().map(s -> {
|
||||
List<String> split = StrUtil.splitTrim(s, StrUtil.SPACE);
|
||||
return Convert.toInt(CollUtil.get(split, 1));
|
||||
}).filter(Objects::nonNull).findAny().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* ssh 执行模版命令
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param command 命令
|
||||
* @return 执行结果
|
||||
* @throws IOException io
|
||||
*/
|
||||
public String exec(SshModel sshModel, String... command) throws IOException {
|
||||
Charset charset = sshModel.getCharsetT();
|
||||
return this.exec(sshModel, (s, session) -> {
|
||||
// 执行命令
|
||||
String exec, error;
|
||||
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
|
||||
exec = JschUtil.exec(session, s, charset, stream);
|
||||
error = new String(stream.toByteArray(), charset);
|
||||
if (StrUtil.isNotEmpty(error)) {
|
||||
error = " 错误:" + error;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
return exec + error;
|
||||
}, command);
|
||||
}
|
||||
/**
|
||||
* ssh 执行模版命令
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param command 命令
|
||||
* @return 执行结果
|
||||
* @throws IOException io
|
||||
*/
|
||||
public String exec(SshModel sshModel, String... command) throws IOException {
|
||||
Charset charset = sshModel.getCharsetT();
|
||||
return this.exec(sshModel, (s, session) -> {
|
||||
// 执行命令
|
||||
String exec, error;
|
||||
try (ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
|
||||
exec = JschUtil.exec(session, s, charset, stream);
|
||||
error = new String(stream.toByteArray(), charset);
|
||||
if (StrUtil.isNotEmpty(error)) {
|
||||
error = " 错误:" + error;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
return exec + error;
|
||||
}, command);
|
||||
}
|
||||
|
||||
/**
|
||||
* ssh 执行模版命令
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param command 命令
|
||||
* @return 执行结果
|
||||
* @throws IOException io
|
||||
*/
|
||||
public String exec(SshModel sshModel, BiFunction<String, Session, String> function, String... command) throws IOException {
|
||||
if (ArrayUtil.isEmpty(command)) {
|
||||
return "没有任何命令";
|
||||
}
|
||||
Session session = null;
|
||||
InputStream sshExecTemplateInputStream = null;
|
||||
Sftp sftp = null;
|
||||
try {
|
||||
String tempId = SecureUtil.sha1(sshModel.getId() + ArrayUtil.join(command, StrUtil.COMMA));
|
||||
File buildSsh = FileUtil.file(ConfigBean.getInstance().getTempPath(), "ssh_temp", tempId + ".sh");
|
||||
String sshExecTemplate;
|
||||
if (ArrayUtil.contains(command, "#disabled-template-auto-evn")) {
|
||||
sshExecTemplate = StrUtil.EMPTY;
|
||||
} else {
|
||||
sshExecTemplateInputStream = ResourceUtil.getStream("classpath:/bin/execTemplate.sh");
|
||||
sshExecTemplate = IoUtil.readUtf8(sshExecTemplateInputStream);
|
||||
}
|
||||
StringBuilder stringBuilder = new StringBuilder(sshExecTemplate);
|
||||
for (String s : command) {
|
||||
stringBuilder.append(s).append(StrUtil.LF);
|
||||
}
|
||||
Charset charset = sshModel.getCharsetT();
|
||||
FileUtil.writeString(stringBuilder.toString(), buildSsh, charset);
|
||||
//
|
||||
session = getSessionByModel(sshModel);
|
||||
// 上传文件
|
||||
sftp = new Sftp(session);
|
||||
String home = sftp.home();
|
||||
String path = home + "/.jpom/";
|
||||
String destFile = path + IdUtil.fastSimpleUUID() + ".sh";
|
||||
sftp.mkDirs(path);
|
||||
sftp.upload(destFile, buildSsh);
|
||||
// 执行命令
|
||||
try {
|
||||
String commandSh = "bash " + destFile;
|
||||
return function.apply(commandSh, session);
|
||||
} finally {
|
||||
try {
|
||||
// 删除 ssh 中临时文件
|
||||
sftp.delFile(destFile);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
// 删除临时文件
|
||||
FileUtil.del(buildSsh);
|
||||
}
|
||||
} finally {
|
||||
IoUtil.close(sftp);
|
||||
IoUtil.close(sshExecTemplateInputStream);
|
||||
JschUtil.close(session);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ssh 执行模版命令
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param command 命令
|
||||
* @return 执行结果
|
||||
* @throws IOException io
|
||||
*/
|
||||
public String exec(SshModel sshModel, BiFunction<String, Session, String> function, String... command) throws IOException {
|
||||
if (ArrayUtil.isEmpty(command)) {
|
||||
return "没有任何命令";
|
||||
}
|
||||
Session session = null;
|
||||
InputStream sshExecTemplateInputStream = null;
|
||||
Sftp sftp = null;
|
||||
try {
|
||||
String tempId = SecureUtil.sha1(sshModel.getId() + ArrayUtil.join(command, StrUtil.COMMA));
|
||||
File buildSsh = FileUtil.file(ConfigBean.getInstance().getTempPath(), "ssh_temp", tempId + ".sh");
|
||||
String sshExecTemplate;
|
||||
if (ArrayUtil.contains(command, "#disabled-template-auto-evn")) {
|
||||
sshExecTemplate = StrUtil.EMPTY;
|
||||
} else {
|
||||
sshExecTemplateInputStream = ResourceUtil.getStream("classpath:/bin/execTemplate.sh");
|
||||
sshExecTemplate = IoUtil.readUtf8(sshExecTemplateInputStream);
|
||||
}
|
||||
StringBuilder stringBuilder = new StringBuilder(sshExecTemplate);
|
||||
for (String s : command) {
|
||||
stringBuilder.append(s).append(StrUtil.LF);
|
||||
}
|
||||
Charset charset = sshModel.getCharsetT();
|
||||
FileUtil.writeString(stringBuilder.toString(), buildSsh, charset);
|
||||
//
|
||||
session = getSessionByModel(sshModel);
|
||||
// 上传文件
|
||||
sftp = new Sftp(session);
|
||||
String home = sftp.home();
|
||||
String path = home + "/.jpom/";
|
||||
String destFile = path + IdUtil.fastSimpleUUID() + ".sh";
|
||||
sftp.mkDirs(path);
|
||||
sftp.upload(destFile, buildSsh);
|
||||
// 执行命令
|
||||
try {
|
||||
String commandSh = "bash " + destFile;
|
||||
return function.apply(commandSh, session);
|
||||
} finally {
|
||||
try {
|
||||
// 删除 ssh 中临时文件
|
||||
sftp.delFile(destFile);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
// 删除临时文件
|
||||
FileUtil.del(buildSsh);
|
||||
}
|
||||
} finally {
|
||||
IoUtil.close(sftp);
|
||||
IoUtil.close(sshExecTemplateInputStream);
|
||||
JschUtil.close(session);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行命令
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param command 命令
|
||||
* @return 结果
|
||||
* @throws IOException io
|
||||
* @throws JSchException jsch
|
||||
*/
|
||||
public String exec(SshModel sshModel, String command) throws IOException, JSchException {
|
||||
Session session = null;
|
||||
try {
|
||||
session = getSessionByModel(sshModel);
|
||||
return exec(session, sshModel.getCharsetT(), command);
|
||||
} finally {
|
||||
JschUtil.close(session);
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 执行命令
|
||||
// *
|
||||
// * @param sshModel ssh
|
||||
// * @param command 命令
|
||||
// * @return 结果
|
||||
// * @throws IOException io
|
||||
// * @throws JSchException jsch
|
||||
// */
|
||||
// public String exec(SshModel sshModel, String command) throws IOException, JSchException {
|
||||
// Session session = null;
|
||||
// try {
|
||||
// session = getSessionByModel(sshModel);
|
||||
// return exec(session, sshModel.getCharsetT(), command);
|
||||
// } finally {
|
||||
// JschUtil.close(session);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private String exec(Session session, Charset charset, String command) throws IOException, JSchException {
|
||||
// ChannelExec channel = null;
|
||||
// try {
|
||||
// channel = (ChannelExec) JschUtil.createChannel(session, ChannelType.EXEC);
|
||||
// // 添加环境变量
|
||||
// channel.setCommand(ServerExtConfigBean.getInstance().getSshInitEnv() + " && " + command);
|
||||
// InputStream inputStream = channel.getInputStream();
|
||||
// InputStream errStream = channel.getErrStream();
|
||||
// channel.connect();
|
||||
// // 读取结果
|
||||
// String result = IoUtil.read(inputStream, charset);
|
||||
// //
|
||||
// String error = IoUtil.read(errStream, charset);
|
||||
// return result + error;
|
||||
// } finally {
|
||||
// JschUtil.close(channel);
|
||||
// }
|
||||
// }
|
||||
|
||||
private String exec(Session session, Charset charset, String command) throws IOException, JSchException {
|
||||
ChannelExec channel = null;
|
||||
try {
|
||||
channel = (ChannelExec) JschUtil.createChannel(session, ChannelType.EXEC);
|
||||
// 添加环境变量
|
||||
channel.setCommand(ServerExtConfigBean.getInstance().getSshInitEnv() + " && " + command);
|
||||
InputStream inputStream = channel.getInputStream();
|
||||
InputStream errStream = channel.getErrStream();
|
||||
channel.connect();
|
||||
// 读取结果
|
||||
String result = IoUtil.read(inputStream, charset);
|
||||
//
|
||||
String error = IoUtil.read(errStream, charset);
|
||||
return result + error;
|
||||
} finally {
|
||||
JschUtil.close(channel);
|
||||
}
|
||||
}
|
||||
// private List<String> execCommand(SshModel sshModel, String command) throws IOException, JSchException {
|
||||
// Session session = null;
|
||||
// ChannelExec channel = null;
|
||||
// try {
|
||||
// session = getSessionByModel(sshModel);
|
||||
// channel = (ChannelExec) JschUtil.createChannel(session, ChannelType.EXEC);
|
||||
// // 添加环境变量
|
||||
// channel.setCommand(ServerExtConfigBean.getInstance().getSshInitEnv() + " && " + command);
|
||||
// InputStream inputStream = channel.getInputStream();
|
||||
// InputStream errStream = channel.getErrStream();
|
||||
// channel.connect();
|
||||
// Charset charset = sshModel.getCharsetT();
|
||||
// // 运行中
|
||||
// List<String> result = new ArrayList<>();
|
||||
// IoUtil.readLines(inputStream, charset, (LineHandler) result::add);
|
||||
// IoUtil.readLines(errStream, charset, (LineHandler) result::add);
|
||||
// return result;
|
||||
// } finally {
|
||||
// JschUtil.close(channel);
|
||||
// JschUtil.close(session);
|
||||
// }
|
||||
// }
|
||||
|
||||
private List<String> execCommand(SshModel sshModel, String command) throws IOException, JSchException {
|
||||
Session session = null;
|
||||
ChannelExec channel = null;
|
||||
try {
|
||||
session = getSessionByModel(sshModel);
|
||||
channel = (ChannelExec) JschUtil.createChannel(session, ChannelType.EXEC);
|
||||
// 添加环境变量
|
||||
channel.setCommand(ServerExtConfigBean.getInstance().getSshInitEnv() + " && " + command);
|
||||
InputStream inputStream = channel.getInputStream();
|
||||
InputStream errStream = channel.getErrStream();
|
||||
channel.connect();
|
||||
Charset charset = sshModel.getCharsetT();
|
||||
// 运行中
|
||||
List<String> result = new ArrayList<>();
|
||||
IoUtil.readLines(inputStream, charset, (LineHandler) result::add);
|
||||
IoUtil.readLines(errStream, charset, (LineHandler) result::add);
|
||||
return result;
|
||||
} finally {
|
||||
JschUtil.close(channel);
|
||||
JschUtil.close(session);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param remotePath 远程路径
|
||||
* @param desc 文件夹或者文件
|
||||
*/
|
||||
public void uploadDir(SshModel sshModel, String remotePath, File desc) {
|
||||
Session session = null;
|
||||
ChannelSftp channel = null;
|
||||
try {
|
||||
session = getSessionByModel(sshModel);
|
||||
channel = (ChannelSftp) JschUtil.openChannel(session, ChannelType.SFTP);
|
||||
Sftp sftp = new Sftp(channel, sshModel.getCharsetT());
|
||||
sftp.syncUpload(desc, remotePath);
|
||||
//uploadDir(channel, remotePath, desc, sshModel.getCharsetT());
|
||||
} finally {
|
||||
JschUtil.close(channel);
|
||||
JschUtil.close(session);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*
|
||||
* @param sshModel ssh
|
||||
* @param remotePath 远程路径
|
||||
* @param desc 文件夹或者文件
|
||||
*/
|
||||
public void uploadDir(SshModel sshModel, String remotePath, File desc) {
|
||||
Session session = null;
|
||||
ChannelSftp channel = null;
|
||||
try {
|
||||
session = getSessionByModel(sshModel);
|
||||
channel = (ChannelSftp) JschUtil.openChannel(session, ChannelType.SFTP);
|
||||
Sftp sftp = new Sftp(channel, sshModel.getCharsetT());
|
||||
sftp.syncUpload(desc, remotePath);
|
||||
//uploadDir(channel, remotePath, desc, sshModel.getCharsetT());
|
||||
} finally {
|
||||
JschUtil.close(channel);
|
||||
JschUtil.close(session);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param sshModel 实体
|
||||
* @param remoteFile 远程文件
|
||||
* @param save 文件对象
|
||||
* @throws FileNotFoundException io
|
||||
* @throws SftpException sftp
|
||||
*/
|
||||
public void download(SshModel sshModel, String remoteFile, File save) throws FileNotFoundException, SftpException {
|
||||
Session session = null;
|
||||
ChannelSftp channel = null;
|
||||
OutputStream output = null;
|
||||
try {
|
||||
session = getSessionByModel(sshModel);
|
||||
channel = (ChannelSftp) JschUtil.openChannel(session, ChannelType.SFTP);
|
||||
output = new FileOutputStream(save);
|
||||
channel.get(remoteFile, output);
|
||||
} finally {
|
||||
IoUtil.close(output);
|
||||
JschUtil.close(channel);
|
||||
JschUtil.close(session);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @param sshModel 实体
|
||||
* @param remoteFile 远程文件
|
||||
* @param save 文件对象
|
||||
* @throws FileNotFoundException io
|
||||
* @throws SftpException sftp
|
||||
*/
|
||||
public void download(SshModel sshModel, String remoteFile, File save) throws FileNotFoundException, SftpException {
|
||||
Session session = null;
|
||||
ChannelSftp channel = null;
|
||||
OutputStream output = null;
|
||||
try {
|
||||
session = getSessionByModel(sshModel);
|
||||
channel = (ChannelSftp) JschUtil.openChannel(session, ChannelType.SFTP);
|
||||
output = new FileOutputStream(save);
|
||||
channel.get(remoteFile, output);
|
||||
} finally {
|
||||
IoUtil.close(output);
|
||||
JschUtil.close(channel);
|
||||
JschUtil.close(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,205 +67,205 @@ import java.util.Set;
|
||||
*/
|
||||
@PreLoadClass
|
||||
public class OperateLogController implements AopLogInterface {
|
||||
private static final ThreadLocal<CacheInfo> CACHE_INFO_THREAD_LOCAL = new ThreadLocal<>();
|
||||
private static final ThreadLocal<CacheInfo> CACHE_INFO_THREAD_LOCAL = new ThreadLocal<>();
|
||||
|
||||
|
||||
@PreLoadMethod
|
||||
private static void init() {
|
||||
WebAopLog.setAopLogInterface(SpringUtil.getBean(OperateLogController.class));
|
||||
}
|
||||
@PreLoadMethod
|
||||
private static void init() {
|
||||
WebAopLog.setAopLogInterface(SpringUtil.getBean(OperateLogController.class));
|
||||
}
|
||||
|
||||
private CacheInfo createCacheInfo(Method method) {
|
||||
Feature feature = method.getAnnotation(Feature.class);
|
||||
if (feature == null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
MethodFeature methodFeature = feature.method();
|
||||
if (methodFeature == MethodFeature.NULL) {
|
||||
DefaultSystemLog.getLog().error("权限分发配置错误:{} {}", declaringClass, method.getName());
|
||||
return null;
|
||||
}
|
||||
ClassFeature classFeature = feature.cls();
|
||||
if (classFeature == ClassFeature.NULL) {
|
||||
Feature feature1 = declaringClass.getAnnotation(Feature.class);
|
||||
if (feature1 == null || feature1.cls() == ClassFeature.NULL) {
|
||||
DefaultSystemLog.getLog().error("权限分发配置错误:{} {} class not find", declaringClass, method.getName());
|
||||
return null;
|
||||
}
|
||||
classFeature = feature1.cls();
|
||||
}
|
||||
CacheInfo cacheInfo = new CacheInfo();
|
||||
cacheInfo.setClassFeature(classFeature);
|
||||
cacheInfo.setMethodFeature(methodFeature);
|
||||
cacheInfo.setOptTime(SystemClock.now());
|
||||
cacheInfo.setResultCode(feature.resultCode());
|
||||
cacheInfo.setLogResponse(feature.logResponse());
|
||||
return cacheInfo;
|
||||
}
|
||||
private CacheInfo createCacheInfo(Method method) {
|
||||
Feature feature = method.getAnnotation(Feature.class);
|
||||
if (feature == null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> declaringClass = method.getDeclaringClass();
|
||||
MethodFeature methodFeature = feature.method();
|
||||
if (methodFeature == MethodFeature.NULL) {
|
||||
DefaultSystemLog.getLog().error("权限分发配置错误:{} {}", declaringClass, method.getName());
|
||||
return null;
|
||||
}
|
||||
ClassFeature classFeature = feature.cls();
|
||||
if (classFeature == ClassFeature.NULL) {
|
||||
Feature feature1 = declaringClass.getAnnotation(Feature.class);
|
||||
if (feature1 == null || feature1.cls() == ClassFeature.NULL) {
|
||||
DefaultSystemLog.getLog().error("权限分发配置错误:{} {} class not find", declaringClass, method.getName());
|
||||
return null;
|
||||
}
|
||||
classFeature = feature1.cls();
|
||||
}
|
||||
CacheInfo cacheInfo = new CacheInfo();
|
||||
cacheInfo.setClassFeature(classFeature);
|
||||
cacheInfo.setMethodFeature(methodFeature);
|
||||
cacheInfo.setOptTime(SystemClock.now());
|
||||
cacheInfo.setResultCode(feature.resultCode());
|
||||
cacheInfo.setLogResponse(feature.logResponse());
|
||||
return cacheInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void before(ProceedingJoinPoint joinPoint) {
|
||||
Signature signature = joinPoint.getSignature();
|
||||
if (signature instanceof MethodSignature) {
|
||||
MethodSignature methodSignature = (MethodSignature) signature;
|
||||
Method method = methodSignature.getMethod();
|
||||
CacheInfo cacheInfo = this.createCacheInfo(method);
|
||||
if (cacheInfo == null) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
ServletRequestAttributes servletRequestAttributes = BaseServerController.getRequestAttributes();
|
||||
HttpServletRequest request = servletRequestAttributes.getRequest();
|
||||
// 获取ip地址
|
||||
cacheInfo.ip = ServletUtil.getClientIP(request);
|
||||
// 获取节点
|
||||
cacheInfo.nodeModel = (NodeModel) request.getAttribute("node");
|
||||
//
|
||||
cacheInfo.dataId = request.getParameter("id");
|
||||
//
|
||||
cacheInfo.userAgent = ServletUtil.getHeaderIgnoreCase(request, HttpHeaders.USER_AGENT);
|
||||
cacheInfo.workspaceId = ServletUtil.getHeaderIgnoreCase(request, Const.WORKSPACEID_REQ_HEADER);
|
||||
//
|
||||
Map<String, String> map = ServletUtil.getParamMap(request);
|
||||
// 过滤密码字段
|
||||
Set<Map.Entry<String, String>> entries = map.entrySet();
|
||||
for (Map.Entry<String, String> entry : entries) {
|
||||
String key = entry.getKey();
|
||||
if (StrUtil.containsAnyIgnoreCase(key, "pwd", "password")) {
|
||||
entry.setValue("***");
|
||||
}
|
||||
}
|
||||
map.put("request_url", request.getRequestURI());
|
||||
cacheInfo.reqData = JSONObject.toJSONString(map);
|
||||
CACHE_INFO_THREAD_LOCAL.set(cacheInfo);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void before(ProceedingJoinPoint joinPoint) {
|
||||
Signature signature = joinPoint.getSignature();
|
||||
if (signature instanceof MethodSignature) {
|
||||
MethodSignature methodSignature = (MethodSignature) signature;
|
||||
Method method = methodSignature.getMethod();
|
||||
CacheInfo cacheInfo = this.createCacheInfo(method);
|
||||
if (cacheInfo == null) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
ServletRequestAttributes servletRequestAttributes = BaseServerController.getRequestAttributes();
|
||||
HttpServletRequest request = servletRequestAttributes.getRequest();
|
||||
// 获取ip地址
|
||||
cacheInfo.ip = ServletUtil.getClientIP(request);
|
||||
// 获取节点
|
||||
cacheInfo.nodeModel = (NodeModel) request.getAttribute("node");
|
||||
//
|
||||
cacheInfo.dataId = request.getParameter("id");
|
||||
//
|
||||
cacheInfo.userAgent = ServletUtil.getHeaderIgnoreCase(request, HttpHeaders.USER_AGENT);
|
||||
cacheInfo.workspaceId = ServletUtil.getHeaderIgnoreCase(request, Const.WORKSPACEID_REQ_HEADER);
|
||||
//
|
||||
Map<String, String> map = ServletUtil.getParamMap(request);
|
||||
// 过滤密码字段
|
||||
Set<Map.Entry<String, String>> entries = map.entrySet();
|
||||
for (Map.Entry<String, String> entry : entries) {
|
||||
String key = entry.getKey();
|
||||
if (StrUtil.containsAnyIgnoreCase(key, "pwd", "password")) {
|
||||
entry.setValue("***");
|
||||
}
|
||||
}
|
||||
map.put("request_url", request.getRequestURI());
|
||||
cacheInfo.reqData = JSONObject.toJSONString(map);
|
||||
CACHE_INFO_THREAD_LOCAL.set(cacheInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterReturning(Object value) {
|
||||
try {
|
||||
CacheInfo cacheInfo = CACHE_INFO_THREAD_LOCAL.get();
|
||||
if (cacheInfo == null || cacheInfo.methodFeature == MethodFeature.LIST) {
|
||||
return;
|
||||
}
|
||||
if (cacheInfo.classFeature == null || cacheInfo.methodFeature == null) {
|
||||
new RuntimeException("权限功能没有配置正确").printStackTrace();
|
||||
return;
|
||||
}
|
||||
UserModel userModel = BaseServerController.getUserByThreadLocal();
|
||||
userModel = userModel == null ? BaseServerController.getUserModel() : userModel;
|
||||
// 没有对应的用户
|
||||
if (userModel == null) {
|
||||
return;
|
||||
}
|
||||
this.log(userModel, value, cacheInfo);
|
||||
} finally {
|
||||
CACHE_INFO_THREAD_LOCAL.remove();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void afterReturning(Object value) {
|
||||
try {
|
||||
CacheInfo cacheInfo = CACHE_INFO_THREAD_LOCAL.get();
|
||||
if (cacheInfo == null || cacheInfo.methodFeature == MethodFeature.LIST) {
|
||||
return;
|
||||
}
|
||||
if (cacheInfo.classFeature == null || cacheInfo.methodFeature == null) {
|
||||
new RuntimeException("权限功能没有配置正确").printStackTrace();
|
||||
return;
|
||||
}
|
||||
UserModel userModel = BaseServerController.getUserByThreadLocal();
|
||||
userModel = userModel == null ? BaseServerController.getUserModel() : userModel;
|
||||
// 没有对应的用户
|
||||
if (userModel == null) {
|
||||
return;
|
||||
}
|
||||
this.log(userModel, value, cacheInfo);
|
||||
} finally {
|
||||
CACHE_INFO_THREAD_LOCAL.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录操作日志
|
||||
*
|
||||
* @param userModel 用户
|
||||
* @param value 返回执行
|
||||
* @param cacheInfo 请求信息
|
||||
*/
|
||||
public void log(UserModel userModel, Object value, CacheInfo cacheInfo) {
|
||||
UserOperateLogV1 userOperateLogV1 = new UserOperateLogV1();
|
||||
userOperateLogV1.setWorkspaceId(cacheInfo.workspaceId);
|
||||
userOperateLogV1.setClassFeature(cacheInfo.classFeature.name());
|
||||
userOperateLogV1.setMethodFeature(cacheInfo.methodFeature.name());
|
||||
userOperateLogV1.setDataId(cacheInfo.dataId);
|
||||
userOperateLogV1.setUserId(userModel.getId());
|
||||
userOperateLogV1.setIp(cacheInfo.ip);
|
||||
userOperateLogV1.setUserAgent(cacheInfo.userAgent);
|
||||
userOperateLogV1.setReqData(cacheInfo.reqData);
|
||||
userOperateLogV1.setOptTime(ObjectUtil.defaultIfNull(cacheInfo.optTime, SystemClock.now()));
|
||||
if (value != null) {
|
||||
// 解析结果
|
||||
if (value instanceof Throwable) {
|
||||
// 发生异常
|
||||
Throwable throwable = (Throwable) value;
|
||||
userOperateLogV1.setResultMsg(ExceptionUtil.stacktraceToString(throwable));
|
||||
userOperateLogV1.setOptStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
} else {
|
||||
String json = value.toString();
|
||||
userOperateLogV1.setResultMsg(json);
|
||||
try {
|
||||
JsonMessage<String> jsonMessage = JSONObject.parseObject(json, JsonMessage.class);
|
||||
int code = jsonMessage.getCode();
|
||||
int[] resultCode = cacheInfo.getResultCode();
|
||||
if (ArrayUtil.isNotEmpty(resultCode) && !ArrayUtil.contains(resultCode, code)) {
|
||||
// 忽略
|
||||
return;
|
||||
}
|
||||
userOperateLogV1.setOptStatus(code);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
// 判断是否记录响应日志
|
||||
Boolean logResponse = cacheInfo.getLogResponse();
|
||||
if (logResponse != null && !logResponse) {
|
||||
userOperateLogV1.setResultMsg("*****");
|
||||
}
|
||||
}
|
||||
//
|
||||
if (cacheInfo.nodeModel != null) {
|
||||
userOperateLogV1.setNodeId(cacheInfo.nodeModel.getId());
|
||||
if (StrUtil.isEmpty(cacheInfo.workspaceId)) {
|
||||
userOperateLogV1.setWorkspaceId(cacheInfo.nodeModel.getWorkspaceId());
|
||||
}
|
||||
}
|
||||
//
|
||||
try {
|
||||
BaseServerController.resetInfo(UserModel.EMPTY);
|
||||
DbUserOperateLogService dbUserOperateLogService = SpringUtil.getBean(DbUserOperateLogService.class);
|
||||
dbUserOperateLogService.insert(userOperateLogV1);
|
||||
} finally {
|
||||
BaseServerController.removeEmpty();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 记录操作日志
|
||||
*
|
||||
* @param userModel 用户
|
||||
* @param value 返回执行
|
||||
* @param cacheInfo 请求信息
|
||||
*/
|
||||
public void log(UserModel userModel, Object value, CacheInfo cacheInfo) {
|
||||
UserOperateLogV1 userOperateLogV1 = new UserOperateLogV1();
|
||||
userOperateLogV1.setWorkspaceId(cacheInfo.workspaceId);
|
||||
userOperateLogV1.setClassFeature(cacheInfo.classFeature.name());
|
||||
userOperateLogV1.setMethodFeature(cacheInfo.methodFeature.name());
|
||||
userOperateLogV1.setDataId(cacheInfo.dataId);
|
||||
userOperateLogV1.setUserId(userModel.getId());
|
||||
userOperateLogV1.setIp(cacheInfo.ip);
|
||||
userOperateLogV1.setUserAgent(cacheInfo.userAgent);
|
||||
userOperateLogV1.setReqData(cacheInfo.reqData);
|
||||
userOperateLogV1.setOptTime(ObjectUtil.defaultIfNull(cacheInfo.optTime, SystemClock.now()));
|
||||
if (value != null) {
|
||||
// 解析结果
|
||||
if (value instanceof Throwable) {
|
||||
// 发生异常
|
||||
Throwable throwable = (Throwable) value;
|
||||
userOperateLogV1.setResultMsg(ExceptionUtil.stacktraceToString(throwable));
|
||||
userOperateLogV1.setOptStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
} else {
|
||||
String json = value.toString();
|
||||
userOperateLogV1.setResultMsg(json);
|
||||
try {
|
||||
JsonMessage<?> jsonMessage = JSONObject.parseObject(json, JsonMessage.class);
|
||||
int code = jsonMessage.getCode();
|
||||
int[] resultCode = cacheInfo.getResultCode();
|
||||
if (ArrayUtil.isNotEmpty(resultCode) && !ArrayUtil.contains(resultCode, code)) {
|
||||
// 忽略
|
||||
return;
|
||||
}
|
||||
userOperateLogV1.setOptStatus(code);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
// 判断是否记录响应日志
|
||||
Boolean logResponse = cacheInfo.getLogResponse();
|
||||
if (logResponse != null && !logResponse) {
|
||||
userOperateLogV1.setResultMsg(new cn.hutool.json.JSONObject().putOpt("hide", "*****").toString());
|
||||
}
|
||||
}
|
||||
//
|
||||
if (cacheInfo.nodeModel != null) {
|
||||
userOperateLogV1.setNodeId(cacheInfo.nodeModel.getId());
|
||||
if (StrUtil.isEmpty(cacheInfo.workspaceId)) {
|
||||
userOperateLogV1.setWorkspaceId(cacheInfo.nodeModel.getWorkspaceId());
|
||||
}
|
||||
}
|
||||
//
|
||||
try {
|
||||
BaseServerController.resetInfo(UserModel.EMPTY);
|
||||
DbUserOperateLogService dbUserOperateLogService = SpringUtil.getBean(DbUserOperateLogService.class);
|
||||
dbUserOperateLogService.insert(userOperateLogV1);
|
||||
} finally {
|
||||
BaseServerController.removeEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改执行结果
|
||||
*
|
||||
* @param reqId 请求id
|
||||
* @param val 结果
|
||||
*/
|
||||
public void updateLog(String reqId, String val) {
|
||||
DbUserOperateLogService dbUserOperateLogService = SpringUtil.getBean(DbUserOperateLogService.class);
|
||||
/**
|
||||
* 修改执行结果
|
||||
*
|
||||
* @param reqId 请求id
|
||||
* @param val 结果
|
||||
*/
|
||||
public void updateLog(String reqId, String val) {
|
||||
DbUserOperateLogService dbUserOperateLogService = SpringUtil.getBean(DbUserOperateLogService.class);
|
||||
|
||||
Entity entity = new Entity();
|
||||
entity.set("resultMsg", val);
|
||||
try {
|
||||
JsonMessage<?> jsonMessage = JSONObject.parseObject(val, JsonMessage.class);
|
||||
entity.set("optStatus", jsonMessage.getCode());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
//
|
||||
Entity where = new Entity();
|
||||
where.set("reqId", reqId);
|
||||
dbUserOperateLogService.update(entity, where);
|
||||
}
|
||||
Entity entity = new Entity();
|
||||
entity.set("resultMsg", val);
|
||||
try {
|
||||
JsonMessage<?> jsonMessage = JSONObject.parseObject(val, JsonMessage.class);
|
||||
entity.set("optStatus", jsonMessage.getCode());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
//
|
||||
Entity where = new Entity();
|
||||
where.set("reqId", reqId);
|
||||
dbUserOperateLogService.update(entity, where);
|
||||
}
|
||||
|
||||
/**
|
||||
* 临时缓存
|
||||
*/
|
||||
@Data
|
||||
public static class CacheInfo {
|
||||
private Long optTime;
|
||||
private String workspaceId;
|
||||
private ClassFeature classFeature;
|
||||
private MethodFeature methodFeature;
|
||||
private String ip;
|
||||
private NodeModel nodeModel;
|
||||
private String dataId;
|
||||
private String userAgent;
|
||||
private String reqData;
|
||||
private int[] resultCode;
|
||||
private Boolean logResponse;
|
||||
}
|
||||
/**
|
||||
* 临时缓存
|
||||
*/
|
||||
@Data
|
||||
public static class CacheInfo {
|
||||
private Long optTime;
|
||||
private String workspaceId;
|
||||
private ClassFeature classFeature;
|
||||
private MethodFeature methodFeature;
|
||||
private String ip;
|
||||
private NodeModel nodeModel;
|
||||
private String dataId;
|
||||
private String userAgent;
|
||||
private String reqData;
|
||||
private int[] resultCode;
|
||||
private Boolean logResponse;
|
||||
}
|
||||
}
|
||||
|
@ -411,11 +411,11 @@ export default {
|
||||
this.$store.dispatch("toggleFullScreenFlag").then((flag) => {
|
||||
if (flag) {
|
||||
this.$notification.success({
|
||||
message: "页面内容自动撑开出现滚动条",
|
||||
message: "页面内容自动撑开出现屏幕滚动条",
|
||||
});
|
||||
} else {
|
||||
this.$notification.success({
|
||||
message: "页面全屏,高度 100%",
|
||||
message: "页面全屏,高度 100%。局部区域可以滚动",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="node-full-content">
|
||||
<!-- 数据表格 -->
|
||||
<a-table :data-source="list" :columns="columns" @change="changePage" :pagination="this.listQuery.total / this.listQuery.limit > 1 ? (this, pagination) : false" bordered rowKey="id">
|
||||
<a-table :data-source="list" size="middle" :columns="columns" @change="changePage" :pagination="this.listQuery.total / this.listQuery.limit > 1 ? (this, pagination) : false" bordered rowKey="id">
|
||||
<template slot="title">
|
||||
<a-space>
|
||||
<a-select v-model="listQuery.nodeId" allowClear placeholder="请选择节点" class="search-input-item">
|
||||
@ -154,7 +154,7 @@ export default {
|
||||
{ title: "修改时间", dataIndex: "modifyTimeMillis", width: 170, sorter: true, ellipsis: true, scopedSlots: { customRender: "modifyTimeMillis" } },
|
||||
{ title: "修改人", dataIndex: "modifyUser", ellipsis: true, scopedSlots: { customRender: "modifyUser" }, width: 120 },
|
||||
{ title: "最后操作人", dataIndex: "lastRunUser", ellipsis: true, scopedSlots: { customRender: "lastRunUser" } },
|
||||
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: 240 },
|
||||
{ title: "操作", dataIndex: "operation", align: "center", scopedSlots: { customRender: "operation" }, width: 220 },
|
||||
],
|
||||
rules: {
|
||||
name: [{ required: true, message: "Please input Script name", trigger: "blur" }],
|
||||
|
Loading…
Reference in New Issue
Block a user