package com.wgcloud.controller;
|
|
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONUtil;
|
import com.github.pagehelper.PageInfo;
|
import com.wgcloud.config.CommonConfig;
|
import com.wgcloud.entity.AccountInfo;
|
import com.wgcloud.entity.ShellInfo;
|
import com.wgcloud.entity.ShellState;
|
import com.wgcloud.entity.SystemInfo;
|
import com.wgcloud.service.LogInfoService;
|
import com.wgcloud.service.ShellInfoService;
|
import com.wgcloud.service.ShellStateService;
|
import com.wgcloud.service.SystemInfoService;
|
import com.wgcloud.util.*;
|
import com.wgcloud.util.msg.WarnMailUtil;
|
import com.wgcloud.util.staticvar.StaticKeys;
|
import org.apache.commons.lang3.StringUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Controller;
|
import org.springframework.ui.Model;
|
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
|
import javax.annotation.Resource;
|
import javax.servlet.http.HttpServletRequest;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* @version v3.3
|
* @ClassName:ShellInfoController.java
|
* @author: http://www.wgstart.com
|
* @date: 2021年8月19日
|
* @Description: 下发指令执行controller
|
* @Copyright: 2019-2021 wgcloud. All rights reserved.
|
*/
|
@Controller
|
@RequestMapping("/shellInfo")
|
public class ShellInfoController {
|
|
|
private static final Logger logger = LoggerFactory.getLogger(ShellInfoController.class);
|
|
@Resource
|
private ShellInfoService shellInfoService;
|
|
@Resource
|
private ShellStateService shellStateService;
|
|
@Resource
|
private LogInfoService logInfoService;
|
|
@Resource
|
private SystemInfoService systemInfoService;
|
|
@Autowired
|
private TokenUtils tokenUtils;
|
|
@Autowired
|
private CommonConfig commonConfig;
|
|
/**
|
* agent查询下发指令列表
|
*
|
* @param model
|
* @param request
|
* @return
|
*/
|
@ResponseBody
|
@RequestMapping(value = "agentList")
|
public String agentList(@RequestBody String paramBean) {
|
JSONObject agentJsonObject = (JSONObject) JSONUtil.parse(paramBean);
|
if (!tokenUtils.checkAgentToken(agentJsonObject)) {
|
logger.error(StaticKeys.TOKEN_ERROR);
|
return ResDataUtils.resetErrorJson(StaticKeys.TOKEN_ERROR);
|
}
|
if (!StaticKeys.TRUE_VAL.equals(commonConfig.getShellToRun())) {
|
return ResDataUtils.resetErrorJson("shellToRun is no open");
|
}
|
Map<String, Object> params = new HashMap<String, Object>();
|
if (null == agentJsonObject.get("hostname") || StringUtils.isEmpty(agentJsonObject.get("hostname").toString())) {
|
return "";
|
}
|
params.put("hostname", agentJsonObject.get("hostname").toString());
|
try {
|
params.put("state", StaticKeys.SHELL_RUN_STATE_1);
|
params.put("shellTime", System.currentTimeMillis());
|
List<ShellState> shellStateList = shellStateService.selectAllByParams(params);
|
//检测系统类型 begin
|
SystemInfo systemInfo = systemInfoService.selectByHostname(agentJsonObject.get("hostname").toString());
|
String shellToRunBlock = commonConfig.getShellToRunLinuxBlock();
|
if (systemInfo != null) {
|
String platForm = systemInfo.getPlatForm().toLowerCase();
|
if (platForm.contains("windows")) {
|
shellToRunBlock = commonConfig.getShellToRunWinBlock();
|
}
|
}
|
//检测系统类型 end
|
String blockKey = "";
|
for (ShellState state : shellStateList) {
|
//检查是否含有敏感字符
|
blockKey = FormatUtil.haveBlockDanger(state.getShell(), shellToRunBlock, "");
|
if (!StringUtils.isEmpty(blockKey)) {
|
logger.info(state.getShell() + "下发指令含有敏感字符" + blockKey + ",不进行下发");
|
shellStateList.remove(state);
|
continue;
|
}
|
//更新状态为已下发
|
shellStateService.updateSendByIds(state.getId().split(","));
|
}
|
return ResDataUtils.resetSuccessJson(shellStateList);
|
} catch (Exception e) {
|
logger.error("agent获取下发指令信息错误", e);
|
logInfoService.save("agent获取下发指令信息错误", e.toString(), StaticKeys.LOG_XTCZ);
|
return ResDataUtils.resetErrorJson(e.toString());
|
}
|
}
|
|
/**
|
* agent执行指令完成,回调此处
|
*
|
* @param paramBean
|
* @return
|
*/
|
@ResponseBody
|
@RequestMapping("/shellCallback")
|
public String appCallback(@RequestBody String paramBean) {
|
JSONObject agentJsonObject = (JSONObject) JSONUtil.parse(paramBean);
|
logger.info("shellCallback-------------" + agentJsonObject.toString());
|
if (!tokenUtils.checkAgentToken(agentJsonObject)) {
|
logger.error(StaticKeys.TOKEN_ERROR);
|
return ResDataUtils.resetErrorJson(StaticKeys.TOKEN_ERROR);
|
}
|
try {
|
String shellStateId = agentJsonObject.getStr("id");
|
if (StringUtils.isEmpty(shellStateId)) {
|
logger.error("shellStateId is null");
|
return ResDataUtils.resetErrorJson("shellStateId is null");
|
}
|
//执行结果错误信息
|
String shellState = agentJsonObject.getStr("state");
|
if (!StringUtils.isEmpty(shellState) && shellState.length() > 500) {
|
shellState = shellState.substring(0, 500);
|
}
|
ShellState shellStateCall = shellStateService.selectById(shellStateId);
|
shellStateCall.setState(shellState);
|
shellStateCall.setCreateTime(new Date());
|
shellStateService.updateById(shellStateCall);
|
return ResDataUtils.resetSuccessJson(null);
|
} catch (Exception e) {
|
logger.error("agent执行指令完成回调错误", e);
|
return ResDataUtils.resetErrorJson(e.toString());
|
}
|
}
|
|
/**
|
* 根据条件查询下发指令列表
|
*
|
* @param model
|
* @param request
|
* @return
|
*/
|
@RequestMapping(value = "list")
|
public String shellInfoList(ShellInfo ShellInfo, Model model, HttpServletRequest request) {
|
Map<String, Object> params = new HashMap<String, Object>();
|
try {
|
|
StringBuffer url = new StringBuffer();
|
String shellName = null;
|
if (!StringUtils.isEmpty(ShellInfo.getShellName())) {
|
shellName = ShellInfo.getShellName();
|
params.put("shellName", shellName.trim());
|
url.append("&shellName=").append(shellName);
|
}
|
if (!StringUtils.isEmpty(ShellInfo.getAccount())) {
|
params.put("account", ShellInfo.getAccount());
|
url.append("&account=").append(ShellInfo.getAccount());
|
}
|
if (!StringUtils.isEmpty(ShellInfo.getState())) {
|
params.put("state", ShellInfo.getState());
|
url.append("&state=").append(ShellInfo.getState());
|
}
|
|
//校验是否需要添加过滤用户查询条件
|
HostUtil.addAccountquery(request, params);
|
|
PageInfo<ShellInfo> pageInfo = shellInfoService.selectByParams(params, ShellInfo.getPage(), ShellInfo.getPageSize());
|
//统计指令执行状态数量 begin
|
Map<String, Object> paramsStateCount = new HashMap<String, Object>();
|
for (ShellInfo shellInfo1 : pageInfo.getList()) {
|
paramsStateCount.clear();
|
paramsStateCount.put("shellId", shellInfo1.getId());
|
Integer stateAllCount = shellStateService.countByParams(paramsStateCount);
|
paramsStateCount.put("state", StaticKeys.SHELL_RUN_STATE_1);
|
Integer state1Count = shellStateService.countByParams(paramsStateCount);
|
shellInfo1.setState1Count(state1Count);
|
shellInfo1.setStateOtherCount(stateAllCount - state1Count);
|
if (state1Count == 0) {
|
shellInfo1.setState(StaticKeys.SHELL_STATE_3);
|
}
|
}
|
//统计指令执行状态数量 end
|
PageUtil.initPageNumber(pageInfo, model);
|
|
//设置用户列表
|
HostUtil.addAccountListModel(model);
|
|
model.addAttribute("pageUrl", "/shellInfo/list?1=1" + url.toString());
|
model.addAttribute("page", pageInfo);
|
model.addAttribute("shellInfo", ShellInfo);
|
model.addAttribute("shellToRun", commonConfig.getShellToRun());
|
} catch (Exception e) {
|
logger.error("查询下发指令信息错误", e);
|
logInfoService.save("查询下发指令信息错误", e.toString(), StaticKeys.LOG_XTCZ);
|
}
|
return "shellInfo/list";
|
}
|
|
|
/**
|
* 保存下发指令信息
|
*
|
* @param ShellInfo
|
* @param model
|
* @param request
|
* @return
|
*/
|
@RequestMapping(value = "save")
|
public String saveShellInfo(ShellInfo shellInfo, Model model, HttpServletRequest request) {
|
if (!StaticKeys.TRUE_VAL.equals(commonConfig.getShellToRun())) {
|
return ResDataUtils.resetErrorJson("shellToRun is no open");
|
}
|
try {
|
//检测指令有无敏感字符 begin
|
String blockKey = FormatUtil.haveBlockDanger(shellInfo.getShell(), commonConfig.getShellToRunLinuxBlock(), commonConfig.getShellToRunWinBlock());
|
if (!StringUtils.isEmpty(blockKey)) {
|
model.addAttribute("shellInfo", shellInfo);
|
String[] selectedHostnames = request.getParameterValues("hostnames");
|
model.addAttribute("selectedHosts", selectedHostnames);
|
List<SystemInfo> systemInfoList = systemInfoService.selectAllByParams(new HashMap<>());
|
for (SystemInfo systemInfo : systemInfoList) {
|
for (String selectedHost : selectedHostnames) {
|
if (selectedHost.equals(systemInfo.getHostname())) {
|
systemInfo.setSelected("selected");
|
}
|
}
|
}
|
model.addAttribute("systemInfoList", systemInfoList);
|
model.addAttribute("msg", "下发指令含有敏感字符" + blockKey + ",请检查");
|
//敏感字符组装
|
getBlockStr(model);
|
return "shellInfo/add";
|
}
|
//检测指令有无敏感字符 end
|
|
//设置下发时间 begin
|
if (StaticKeys.SHELL_TYPE_2.equals(shellInfo.getShellType()) && !StringUtils.isEmpty(shellInfo.getShellTime())) {
|
shellInfo.setShellTime(shellInfo.getShellTime() + ":00");
|
}
|
//设置下发时间 end
|
|
if (StringUtils.isEmpty(shellInfo.getId())) {
|
String[] hostnames = request.getParameterValues("hostnames");
|
if (null == hostnames || hostnames.length < 1) {
|
return "redirect:/shellInfo/list";
|
}
|
|
AccountInfo accountInfo = HostUtil.getAccountByRequest(request);
|
if (null != accountInfo) {
|
if (!StaticKeys.ROLE_ADMIN.equals(accountInfo.getRole())) {
|
shellInfo.setAccount(accountInfo.getAccount());
|
}
|
}
|
|
shellInfoService.save(shellInfo, hostnames);
|
//发送邮件提示 begin
|
Runnable runnable = () -> {
|
try {
|
if (shellInfo != null) {
|
WarnMailUtil.sendShellInfo(shellInfo, "开始下发指令");
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
};
|
ThreadPoolUtil.executor.execute(runnable);
|
//发送邮件提示 end
|
} else {
|
shellInfoService.updateById(shellInfo);
|
}
|
} catch (Exception e) {
|
logger.error("保存下发指令错误", e);
|
logInfoService.save("保存下发指令错误", e.toString(), StaticKeys.LOG_XTCZ);
|
}
|
return "redirect:/shellInfo/list";
|
}
|
|
/**
|
* 添加
|
*
|
* @param model
|
* @param request
|
* @return
|
*/
|
@RequestMapping(value = "edit")
|
public String edit(Model model, HttpServletRequest request) {
|
String errorMsg = "添加下发指令";
|
String id = request.getParameter("id");
|
ShellInfo ShellInfo = new ShellInfo();
|
try {
|
//校验是否需要添加过滤用户查询条件
|
Map<String, Object> paramsAccount = new HashMap<String, Object>();
|
HostUtil.addAccountquery(request, paramsAccount);
|
List<SystemInfo> systemInfoList = systemInfoService.selectAllByParams(paramsAccount);
|
model.addAttribute("systemInfoList", systemInfoList);
|
|
//敏感字符组装
|
getBlockStr(model);
|
|
if (StringUtils.isEmpty(id)) {
|
model.addAttribute("shellInfo", ShellInfo);
|
|
return "shellInfo/add";
|
}
|
ShellInfo = shellInfoService.selectById(id);
|
model.addAttribute("ShellInfo", ShellInfo);
|
} catch (Exception e) {
|
logger.error(errorMsg, e);
|
logInfoService.save(errorMsg, e.toString(), StaticKeys.LOG_XTCZ);
|
}
|
return "shellInfo/add";
|
}
|
|
|
/**
|
* 查看指令下发执行状态信息
|
*
|
* @param model
|
* @param request
|
* @return
|
*/
|
@RequestMapping(value = "view")
|
public String view(Model model, HttpServletRequest request) {
|
String errorMsg = "查看指令下发执行状态信息错误";
|
String id = request.getParameter("id");
|
ShellInfo ShellInfo = new ShellInfo();
|
try {
|
ShellInfo = shellInfoService.selectById(id);
|
Map<String, Object> params = new HashMap<String, Object>();
|
params.put("shellId", id);
|
List<ShellState> shellStateList = shellStateService.selectAllByParams(params);
|
//提取主机备注 begin
|
for (ShellState shellState1 : shellStateList) {
|
shellState1.setHostname(shellState1.getHostname() + HostUtil.addRemark(shellState1.getHostname()));
|
}
|
//提取主机备注 end
|
model.addAttribute("shellStateList", shellStateList);
|
model.addAttribute("shellInfo", ShellInfo);
|
} catch (Exception e) {
|
logger.error(errorMsg, e);
|
logInfoService.save(errorMsg, e.toString(), StaticKeys.LOG_XTCZ);
|
}
|
return "shellInfo/stateList";
|
}
|
|
|
/**
|
* 取消下发指令
|
*
|
* @param id
|
* @param model
|
* @param request
|
* @param redirectAttributes
|
* @return
|
*/
|
@ResponseBody
|
@RequestMapping(value = "cancel")
|
public String cancel(Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
|
String errorMsg = "取消下发指令信息错误";
|
try {
|
if (!StringUtils.isEmpty(request.getParameter("id"))) {
|
ShellInfo shellInfo = shellInfoService.selectById(request.getParameter("id"));
|
shellInfoService.cancelShell(request.getParameter("id"));
|
//发送邮件提示 begin
|
Runnable runnable = () -> {
|
try {
|
if (shellInfo != null) {
|
WarnMailUtil.sendShellInfo(shellInfo, "取消下发指令");
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
};
|
ThreadPoolUtil.executor.execute(runnable);
|
//发送邮件提示 end
|
}
|
} catch (Exception e) {
|
logger.error(errorMsg, e);
|
logInfoService.save(errorMsg, e.toString(), StaticKeys.LOG_XTCZ);
|
}
|
return ResDataUtils.resetSuccessJson(null);
|
}
|
|
|
/**
|
* 删除下发执行信息,不删除执行状态数据
|
*
|
* @param id
|
* @param model
|
* @param request
|
* @param redirectAttributes
|
* @return
|
*/
|
@RequestMapping(value = "del")
|
public String delete(Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
|
String errorMsg = "删除下发执行信息错误";
|
try {
|
if (!StringUtils.isEmpty(request.getParameter("id"))) {
|
String[] ids = request.getParameter("id").split(",");
|
for (String id : ids) {
|
ShellInfo shellInfo = shellInfoService.selectById(id);
|
|
//发送邮件提示 begin
|
Runnable runnable = () -> {
|
try {
|
if (shellInfo != null) {
|
WarnMailUtil.sendShellInfo(shellInfo, "删除下发指令");
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
};
|
ThreadPoolUtil.executor.execute(runnable);
|
//发送邮件提示 end
|
|
}
|
shellInfoService.deleteById(ids);
|
}
|
} catch (Exception e) {
|
logger.error(errorMsg, e);
|
logInfoService.save(errorMsg, e.toString(), StaticKeys.LOG_XTCZ);
|
}
|
|
return "redirect:/shellInfo/list";
|
}
|
|
|
/**
|
* 提取已配置的敏感字符串
|
*
|
* @return
|
*/
|
private void getBlockStr(Model model) {
|
//敏感字符组装 begin
|
String blockStr = "";
|
if (!StringUtils.isEmpty(commonConfig.getShellToRunLinuxBlock())) {
|
blockStr = "[linux不能包含敏感字符:" + commonConfig.getShellToRunLinuxBlock() + "]";
|
}
|
if (!StringUtils.isEmpty(commonConfig.getShellToRunLinuxBlock())) {
|
blockStr += "[windows不能包含敏感字符:" + commonConfig.getShellToRunWinBlock() + "]";
|
}
|
model.addAttribute("blockStr", blockStr);
|
//敏感字符组装 end
|
}
|
|
}
|