基本功能完成

This commit is contained in:
jiangzeyin 2019-04-17 16:17:17 +08:00
parent e349e0503f
commit 839b1d21dd
34 changed files with 1089 additions and 801 deletions

View File

@ -26,6 +26,11 @@ public abstract class BaseAgentController extends BaseJpomController {
return StrUtil.emptyToDefault(name, StrUtil.DASHED);
}
protected boolean isSystemUser() {
String val = ServletUtil.getHeaderIgnoreCase(getRequest(), "Jpom-Server-SystemUserRole");
return Boolean.valueOf(val);
}
/**
* 获取拦截器中缓存的项目信息

View File

@ -0,0 +1,27 @@
package cn.keepbx.jpom.controller;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseAgentController;
import cn.keepbx.jpom.model.system.JpomManifest;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* @author jiangzeyin
* @date 2019/4/17
*/
@RestController
public class IndexController extends BaseAgentController {
@RequestMapping(value = {"index", "", "index.html", "/"}, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String index() {
return "Jpom-Agent";
}
@RequestMapping(value = "info", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String info() {
return JsonMessage.getString(200, "", JpomManifest.getInstance());
}
}

View File

@ -0,0 +1,165 @@
package cn.keepbx.jpom.controller.monitor;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseAgentController;
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
import cn.keepbx.jpom.common.commander.AbstractSystemCommander;
import cn.keepbx.jpom.model.system.NetstatModel;
import cn.keepbx.jpom.model.system.ProcessModel;
import cn.keepbx.jpom.system.AgentConfigBean;
import cn.keepbx.jpom.util.CommandUtil;
import cn.keepbx.jpom.util.JvmUtil;
import com.alibaba.fastjson.JSONObject;
import com.sun.tools.attach.VirtualMachine;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.math.BigDecimal;
import java.util.List;
/**
* 内存查看
*
* @author Administrator
*/
@RestController
@RequestMapping(value = "/manage/")
public class InternalController extends BaseAgentController {
/**
* 获取内存信息
*/
@RequestMapping(value = "internal_data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String getInternal(String tag) throws Exception {
int pid = AbstractProjectCommander.getInstance().getPid(tag);
if (pid <= 0) {
return JsonMessage.getString(400, "");
}
JSONObject jsonObject = new JSONObject();
ProcessModel item = AbstractSystemCommander.getInstance().getPidInfo(pid);
jsonObject.put("process", item);
JSONObject beanMem = getBeanMem(tag);
jsonObject.put("beanMem", beanMem);
//获取端口信息
List<NetstatModel> netstatModels = AbstractProjectCommander.getInstance().listNetstat(pid);
jsonObject.put("netstat", netstatModels);
return JsonMessage.getString(200, "", jsonObject);
}
/**
* 获取jvm内存
*
* @param tag tag
* @return JSONObject
*/
private JSONObject getBeanMem(String tag) {
try {
VirtualMachine virtualMachine = JvmUtil.getVirtualMachine(tag);
MemoryMXBean memoryMXBean = JvmUtil.getMemoryMXBean(virtualMachine);
if (memoryMXBean == null) {
return null;
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("mount", memoryMXBean.getObjectPendingFinalizationCount());
//堆内存
MemoryUsage memory = memoryMXBean.getHeapMemoryUsage();
//非堆内存
MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
long used = memory.getUsed();
long max = memory.getMax();
//未定义
if (-1 == max) {
max = memory.getCommitted();
}
//计算使用内存占最大内存的百分比
double v = new BigDecimal(used).divide(new BigDecimal(max), 2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
jsonObject.put("heapUsed", FileUtil.readableFileSize(used));
jsonObject.put("heapProportion", String.format("%.2f", v) + "%");
jsonObject.put("heapCommitted", FileUtil.readableFileSize(memory.getCommitted()));
long nonUsed = nonHeapMemoryUsage.getUsed();
long nonMax = nonHeapMemoryUsage.getMax();
long nonCommitted = nonHeapMemoryUsage.getCommitted();
if (-1 == nonMax) {
nonMax = nonCommitted;
}
jsonObject.put("nonHeapUsed", FileUtil.readableFileSize(nonUsed));
double proportion = new BigDecimal(nonUsed).divide(new BigDecimal(nonMax), 2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
jsonObject.put("nonHeapProportion", String.format("%.2f", proportion) + "%");
jsonObject.put("nonHeapCommitted", FileUtil.readableFileSize(nonCommitted));
return jsonObject;
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
}
return null;
}
/**
* 导出堆栈信息
*/
@RequestMapping(value = "internal_stack", method = RequestMethod.GET)
@ResponseBody
public String stack(String tag) throws Exception {
String fileName = AgentConfigBean.getInstance().getTempPathName() + "/" + tag + "_java_cpu.txt";
fileName = FileUtil.normalize(fileName);
try {
int pid = AbstractProjectCommander.getInstance().getPid(tag);
if (pid <= 0) {
return JsonMessage.getString(400, "未运行");
}
String command = String.format("jstack %s >> %s ", pid, fileName);
CommandUtil.execSystemCommand(command);
downLoad(getResponse(), fileName);
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
// getResponse().sendRedirect("internal?tag=" + tag);
}
return JsonMessage.getString(200, "");
}
/**
* 导出内存信息
*/
@RequestMapping(value = "internal_ram", method = RequestMethod.GET)
@ResponseBody
public String ram(String tag) throws Exception {
String fileName = AgentConfigBean.getInstance().getTempPathName() + "/" + tag + "_java_ram.txt";
fileName = FileUtil.normalize(fileName);
try {
int pid = AbstractProjectCommander.getInstance().getPid(tag);
if (pid <= 0) {
return JsonMessage.getString(400, "未运行");
}
String command = String.format("jmap -histo:live %s >> %s", pid, fileName);
CommandUtil.execSystemCommand(command);
downLoad(getResponse(), fileName);
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
// getResponse().sendRedirect("internal?tag=" + tag);
}
return JsonMessage.getString(200, "");
}
/**
* 下载文件
*
* @param response response
* @param fileName 文件名字
*/
private void downLoad(HttpServletResponse response, String fileName) {
//获取项目根路径
File file = new File(fileName);
ServletUtil.write(response, file);
FileUtil.del(file);
}
}

View File

@ -0,0 +1,263 @@
package cn.keepbx.jpom.controller.system;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.jiangzeyin.controller.multipart.MultipartFileBuilder;
import cn.keepbx.jpom.common.BaseAgentController;
import cn.keepbx.jpom.model.data.CertModel;
import cn.keepbx.jpom.service.WhitelistDirectoryService;
import cn.keepbx.jpom.service.system.CertService;
import cn.keepbx.jpom.system.AgentConfigBean;
import com.alibaba.fastjson.JSONObject;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* 证书管理
*
* @author Arno
*/
@RestController
@RequestMapping(value = "/system/certificate")
public class CertificateController extends BaseAgentController {
@Resource
private CertService certService;
@Resource
private WhitelistDirectoryService whitelistDirectoryService;
/**
* 保存证书
*
* @return json
*/
@RequestMapping(value = "/saveCertificate", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String saveCertificate() {
String data = getParameter("data");
JSONObject jsonObject = JSONObject.parseObject(data);
String type = jsonObject.getString("type");
String id = jsonObject.getString("id");
try {
CertModel certModel;
if ("add".equalsIgnoreCase(type)) {
if (certService.getItem(id) != null) {
return JsonMessage.getString(405, "证书id已经存在啦");
}
certModel = new CertModel();
String error = getCertModel(certModel, jsonObject);
if (error != null) {
return error;
}
if (!hasFile()) {
return JsonMessage.getString(405, "请选择证书包文件");
}
error = getCertFile(certModel, true);
if (error != null) {
return error;
}
certService.addItem(certModel);
} else {
certModel = certService.getItem(id);
if (certModel == null) {
return JsonMessage.getString(404, "没有找到对应证书文件");
}
String name = jsonObject.getString("name");
if (StrUtil.isEmpty(name)) {
return JsonMessage.getString(400, "请填写证书名称");
}
certModel.setName(name);
if (ServletFileUpload.isMultipartContent(getRequest()) && hasFile()) {
String error = getCertFile(certModel, false);
if (error != null) {
return error;
}
}
if (!certService.updateItem(certModel)) {
return JsonMessage.getString(406, "修改失败");
}
}
} catch (Exception e) {
DefaultSystemLog.ERROR().error("证书文件", e);
return JsonMessage.getString(400, e.getMessage());
}
return JsonMessage.getString(200, "提交成功");
}
/**
* 获取证书信息
*
* @param certModel 实体
* @return 错误消息
*/
private String getCertModel(CertModel certModel, JSONObject jsonObject) {
String id = jsonObject.getString("id");
String path = jsonObject.getString("path");
String name = jsonObject.getString("name");
if (StrUtil.isEmpty(id)) {
return JsonMessage.getString(400, "请填写证书id");
}
if (Validator.isChinese(id)) {
return JsonMessage.getString(400, "证书id不能使用中文");
}
if (StrUtil.isEmpty(name)) {
return JsonMessage.getString(400, "请填写证书名称");
}
if (!whitelistDirectoryService.checkCertificateDirectory(path)) {
return JsonMessage.getString(400, "请选择正确的项目路径,或者还没有配置白名单");
}
certModel.setId(id);
certModel.setWhitePath(path);
certModel.setName(name);
return null;
}
private String getCertFile(CertModel certModel, boolean add) throws IOException {
String certPath = null;
String pemPath = null, keyPath = null;
try {
String path = AgentConfigBean.getInstance().getTempPathName();
MultipartFileBuilder cert = createMultipart().addFieldName("file").setSavePath(path);
certPath = cert.save();
ZipFile zipFile = new ZipFile(certPath);
Enumeration<? extends ZipEntry> zipEntryEnumeration = zipFile.entries();
while (zipEntryEnumeration.hasMoreElements()) {
ZipEntry zipEntry = zipEntryEnumeration.nextElement();
if (zipEntry.isDirectory()) {
continue;
}
String keyName = zipEntry.getName();
if (pemPath == null && StrUtil.endWith(keyName, ".pem", true)) {
String filePathItem = String.format("%s/%s/%s", path, certModel.getId(), keyName);
InputStream inputStream = zipFile.getInputStream(zipEntry);
FileUtil.writeFromStream(inputStream, filePathItem);
pemPath = filePathItem;
}
//
if (keyPath == null && StrUtil.endWith(keyName, ".key", true)) {
String filePathItem = String.format("%s/%s/%s", path, certModel.getId(), keyName);
InputStream inputStream = zipFile.getInputStream(zipEntry);
FileUtil.writeFromStream(inputStream, filePathItem);
keyPath = filePathItem;
}
if (pemPath != null && keyPath != null) {
break;
}
}
if (pemPath == null || keyPath == null) {
return JsonMessage.getString(405, "证书包中文件不完整需要包含key、pem");
}
JSONObject jsonObject = CertModel.decodeCert(pemPath, keyPath);
if (jsonObject == null) {
return JsonMessage.getString(405, "解析证书失败");
}
String domain = jsonObject.getString("domain");
if (add) {
List<CertModel> array = certService.list();
if (array != null) {
for (CertModel certModel1 : array) {
if (StrUtil.emptyToDefault(domain, "").equals(certModel1.getDomain())) {
return JsonMessage.getString(405, "证书的域名已经存在啦");
}
}
}
} else {
if (!StrUtil.emptyToDefault(domain, "").equals(certModel.getDomain())) {
return JsonMessage.getString(405, "新证书的域名不一致");
}
}
// 移动位置
String temporary = certModel.getWhitePath() + "/" + certModel.getId() + "/";
File pemFile = FileUtil.file(temporary + certModel.getId() + ".pem");
File keyFile = FileUtil.file(temporary + certModel.getId() + ".key");
if (add) {
if (pemFile.exists()) {
return JsonMessage.getString(405, pemFile.getAbsolutePath() + " 已经被占用啦");
}
if (keyFile.exists()) {
return JsonMessage.getString(405, keyFile.getAbsolutePath() + " 已经被占用啦");
}
}
FileUtil.move(FileUtil.file(pemPath), pemFile, true);
FileUtil.move(FileUtil.file(keyPath), keyFile, true);
certModel.setCert(pemFile.getAbsolutePath());
certModel.setKey(keyFile.getAbsolutePath());
//
certModel.setDomain(domain);
certModel.setExpirationTime(jsonObject.getLongValue("expirationTime"));
certModel.setEffectiveTime(jsonObject.getLongValue("effectiveTime"));
} finally {
if (certPath != null) {
FileUtil.del(certPath);
}
}
return null;
}
/**
* 证书列表
*/
@RequestMapping(value = "/getCertList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String getCertList() {
List<CertModel> array = certService.list();
return JsonMessage.getString(200, "", array);
}
/**
* 删除证书
*
* @param id id
* @return json
*/
@RequestMapping(value = "/delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String delete(String id) {
if (StrUtil.isEmpty(id)) {
return JsonMessage.getString(400, "删除失败");
}
if (!isSystemUser()) {
return JsonMessage.getString(400, "你没有操作权限");
}
boolean b = certService.delete(id);
if (!b) {
return JsonMessage.getString(400, "删除失败");
}
return JsonMessage.getString(200, "删除成功");
}
/**
* 导出证书
*/
@RequestMapping(value = "/export", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String export(String id) {
CertModel item = certService.getItem(id);
if (null == item) {
return JsonMessage.getString(400, "导出失败");
}
String parent = FileUtil.file(item.getCert()).getParent();
File zip = ZipUtil.zip(parent);
ServletUtil.write(getResponse(), zip);
FileUtil.del(zip);
return JsonMessage.getString(400, "导出成功");
}
}

View File

@ -0,0 +1,206 @@
package cn.keepbx.jpom.controller.system;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseAgentController;
import cn.keepbx.jpom.service.WhitelistDirectoryService;
import cn.keepbx.jpom.service.system.NginxService;
import cn.keepbx.jpom.util.CommandUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.odiszapc.nginxparser.NgxBlock;
import com.github.odiszapc.nginxparser.NgxConfig;
import com.github.odiszapc.nginxparser.NgxEntry;
import com.github.odiszapc.nginxparser.NgxParam;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author jiangzeyin
* @date 2019/4/17
*/
@RestController
@RequestMapping("/system/nginx")
public class NginxController extends BaseAgentController {
@Resource
private NginxService nginxService;
@Resource
private WhitelistDirectoryService whitelistDirectoryService;
/**
* 配置列表
*/
@RequestMapping(value = "list_data.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String list() {
JSONArray array = nginxService.list();
return JsonMessage.getString(200, "", array);
}
@RequestMapping(value = "item_data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String itemData(String path, String name, String type) {
name = pathSafe(name);
if (whitelistDirectoryService.checkNgxDirectory(path)) {
File file = FileUtil.file(path, name);
JSONObject jsonObject = new JSONObject();
String string = FileUtil.readUtf8String(file);
jsonObject.put("context", string);
jsonObject.put("name", nginxService.paresName(path, file.getAbsolutePath()));
jsonObject.put("whitePath", path);
return JsonMessage.getString(200, "", jsonObject);
// setAttribute("data", jsonObject);
}
return JsonMessage.getString(400, "错误");
}
/**
* 新增或修改配置
*
* @param name 文件名
* @param whitePath 白名单路径
*/
@RequestMapping(value = "updateNgx", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String updateNgx(String name, String whitePath, String context, String genre) {
if (StrUtil.isEmpty(name)) {
return JsonMessage.getString(400, "请填写文件名");
}
if (!name.endsWith(".conf")) {
return JsonMessage.getString(400, "文件后缀必须为\".conf\"");
}
if (!checkPathSafe(name)) {
return JsonMessage.getString(400, "文件名存在非法字符");
}
if (!whitelistDirectoryService.checkNgxDirectory(whitePath)) {
return JsonMessage.getString(400, "请选择正确的白名单");
}
//nginx文件
File file = FileUtil.file(whitePath, name);
if ("add".equals(genre) && file.exists()) {
return JsonMessage.getString(400, "该文件已存在");
}
if (StrUtil.isEmpty(context)) {
return JsonMessage.getString(400, "请填写配置信息");
}
InputStream inputStream = new ByteArrayInputStream(context.getBytes());
try {
NgxConfig conf = NgxConfig.read(inputStream);
List<NgxEntry> list = conf.findAll(NgxBlock.class, "server");
if (list == null || list.size() <= 0) {
return JsonMessage.getString(404, "内容解析为空");
}
for (NgxEntry ngxEntry : list) {
NgxBlock ngxBlock = (NgxBlock) ngxEntry;
// 检查日志路径
NgxParam accessLog = ngxBlock.findParam("access_log");
if (accessLog != null) {
FileUtil.mkParentDirs(accessLog.getValue());
}
accessLog = ngxBlock.findParam("error_log");
if (accessLog != null) {
FileUtil.mkParentDirs(accessLog.getValue());
}
// 检查证书文件
NgxParam sslCertificate = ngxBlock.findParam("ssl_certificate");
if (sslCertificate != null && !FileUtil.exist(sslCertificate.getValue())) {
return JsonMessage.getString(404, "证书文件ssl_certificate,不存在");
}
NgxParam sslCertificateKey = ngxBlock.findParam("ssl_certificate_key");
if (sslCertificateKey != null && !FileUtil.exist(sslCertificateKey.getValue())) {
return JsonMessage.getString(404, "证书文件ssl_certificate_key,不存在");
}
if (!checkRootRole(ngxBlock)) {
return JsonMessage.getString(405, "非系统管理员,不能配置静态资源代理");
}
}
} catch (IOException e) {
DefaultSystemLog.ERROR().error("解析失败", e);
return JsonMessage.getString(500, "解析失败");
}
try {
FileUtil.writeString(context, file, CharsetUtil.UTF_8);
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
return JsonMessage.getString(400, "操作失败:" + e.getMessage());
}
String msg = this.reloadNginx();
return JsonMessage.getString(200, "提交成功" + msg);
}
private String reloadNginx() {
try {
String msg = CommandUtil.execSystemCommand("nginx -s reload");
if (StrUtil.isNotEmpty(msg)) {
DefaultSystemLog.LOG().info(msg);
return "(" + msg + ")";
}
} catch (Exception e) {
DefaultSystemLog.ERROR().error("reload nginx error", e);
}
return StrUtil.EMPTY;
}
/**
* 权限检查 防止非系统管理员配置静态资源访问
*
* @return false 不正确
*/
private boolean checkRootRole(NgxBlock ngxBlock) {
// UserModel userModel = getUser();
List<NgxEntry> locationAll = ngxBlock.findAll(NgxBlock.class, "location");
if (locationAll != null) {
for (NgxEntry ngxEntry1 : locationAll) {
NgxBlock ngxBlock1 = (NgxBlock) ngxEntry1;
NgxParam locationMain = ngxBlock1.findParam("root");
if (locationMain == null) {
locationMain = ngxBlock1.findParam("alias");
}
if (locationMain != null && !isSystemUser()) {
return false;
}
}
}
return true;
}
/**
* 删除配置
*
* @param path 文件路径
*/
@RequestMapping(value = "delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String delete(String path, String name) {
if (!whitelistDirectoryService.checkNgxDirectory(path)) {
return JsonMessage.getString(400, "非法操作");
}
path = pathSafe(path);
name = pathSafe(name);
if (StrUtil.isEmpty(name)) {
return JsonMessage.getString(400, "删除失败,请正常操作");
}
File file = FileUtil.file(path, name);
try {
FileUtil.rename(file, file.getName() + "_back", false, true);
} catch (Exception e) {
DefaultSystemLog.ERROR().error("删除nginx", e);
return JsonMessage.getString(400, "删除失败:" + e.getMessage());
}
String msg = this.reloadNginx();
return JsonMessage.getString(200, "删除成功" + msg);
}
}

View File

@ -26,6 +26,8 @@ import java.util.Date;
* @author Arno
*/
public class CertModel extends BaseModel {
private static final String KEY = "Jpom 管理系统";
private String name;
/**
* 证书文件
@ -146,10 +148,10 @@ public class CertModel extends BaseModel {
PrivateKey privateKey = BCUtil.readPrivateKey(ResourceUtil.getStream(key));
PublicKey publicKey = BCUtil.readPublicKey(ResourceUtil.getStream(file));
RSA rsa = new RSA(privateKey, publicKey);
String str = UserModel.SYSTEM_OCCUPY_NAME;
String encryptStr = rsa.encryptBase64(str, KeyType.PublicKey);
// String str = KEY;
String encryptStr = rsa.encryptBase64(KEY, KeyType.PublicKey);
String decryptStr = rsa.decryptStr(encryptStr, KeyType.PrivateKey);
if (!str.equals(decryptStr)) {
if (!KEY.equals(decryptStr)) {
throw new JpomRuntimeException("证书和私钥证书不匹配");
}
try {

View File

@ -1,5 +1,7 @@
package cn.keepbx.jpom.service;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.keepbx.jpom.common.BaseDataService;
import cn.keepbx.jpom.model.data.Whitelist;
@ -8,6 +10,7 @@ import cn.keepbx.jpom.util.JsonFileUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.List;
/**
@ -30,6 +33,14 @@ public class WhitelistDirectoryService extends BaseDataService {
return null;
}
private List<String> getNgxDirectory() {
Whitelist whitelist = getWhitelist();
if (whitelist == null) {
return null;
}
return whitelist.getNginx();
}
public boolean checkProjectDirectory(String path) {
Whitelist whitelist = getWhitelist();
if (whitelist == null) {
@ -41,22 +52,44 @@ public class WhitelistDirectoryService extends BaseDataService {
}
return list.contains(path);
}
//
// public boolean checkNgxDirectory(String path) {
// List<String> list = getNgxDirectory();
// if (list == null) {
// return false;
// }
// return list.contains(path);
// }
//
// public boolean checkCertificateDirectory(String path) {
// List<String> list = getCertificateDirectory();
// if (list == null) {
// return false;
// }
// return list.contains(path);
// }
public boolean checkNgxDirectory(String path) {
List<String> list = getNgxDirectory();
if (list == null) {
return false;
}
return checkPath(list, path);
}
private boolean checkPath(List<String> list, String path) {
if (StrUtil.isEmpty(path)) {
return false;
}
File file1, file2 = FileUtil.file(path);
for (String item : list) {
file1 = FileUtil.file(item);
if (FileUtil.pathEquals(file1, file2)) {
return true;
}
}
return false;
}
private List<String> getCertificateDirectory() {
Whitelist whitelist = getWhitelist();
if (whitelist == null) {
return null;
}
return whitelist.getCertificate();
}
public boolean checkCertificateDirectory(String path) {
List<String> list = getCertificateDirectory();
if (list == null) {
return false;
}
return checkPath(list, path);
}
// private JSONArray getItemArray(String key) {
// try {

View File

@ -5,7 +5,7 @@ import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.keepbx.jpom.common.BaseOperService;
import cn.keepbx.jpom.model.data.CertModel;
import cn.keepbx.jpom.system.ServerConfigBean;
import cn.keepbx.jpom.system.AgentConfigBean;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
@ -27,7 +27,7 @@ public class CertService extends BaseOperService<CertModel> {
*/
@Override
public void addItem(CertModel certModel) {
saveJson(ServerConfigBean.CERT, certModel.toJson());
saveJson(AgentConfigBean.CERT, certModel.toJson());
}
/**
@ -37,7 +37,7 @@ public class CertService extends BaseOperService<CertModel> {
*/
@Override
public List<CertModel> list() {
JSONObject jsonObject = getJSONObject(ServerConfigBean.CERT);
JSONObject jsonObject = getJSONObject(AgentConfigBean.CERT);
if (jsonObject == null) {
return null;
}
@ -47,7 +47,7 @@ public class CertService extends BaseOperService<CertModel> {
@Override
public CertModel getItem(String id) {
return getJsonObjectById(ServerConfigBean.CERT, id, CertModel.class);
return getJsonObjectById(AgentConfigBean.CERT, id, CertModel.class);
}
@ -63,7 +63,7 @@ public class CertService extends BaseOperService<CertModel> {
return true;
}
String keyPath = certModel.getCert();
deleteJson(ServerConfigBean.CERT, id);
deleteJson(AgentConfigBean.CERT, id);
if (StrUtil.isNotEmpty(keyPath)) {
// 删除证书文件
File parentFile = FileUtil.file(keyPath).getParentFile();
@ -84,7 +84,7 @@ public class CertService extends BaseOperService<CertModel> {
@Override
public boolean updateItem(CertModel certModel) {
try {
updateJson(ServerConfigBean.CERT, certModel.toJson());
updateJson(AgentConfigBean.CERT, certModel.toJson());
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
return false;

View File

@ -6,6 +6,8 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.keepbx.jpom.common.BaseOperService;
import cn.keepbx.jpom.model.data.Whitelist;
import cn.keepbx.jpom.service.WhitelistDirectoryService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.odiszapc.nginxparser.NgxBlock;
@ -31,7 +33,11 @@ public class NginxService extends BaseOperService {
@Override
public JSONArray list() {
List<String> ngxDirectory = whitelistDirectoryService.getNgxDirectory(null);
Whitelist whitelist = whitelistDirectoryService.getWhitelist();
if (whitelist == null) {
return null;
}
List<String> ngxDirectory = whitelist.getNginx();
if (ngxDirectory == null) {
return null;
}

View File

@ -1,6 +1,7 @@
package cn.keepbx.jpom.socket;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.jiangzeyin.common.spring.SpringUtil;
@ -17,23 +18,28 @@ import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author jiangzeyin
* @date 2019/4/16
*/
@ServerEndpoint(value = "/console/{projectId}")
@ServerEndpoint(value = "/console/{projectId}/{optUser}")
@Component
public class AgentWebSocketHandle {
private static final ConcurrentHashMap<String, String> USER = new ConcurrentHashMap<>();
private static ProjectInfoService projectInfoService;
@OnOpen
public void onOpen(@PathParam("projectId") String projectId, Session session) {
public void onOpen(@PathParam("projectId") String projectId, @PathParam("optUser") String optUser, Session session) {
System.out.println(projectId);
try {
// 判断项目
if (!WebSocketConfig.SYSTEM_ID.equals(projectId)) {
ProjectInfoService projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
if (projectInfoService == null) {
projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
}
ProjectInfoModel projectInfoModel = projectInfoService.getItem(projectId);
if (projectInfoModel == null) {
SocketSessionUtil.send(session, "获取项目信息错误");
@ -41,6 +47,7 @@ public class AgentWebSocketHandle {
return;
}
}
USER.put(session.getId(), optUser);
} catch (Exception e) {
DefaultSystemLog.ERROR().error("socket 错误", e);
try {
@ -50,7 +57,22 @@ public class AgentWebSocketHandle {
DefaultSystemLog.ERROR().error(e1.getMessage(), e1);
}
}
}
private String getOptUserName(Session session) {
String name = USER.get(session.getId());
return StrUtil.emptyToDefault(name, StrUtil.DASHED);
}
private boolean silentMsg(CommandOp commandOp, Session session) {
if (commandOp == CommandOp.heart) {
return true;
}
if (commandOp == CommandOp.top) {
TopManager.addMonitor(session);
return true;
}
return false;
}
@OnMessage
@ -58,21 +80,21 @@ public class AgentWebSocketHandle {
JSONObject json = JSONObject.parseObject(message);
String op = json.getString("op");
CommandOp commandOp = CommandOp.valueOf(op);
if (commandOp == CommandOp.heart) {
return;
}
if (commandOp == CommandOp.top) {
TopManager.addMonitor(session);
if (silentMsg(commandOp, session)) {
return;
}
String projectId = json.getString("projectId");
ProjectInfoService projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
ProjectInfoModel projectInfoModel = projectInfoService.getItem(projectId);
System.out.println(op + " " + projectId);
if (projectInfoModel == null) {
SocketSessionUtil.send(session, "没有对应项目");
return;
}
runMsg(commandOp, session, projectInfoModel);
}
private void runMsg(CommandOp commandOp, Session session, ProjectInfoModel projectInfoModel) throws Exception {
ConsoleService consoleService = SpringUtil.getBean(ConsoleService.class);
JSONObject resultData = null;
String strResult;
@ -121,7 +143,7 @@ public class AgentWebSocketHandle {
break;
}
default:
resultData = JsonMessage.toJson(404, "不支持的方式:" + op);
resultData = JsonMessage.toJson(404, "不支持的方式:" + commandOp.name());
break;
}
} catch (Exception e) {
@ -132,14 +154,15 @@ public class AgentWebSocketHandle {
} finally {
if (logUser) {
// 记录操作人
projectInfoModel = projectInfoService.getItem(projectId);
// projectInfoModel.logModifyUser(userModel);
projectInfoModel = projectInfoService.getItem(projectInfoModel.getId());
String name = getOptUserName(session);
projectInfoModel.setModifyUser(name);
projectInfoService.updateItem(projectInfoModel);
}
}
//
if (resultData != null) {
resultData.put("op", op);
resultData.put("op", commandOp.name());
DefaultSystemLog.LOG().info(resultData.toString());
SocketSessionUtil.send(session, resultData.toString());
}
@ -160,6 +183,7 @@ public class AgentWebSocketHandle {
} catch (Exception e) {
DefaultSystemLog.ERROR().error("关闭异常", e);
}
USER.remove(session.getId());
}
@OnError

View File

@ -36,6 +36,12 @@ public class AgentConfigBean {
*/
public static final String ALI_OSS = "aliOss.json";
/**
* 证书文件
*/
public static final String CERT = "cert.json";
private static AgentConfigBean agentConfigBean;
/**

View File

@ -16,6 +16,36 @@ public class AgentExtConfigBean {
@Value("${whitelistDirectory.checkStartsWith:true}")
public boolean whitelistDirectoryCheckStartsWith;
/**
* 自动备份控制台日志防止日志文件过大目前暂只支持linux 不停服备份 如果配置none 则不自动备份 默认10分钟扫描一次
*/
@Value("${log.autoBackConsoleCron:0 0/10 * * * ?}")
public String autoBackConsoleCron;
/**
* 当文件多大时自动备份
*
* @see ch.qos.logback.core.util.FileSize
*/
@Value("${log.autoBackSize:50MB}")
public String autoBackSize;
/**
* 控制台日志保存时长单位天
*/
@Value("${log.saveDays:7}")
private int logSaveDays;
/**
* 配置错误或者没有默认是7天
*
* @return int
*/
public int getLogSaveDays() {
if (logSaveDays <= 0) {
return 7;
}
return logSaveDays;
}
/**
* 单例
*

View File

@ -1,9 +1,23 @@
package cn.keepbx.jpom.system.init;
import ch.qos.logback.core.util.FileSize;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil;
import cn.hutool.cron.Scheduler;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.PreLoadClass;
import cn.jiangzeyin.common.PreLoadMethod;
import cn.jiangzeyin.common.spring.SpringUtil;
import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
import cn.keepbx.jpom.model.data.ProjectInfoModel;
import cn.keepbx.jpom.service.manage.ProjectInfoService;
import cn.keepbx.jpom.system.AgentExtConfigBean;
import java.io.File;
import java.util.List;
/**
* 自动备份控制台日志防止日志文件过大
@ -15,7 +29,7 @@ import cn.jiangzeyin.common.PreLoadMethod;
public class AutoBackLog {
private static final String ID = "auto_back_log";
// private static ProjectInfoService projectInfoService;
private static ProjectInfoService projectInfoService;
private static FileSize MAX_SIZE;
@ -23,55 +37,55 @@ public class AutoBackLog {
private static void startAutoBackLog() {
// 开启秒级表达式
CronUtil.setMatchSecond(true);
// if (projectInfoService == null) {
// projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
// }
// // 获取cron 表达式
// String cron = StrUtil.emptyToDefault(ServerExtConfigBean.getInstance().autoBackConsoleCron, "none");
// if ("none".equalsIgnoreCase(cron.trim())) {
// DefaultSystemLog.LOG().info("没有配置自动备份控制台日志表达式");
// return;
// }
// String size = StrUtil.emptyToDefault(ServerExtConfigBean.getInstance().autoBackSize, "50MB");
// MAX_SIZE = FileSize.valueOf(size.trim());
// //
// CronUtil.schedule(ID, cron, () -> {
// try {
// List<ProjectInfoModel> list = projectInfoService.list();
// if (list == null) {
// return;
// }
// list.forEach(projectInfoModel -> {
// String log = projectInfoModel.getLog();
// File file = new File(log);
// if (!file.exists()) {
// return;
// }
// long len = file.length();
// if (len > MAX_SIZE.getSize()) {
// try {
// AbstractProjectCommander.getInstance().backLog(projectInfoModel);
// } catch (Exception ignored) {
// }
// }
// // 清理过期的文件
// File logFile = projectInfoModel.getLogBack();
// DateTime nowTime = DateTime.now();
// List<File> files = FileUtil.loopFiles(logFile, pathname -> {
// DateTime dateTime = DateUtil.date(pathname.lastModified());
// long days = DateUtil.betweenDay(dateTime, nowTime, false);
// long saveDays = ServerExtConfigBean.getInstance().getLogSaveDays();
// return days > saveDays;
// });
// files.forEach(FileUtil::del);
// });
// } catch (Exception e) {
// DefaultSystemLog.ERROR().error("定时备份日志失败", e);
// }
// });
// Scheduler scheduler = CronUtil.getScheduler();
// if (!scheduler.isStarted()) {
// CronUtil.start();
// }
if (projectInfoService == null) {
projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
}
// 获取cron 表达式
String cron = StrUtil.emptyToDefault(AgentExtConfigBean.getInstance().autoBackConsoleCron, "none");
if ("none".equalsIgnoreCase(cron.trim())) {
DefaultSystemLog.LOG().info("没有配置自动备份控制台日志表达式");
return;
}
String size = StrUtil.emptyToDefault(AgentExtConfigBean.getInstance().autoBackSize, "50MB");
MAX_SIZE = FileSize.valueOf(size.trim());
//
CronUtil.schedule(ID, cron, () -> {
try {
List<ProjectInfoModel> list = projectInfoService.list();
if (list == null) {
return;
}
list.forEach(projectInfoModel -> {
String log = projectInfoModel.getLog();
File file = new File(log);
if (!file.exists()) {
return;
}
long len = file.length();
if (len > MAX_SIZE.getSize()) {
try {
AbstractProjectCommander.getInstance().backLog(projectInfoModel);
} catch (Exception ignored) {
}
}
// 清理过期的文件
File logFile = projectInfoModel.getLogBack();
DateTime nowTime = DateTime.now();
List<File> files = FileUtil.loopFiles(logFile, pathname -> {
DateTime dateTime = DateUtil.date(pathname.lastModified());
long days = DateUtil.betweenDay(dateTime, nowTime, false);
long saveDays = AgentExtConfigBean.getInstance().getLogSaveDays();
return days > saveDays;
});
files.forEach(FileUtil::del);
});
} catch (Exception e) {
DefaultSystemLog.ERROR().error("定时备份日志失败", e);
}
});
Scheduler scheduler = CronUtil.getScheduler();
if (!scheduler.isStarted()) {
CronUtil.start();
}
}
}

View File

@ -5,6 +5,8 @@ import cn.keepbx.jpom.model.BaseJsonModel;
import java.util.List;
/**
* 白名单
*
* @author jiangzeyin
* @date 2019/4/16
*/

View File

@ -49,14 +49,7 @@ public abstract class BaseController extends BaseJpomController {
}
public static String getOptUserName() {
UserModel userModel = getUserModel();
String userId;
if (userModel.isSystemUser()) {
userId = UserModel.SYSTEM_OCCUPY_NAME;
} else {
userId = userModel.getId();
}
return userId;
return UserModel.getOptUserName(getUserModel());
}
}

View File

@ -8,6 +8,7 @@ import cn.hutool.http.HttpUtil;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.data.NodeModel;
import cn.keepbx.jpom.model.data.UserModel;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.multipart.MultipartFile;
@ -17,8 +18,11 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
/**
* 节点请求转发
*
* @author jiangzeyin
* @date 2019/4/16
*/
@ -39,10 +43,27 @@ public class NodeForward {
return JSON.parseObject(body, JsonMessage.class);
}
public static <T> T requestData(NodeModel nodeModel, NodeUrl nodeUrl, HttpServletRequest request, Class<T> tClass) {
JsonMessage jsonMessage = request(nodeModel, request, nodeUrl);
return toObj(jsonMessage, tClass);
}
public static <T> T requestData(NodeModel nodeModel, NodeUrl nodeUrl, Class<T> tClass) {
return requestData(nodeModel, nodeUrl, tClass, null, null);
}
private static <T> T toObj(JsonMessage jsonMessage, Class<T> tClass) {
Object data = jsonMessage.getData();
if (jsonMessage.getCode() == 200 && null != data) {
if (tClass == String.class) {
return (T) data.toString();
}
return JSONObject.parseObject(data.toString(), tClass);
}
System.out.println(jsonMessage.toString());
return null;
}
public static <T> T requestData(NodeModel nodeModel, NodeUrl nodeUrl, Class<T> tClass, String name, Object value, Object... parameters) {
String url = StrUtil.format("http://{}{}", nodeModel.getUrl(), nodeUrl.getUrl());
//
@ -57,15 +78,7 @@ public class NodeForward {
.execute()
.body();
JsonMessage jsonMessage = JSON.parseObject(body, JsonMessage.class);
Object data = jsonMessage.getData();
if (jsonMessage.getCode() == 200 && null != data) {
if (tClass == String.class) {
return (T) data.toString();
}
return JSONObject.parseObject(data.toString(), tClass);
}
System.out.println(jsonMessage.toString());
return null;
return toObj(jsonMessage, tClass);
}
public static JsonMessage requestMultipart(NodeModel nodeModel, MultipartHttpServletRequest request, NodeUrl nodeUrl) {
@ -111,7 +124,10 @@ public class NodeForward {
private static void addUser(HttpRequest httpRequest) {
httpRequest.header("Jpom-Server-UserName", BaseController.getOptUserName());
UserModel userModel = BaseController.getUserModel();
Objects.requireNonNull(userModel);
httpRequest.header("Jpom-Server-UserName", UserModel.getOptUserName(userModel));
httpRequest.header("Jpom-Server-SystemUserRole", String.valueOf(userModel.isSystemUser()));
}
public static String getSocketUrl(NodeModel nodeModel, NodeUrl nodeUrl) {

View File

@ -5,6 +5,10 @@ package cn.keepbx.jpom.common.forward;
* @date 2019/4/16
*/
public enum NodeUrl {
/**
* Jpom agent 信息
*/
Info("/info"),
/**
*
*/
@ -70,6 +74,26 @@ public enum NodeUrl {
Manage_build_install("/manage/build_install"),
Manage_internal_data("/manage/internal_data"),
Manage_internal_stack("/manage/internal_stack"),
Manage_internal_ram("/manage/internal_ram"),
System_Nginx_list_data("/system/nginx/list_data.json"),
System_Nginx_item_data("/system/nginx/item_data"),
System_Nginx_updateNgx("/system/nginx/updateNgx"),
System_Nginx_delete("/system/nginx/delete"),
System_Certificate_saveCertificate("/system/certificate/saveCertificate"),
System_Certificate_getCertList("/system/certificate/getCertList"),
System_Certificate_delete("/system/certificate/delete"),
System_Certificate_export("/system/certificate/export"),
;
private String url;

View File

@ -1,8 +1,11 @@
package cn.keepbx.jpom.controller.node;
import cn.hutool.core.util.StrUtil;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.BaseNodeController;
import cn.keepbx.jpom.common.forward.NodeForward;
import cn.keepbx.jpom.common.forward.NodeUrl;
import cn.keepbx.jpom.model.data.NodeModel;
import cn.keepbx.jpom.model.system.JpomManifest;
import cn.keepbx.jpom.service.node.NodeService;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
@ -20,7 +23,7 @@ import java.util.List;
*/
@Controller
@RequestMapping(value = "/node")
public class NodeIndexController extends BaseController {
public class NodeIndexController extends BaseNodeController {
@Resource
private NodeService nodeService;
@ -35,10 +38,14 @@ public class NodeIndexController extends BaseController {
@RequestMapping(value = "index.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String index(String nodeId) {
NodeModel nodeModel = nodeService.getItem(nodeId);
System.out.println(nodeModel);
if (nodeModel != null) {
setAttribute("node", nodeModel);
}
List<NodeModel> nodeModels = nodeService.list();
setAttribute("array", nodeModels);
//
JpomManifest jpomManifest = NodeForward.requestData(getNode(), NodeUrl.Info, getRequest(), JpomManifest.class);
setAttribute("jpomManifest", jpomManifest);
return "node/index";
}

View File

@ -1,162 +1,50 @@
//package cn.keepbx.jpom.controller.node.monitor;
//
//import cn.hutool.core.io.FileUtil;
//import cn.hutool.extra.servlet.ServletUtil;
//import cn.jiangzeyin.common.DefaultSystemLog;
//import cn.jiangzeyin.common.JsonMessage;
//import cn.keepbx.jpom.common.BaseController;
//import cn.keepbx.jpom.common.commander.AbstractProjectCommander;
//import cn.keepbx.jpom.model.system.NetstatModel;
//import cn.keepbx.jpom.system.ServerConfigBean;
//import cn.keepbx.jpom.util.CommandUtil;
//import cn.keepbx.jpom.util.JvmUtil;
//import com.alibaba.fastjson.JSONObject;
//import com.sun.tools.attach.VirtualMachine;
//import org.springframework.http.MediaType;
//import org.springframework.stereotype.Controller;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RequestMethod;
//import org.springframework.web.bind.annotation.ResponseBody;
//
//import javax.servlet.http.HttpServletResponse;
//import java.io.File;
//import java.lang.management.MemoryMXBean;
//import java.lang.management.MemoryUsage;
//import java.math.BigDecimal;
//import java.util.List;
//
///**
// * 内存查看
// *
// * @author Administrator
// */
//@Controller
//@RequestMapping(value = "/node/manage/")
//public class InternalController extends BaseController {
//
// /**
// * 获取内存信息
// */
// @RequestMapping(value = "internal", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
// public String getInternal(String tag) throws Exception {
// setAttribute("tag", tag);
// int pid = AbstractProjectCommander.getInstance().getPid(tag);
// if (pid > 0) {
//// ProcessModel item = AbstractSystemCommander.getInstance().getPidInfo(pid);
//// setAttribute("item", item);
// JSONObject beanMem = getBeanMem(tag);
// setAttribute("beanMem", beanMem);
// //获取端口信息
// List<NetstatModel> port = AbstractProjectCommander.getInstance().listNetstat(pid);
// setAttribute("port", port);
// }
// return "node/manage/internal";
// }
//
// /**
// * 获取jvm内存
// *
// * @param tag tag
// * @return JSONObject
// */
// private JSONObject getBeanMem(String tag) {
// try {
// VirtualMachine virtualMachine = JvmUtil.getVirtualMachine(tag);
// MemoryMXBean memoryMXBean = JvmUtil.getMemoryMXBean(virtualMachine);
// if (memoryMXBean == null) {
// return null;
// }
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("mount", memoryMXBean.getObjectPendingFinalizationCount());
// //堆内存
// MemoryUsage memory = memoryMXBean.getHeapMemoryUsage();
// //非堆内存
// MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
// long used = memory.getUsed();
// long max = memory.getMax();
// //未定义
// if (-1 == max) {
// max = memory.getCommitted();
// }
// //计算使用内存占最大内存的百分比
// double v = new BigDecimal(used).divide(new BigDecimal(max), 2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
// jsonObject.put("heapUsed", FileUtil.readableFileSize(used));
// jsonObject.put("heapProportion", String.format("%.2f", v) + "%");
// jsonObject.put("heapCommitted", FileUtil.readableFileSize(memory.getCommitted()));
// long nonUsed = nonHeapMemoryUsage.getUsed();
// long nonMax = nonHeapMemoryUsage.getMax();
// long nonCommitted = nonHeapMemoryUsage.getCommitted();
// if (-1 == nonMax) {
// nonMax = nonCommitted;
// }
// jsonObject.put("nonHeapUsed", FileUtil.readableFileSize(nonUsed));
// double proportion = new BigDecimal(nonUsed).divide(new BigDecimal(nonMax), 2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
// jsonObject.put("nonHeapProportion", String.format("%.2f", proportion) + "%");
// jsonObject.put("nonHeapCommitted", FileUtil.readableFileSize(nonCommitted));
// return jsonObject;
// } catch (Exception e) {
// DefaultSystemLog.ERROR().error(e.getMessage(), e);
// }
// return null;
// }
//
//
// /**
// * 导出堆栈信息
// */
// @RequestMapping(value = "stack", method = RequestMethod.GET)
// @ResponseBody
// public String stack(String tag) throws Exception {
// String fileName = ServerConfigBean.getInstance().getTempPathName() + "/" + tag + "_java_cpu.txt";
// fileName = FileUtil.normalize(fileName);
// try {
// int pid = AbstractProjectCommander.getInstance().getPid(tag);
// if (pid <= 0) {
// return JsonMessage.getString(400, "未运行");
// }
// String command = String.format("jstack %s >> %s ", pid, fileName);
// CommandUtil.execSystemCommand(command);
// downLoad(getResponse(), fileName);
// } catch (Exception e) {
// DefaultSystemLog.ERROR().error(e.getMessage(), e);
// getResponse().sendRedirect("internal?tag=" + tag);
// }
// return JsonMessage.getString(200, "");
// }
//
// /**
// * 导出内存信息
// */
// @RequestMapping(value = "ram", method = RequestMethod.GET)
// @ResponseBody
// public String ram(String tag) throws Exception {
// String fileName = ServerConfigBean.getInstance().getTempPathName() + "/" + tag + "_java_ram.txt";
// fileName = FileUtil.normalize(fileName);
// try {
// int pid = AbstractProjectCommander.getInstance().getPid(tag);
// if (pid <= 0) {
// return JsonMessage.getString(400, "未运行");
// }
// String command = String.format("jmap -histo:live %s >> %s", pid, fileName);
// CommandUtil.execSystemCommand(command);
// downLoad(getResponse(), fileName);
// } catch (Exception e) {
// DefaultSystemLog.ERROR().error(e.getMessage(), e);
// getResponse().sendRedirect("internal?tag=" + tag);
// }
// return JsonMessage.getString(200, "");
// }
//
// /**
// * 下载文件
// *
// * @param response response
// * @param fileName 文件名字
// */
// private void downLoad(HttpServletResponse response, String fileName) {
// //获取项目根路径
// File file = new File(fileName);
// ServletUtil.write(response, file);
// FileUtil.del(file);
// }
//}
package cn.keepbx.jpom.controller.node.monitor;
import cn.keepbx.jpom.common.BaseNodeController;
import cn.keepbx.jpom.common.forward.NodeForward;
import cn.keepbx.jpom.common.forward.NodeUrl;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 内存查看
*
* @author Administrator
*/
@Controller
@RequestMapping(value = "/node/manage/")
public class InternalController extends BaseNodeController {
/**
* 获取内存信息
*/
@RequestMapping(value = "internal", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String getInternal(String tag) throws Exception {
setAttribute("tag", tag);
JSONObject data = NodeForward.requestData(getNode(), NodeUrl.Manage_internal_data, JSONObject.class, "tag", tag);
setAttribute("data", data);
return "node/manage/internal";
}
/**
* 导出堆栈信息
*/
@RequestMapping(value = "stack", method = RequestMethod.GET)
@ResponseBody
public void stack() {
NodeForward.requestDownload(getNode(), getRequest(), getResponse(), NodeUrl.Manage_internal_stack);
}
/**
* 导出内存信息
*/
@RequestMapping(value = "ram", method = RequestMethod.GET)
@ResponseBody
public void ram() throws Exception {
NodeForward.requestDownload(getNode(), getRequest(), getResponse(), NodeUrl.Manage_internal_ram);
}
}

View File

@ -1,26 +1,12 @@
package cn.keepbx.jpom.controller.node.system.nginx;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseNodeController;
import cn.keepbx.jpom.common.Role;
import cn.keepbx.jpom.common.forward.NodeForward;
import cn.keepbx.jpom.common.forward.NodeUrl;
import cn.keepbx.jpom.common.interceptor.UrlPermission;
import cn.keepbx.jpom.model.data.CertModel;
import cn.keepbx.jpom.model.data.UserModel;
import cn.keepbx.jpom.model.data.Whitelist;
import cn.keepbx.jpom.service.system.CertService;
import cn.keepbx.jpom.service.system.NginxService;
import cn.keepbx.jpom.service.system.WhitelistDirectoryService;
import cn.keepbx.jpom.util.CommandUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.odiszapc.nginxparser.NgxBlock;
import com.github.odiszapc.nginxparser.NgxConfig;
import com.github.odiszapc.nginxparser.NgxEntry;
import com.github.odiszapc.nginxparser.NgxParam;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@ -28,10 +14,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
@ -43,21 +25,12 @@ import java.util.List;
@RequestMapping("/node/system/nginx")
public class NginxController extends BaseNodeController {
@Resource
private WhitelistDirectoryService whitelistDirectoryService;
@Resource
private CertService certService;
@Resource
private NginxService nginxService;
@RequestMapping(value = "list.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String ngx() {
Whitelist ngxDirectory = whitelistDirectoryService.getData(getNode());
setAttribute("nginx", ngxDirectory.getNginx());
List<CertModel> certList = certService.list();
setAttribute("cert", certList);
return "node/system/nginx";
}
@ -68,168 +41,33 @@ public class NginxController extends BaseNodeController {
@ResponseBody
@UrlPermission(Role.Manage)
public String list() {
JSONArray array = nginxService.list();
return JsonMessage.getString(200, "", array);
return NodeForward.request(getNode(), getRequest(), NodeUrl.System_Nginx_list_data).toString();
}
@RequestMapping(value = "item.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String setting(String path, String name, String type) {
public String setting(String type) {
List<String> ngxDirectory = whitelistDirectoryService.getNgxDirectory(getNode());
setAttribute("nginx", ngxDirectory);
List<CertModel> certList = certService.list();
setAttribute("cert", certList);
setAttribute("type", type);
name = pathSafe(name);
if (StrUtil.isNotEmpty(path) && ngxDirectory != null && ngxDirectory.contains(path)) {
File file = FileUtil.file(path, name);
JSONObject jsonObject = new JSONObject();
String string = FileUtil.readUtf8String(file);
jsonObject.put("context", string);
jsonObject.put("name", nginxService.paresName(path, file.getAbsolutePath()));
jsonObject.put("whitePath", path);
setAttribute("data", jsonObject);
}
JSONObject data = NodeForward.requestData(getNode(), NodeUrl.System_Nginx_item_data, getRequest(), JSONObject.class);
setAttribute("data", data);
return "node/system/nginxSetting";
}
/**
* 新增或修改配置
*
* @param name 文件名
* @param whitePath 白名单路径
*/
@RequestMapping(value = "updateNgx", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
@UrlPermission(Role.Manage)
public String updateNgx(String name, String whitePath, String context, String genre) {
if (StrUtil.isEmpty(name)) {
return JsonMessage.getString(400, "请填写文件名");
}
if (!name.endsWith(".conf")) {
return JsonMessage.getString(400, "文件后缀必须为\".conf\"");
}
if (!checkPathSafe(name)) {
return JsonMessage.getString(400, "文件名存在非法字符");
}
// if (!whitelistDirectoryService.checkNgxDirectory(whitePath)) {
// return JsonMessage.getString(400, "请选择正确的白名单");
// }
//nginx文件
File file = FileUtil.file(whitePath, name);
if ("add".equals(genre) && file.exists()) {
return JsonMessage.getString(400, "该文件已存在");
}
if (StrUtil.isEmpty(context)) {
return JsonMessage.getString(400, "请填写配置信息");
}
InputStream inputStream = new ByteArrayInputStream(context.getBytes());
try {
NgxConfig conf = NgxConfig.read(inputStream);
List<NgxEntry> list = conf.findAll(NgxBlock.class, "server");
if (list == null || list.size() <= 0) {
return JsonMessage.getString(404, "内容解析为空");
}
for (NgxEntry ngxEntry : list) {
NgxBlock ngxBlock = (NgxBlock) ngxEntry;
// 检查日志路径
NgxParam accessLog = ngxBlock.findParam("access_log");
if (accessLog != null) {
FileUtil.mkParentDirs(accessLog.getValue());
}
accessLog = ngxBlock.findParam("error_log");
if (accessLog != null) {
FileUtil.mkParentDirs(accessLog.getValue());
}
// 检查证书文件
NgxParam sslCertificate = ngxBlock.findParam("ssl_certificate");
if (sslCertificate != null && !FileUtil.exist(sslCertificate.getValue())) {
return JsonMessage.getString(404, "证书文件ssl_certificate,不存在");
}
NgxParam sslCertificateKey = ngxBlock.findParam("ssl_certificate_key");
if (sslCertificateKey != null && !FileUtil.exist(sslCertificateKey.getValue())) {
return JsonMessage.getString(404, "证书文件ssl_certificate_key,不存在");
}
if (!checkRootRole(ngxBlock)) {
return JsonMessage.getString(405, "非系统管理员,不能配置静态资源代理");
}
}
} catch (IOException e) {
DefaultSystemLog.ERROR().error("解析失败", e);
return JsonMessage.getString(500, "解析失败");
}
try {
FileUtil.writeString(context, file, CharsetUtil.UTF_8);
} catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
return JsonMessage.getString(400, "操作失败:" + e.getMessage());
}
String msg = this.reloadNginx();
return JsonMessage.getString(200, "提交成功" + msg);
public String updateNgx() {
return NodeForward.request(getNode(), getRequest(), NodeUrl.System_Nginx_updateNgx).toString();
}
private String reloadNginx() {
try {
String msg = CommandUtil.execSystemCommand("nginx -s reload");
if (StrUtil.isNotEmpty(msg)) {
DefaultSystemLog.LOG().info(msg);
return "(" + msg + ")";
}
} catch (Exception e) {
DefaultSystemLog.ERROR().error("reload nginx error", e);
}
return StrUtil.EMPTY;
}
/**
* 权限检查 防止非系统管理员配置静态资源访问
*
* @return false 不正确
*/
private boolean checkRootRole(NgxBlock ngxBlock) {
UserModel userModel = getUser();
List<NgxEntry> locationAll = ngxBlock.findAll(NgxBlock.class, "location");
if (locationAll != null) {
for (NgxEntry ngxEntry1 : locationAll) {
NgxBlock ngxBlock1 = (NgxBlock) ngxEntry1;
NgxParam locationMain = ngxBlock1.findParam("root");
if (locationMain == null) {
locationMain = ngxBlock1.findParam("alias");
}
if (locationMain != null && !userModel.isSystemUser()) {
return false;
}
}
}
return true;
}
/**
* 删除配置
*
* @param path 文件路径
*/
@RequestMapping(value = "delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
@UrlPermission(Role.Manage)
public String delete(String path, String name) {
// if (!whitelistDirectoryService.checkNgxDirectory(path)) {
// return JsonMessage.getString(400, "非法操作");
// }
path = pathSafe(path);
name = pathSafe(name);
if (StrUtil.isEmpty(name)) {
return JsonMessage.getString(400, "删除失败,请正常操作");
}
File file = FileUtil.file(path, name);
try {
FileUtil.rename(file, file.getName() + "_back", false, true);
} catch (Exception e) {
DefaultSystemLog.ERROR().error("删除nginx", e);
return JsonMessage.getString(400, "删除失败:" + e.getMessage());
}
String msg = this.reloadNginx();
return JsonMessage.getString(200, "删除成功" + msg);
public String delete() {
return NodeForward.request(getNode(), getRequest(), NodeUrl.System_Nginx_delete).toString();
}
}

View File

@ -1,22 +1,11 @@
package cn.keepbx.jpom.controller.node.system.ssl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.jiangzeyin.controller.multipart.MultipartFileBuilder;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.BaseNodeController;
import cn.keepbx.jpom.common.Role;
import cn.keepbx.jpom.common.forward.NodeForward;
import cn.keepbx.jpom.common.forward.NodeUrl;
import cn.keepbx.jpom.common.interceptor.UrlPermission;
import cn.keepbx.jpom.model.data.CertModel;
import cn.keepbx.jpom.model.data.UserModel;
import cn.keepbx.jpom.service.system.CertService;
import cn.keepbx.jpom.system.ServerConfigBean;
import com.alibaba.fastjson.JSONObject;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import cn.keepbx.jpom.service.system.WhitelistDirectoryService;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@ -24,13 +13,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* 证书管理
@ -39,17 +22,15 @@ import java.util.zip.ZipFile;
*/
@Controller
@RequestMapping(value = "/node/system/certificate")
public class CertificateController extends BaseController {
public class CertificateController extends BaseNodeController {
@Resource
private CertService certService;
// @Resource
// private WhitelistDirectoryService whitelistDirectoryService;
private WhitelistDirectoryService whitelistDirectoryService;
@RequestMapping(value = "/list.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String certificate() {
// JSONArray jsonArray = whitelistDirectoryService.getCertificateDirectory();
// setAttribute("certificate", jsonArray);
List<String> jsonArray = whitelistDirectoryService.getCertificateDirectory(getNode());
setAttribute("certificate", jsonArray);
return "node/system/certificate";
}
@ -63,165 +44,7 @@ public class CertificateController extends BaseController {
@ResponseBody
@UrlPermission(Role.Manage)
public String saveCertificate() {
String data = getParameter("data");
JSONObject jsonObject = JSONObject.parseObject(data);
String type = jsonObject.getString("type");
String id = jsonObject.getString("id");
try {
CertModel certModel;
if ("add".equalsIgnoreCase(type)) {
if (certService.getItem(id) != null) {
return JsonMessage.getString(405, "证书id已经存在啦");
}
certModel = new CertModel();
String error = getCertModel(certModel, jsonObject);
if (error != null) {
return error;
}
if (!hasFile()) {
return JsonMessage.getString(405, "请选择证书包文件");
}
error = getCertFile(certModel, true);
if (error != null) {
return error;
}
certService.addItem(certModel);
} else {
certModel = certService.getItem(id);
if (certModel == null) {
return JsonMessage.getString(404, "没有找到对应证书文件");
}
String name = jsonObject.getString("name");
if (StrUtil.isEmpty(name)) {
return JsonMessage.getString(400, "请填写证书名称");
}
certModel.setName(name);
if (ServletFileUpload.isMultipartContent(getRequest()) && hasFile()) {
String error = getCertFile(certModel, false);
if (error != null) {
return error;
}
}
if (!certService.updateItem(certModel)) {
return JsonMessage.getString(406, "修改失败");
}
}
} catch (Exception e) {
DefaultSystemLog.ERROR().error("证书文件", e);
return JsonMessage.getString(400, e.getMessage());
}
return JsonMessage.getString(200, "提交成功");
}
/**
* 获取证书信息
*
* @param certModel 实体
* @return 错误消息
*/
private String getCertModel(CertModel certModel, JSONObject jsonObject) {
String id = jsonObject.getString("id");
String path = jsonObject.getString("path");
String name = jsonObject.getString("name");
if (StrUtil.isEmpty(id)) {
return JsonMessage.getString(400, "请填写证书id");
}
if (Validator.isChinese(id)) {
return JsonMessage.getString(400, "证书id不能使用中文");
}
if (StrUtil.isEmpty(name)) {
return JsonMessage.getString(400, "请填写证书名称");
}
// if (!whitelistDirectoryService.checkCertificateDirectory(path)) {
// return JsonMessage.getString(400, "请选择正确的项目路径,或者还没有配置白名单");
// }
certModel.setId(id);
certModel.setWhitePath(path);
certModel.setName(name);
return null;
}
private String getCertFile(CertModel certModel, boolean add) throws IOException {
String certPath = null;
String pemPath = null, keyPath = null;
try {
String path = ServerConfigBean.getInstance().getTempPathName();
MultipartFileBuilder cert = createMultipart().addFieldName("file").setSavePath(path);
certPath = cert.save();
ZipFile zipFile = new ZipFile(certPath);
Enumeration<? extends ZipEntry> zipEntryEnumeration = zipFile.entries();
while (zipEntryEnumeration.hasMoreElements()) {
ZipEntry zipEntry = zipEntryEnumeration.nextElement();
if (zipEntry.isDirectory()) {
continue;
}
String keyName = zipEntry.getName();
if (pemPath == null && StrUtil.endWith(keyName, ".pem", true)) {
String filePathItem = String.format("%s/%s/%s", path, certModel.getId(), keyName);
InputStream inputStream = zipFile.getInputStream(zipEntry);
FileUtil.writeFromStream(inputStream, filePathItem);
pemPath = filePathItem;
}
//
if (keyPath == null && StrUtil.endWith(keyName, ".key", true)) {
String filePathItem = String.format("%s/%s/%s", path, certModel.getId(), keyName);
InputStream inputStream = zipFile.getInputStream(zipEntry);
FileUtil.writeFromStream(inputStream, filePathItem);
keyPath = filePathItem;
}
if (pemPath != null && keyPath != null) {
break;
}
}
if (pemPath == null || keyPath == null) {
return JsonMessage.getString(405, "证书包中文件不完整需要包含key、pem");
}
JSONObject jsonObject = CertModel.decodeCert(pemPath, keyPath);
if (jsonObject == null) {
return JsonMessage.getString(405, "解析证书失败");
}
String domain = jsonObject.getString("domain");
if (add) {
List<CertModel> array = certService.list();
if (array != null) {
for (CertModel certModel1 : array) {
if (StrUtil.emptyToDefault(domain, "").equals(certModel1.getDomain())) {
return JsonMessage.getString(405, "证书的域名已经存在啦");
}
}
}
} else {
if (!StrUtil.emptyToDefault(domain, "").equals(certModel.getDomain())) {
return JsonMessage.getString(405, "新证书的域名不一致");
}
}
// 移动位置
String temporary = certModel.getWhitePath() + "/" + certModel.getId() + "/";
File pemFile = FileUtil.file(temporary + certModel.getId() + ".pem");
File keyFile = FileUtil.file(temporary + certModel.getId() + ".key");
if (add) {
if (pemFile.exists()) {
return JsonMessage.getString(405, pemFile.getAbsolutePath() + " 已经被占用啦");
}
if (keyFile.exists()) {
return JsonMessage.getString(405, keyFile.getAbsolutePath() + " 已经被占用啦");
}
}
FileUtil.move(FileUtil.file(pemPath), pemFile, true);
FileUtil.move(FileUtil.file(keyPath), keyFile, true);
certModel.setCert(pemFile.getAbsolutePath());
certModel.setKey(keyFile.getAbsolutePath());
//
certModel.setDomain(domain);
certModel.setExpirationTime(jsonObject.getLongValue("expirationTime"));
certModel.setEffectiveTime(jsonObject.getLongValue("effectiveTime"));
} finally {
if (certPath != null) {
FileUtil.del(certPath);
}
}
return null;
return NodeForward.requestMultipart(getNode(), getMultiRequest(), NodeUrl.System_Certificate_saveCertificate).toString();
}
@ -232,8 +55,7 @@ public class CertificateController extends BaseController {
@ResponseBody
@UrlPermission(Role.Manage)
public String getCertList() {
List<CertModel> array = certService.list();
return JsonMessage.getString(200, "", array);
return NodeForward.request(getNode(), getRequest(), NodeUrl.System_Certificate_getCertList).toString();
}
/**
@ -246,18 +68,7 @@ public class CertificateController extends BaseController {
@ResponseBody
@UrlPermission(Role.System)
public String delete(String id) {
if (StrUtil.isEmpty(id)) {
return JsonMessage.getString(400, "删除失败");
}
UserModel userModel = getUser();
if (!userModel.isSystemUser()) {
return JsonMessage.getString(400, "你没有操作权限");
}
boolean b = certService.delete(id);
if (!b) {
return JsonMessage.getString(400, "删除失败");
}
return JsonMessage.getString(200, "删除成功");
return NodeForward.request(getNode(), getRequest(), NodeUrl.System_Certificate_delete).toString();
}
@ -267,15 +78,7 @@ public class CertificateController extends BaseController {
@RequestMapping(value = "/export", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
@UrlPermission(Role.Manage)
public String export(String id) {
CertModel item = certService.getItem(id);
if (null == item) {
return JsonMessage.getString(400, "导出失败");
}
String parent = FileUtil.file(item.getCert()).getParent();
File zip = ZipUtil.zip(parent);
ServletUtil.write(getResponse(), zip);
FileUtil.del(zip);
return JsonMessage.getString(400, "导出成功");
public void export(String id) {
NodeForward.requestDownload(getNode(), getRequest(), getResponse(), NodeUrl.System_Certificate_export);
}
}

View File

@ -295,4 +295,14 @@ public class UserModel extends BaseModel {
public void setModifyTime(long modifyTime) {
this.modifyTime = modifyTime;
}
public static String getOptUserName(UserModel userModel) {
String userId;
if (userModel.isSystemUser()) {
userId = UserModel.SYSTEM_OCCUPY_NAME;
} else {
userId = userModel.getId();
}
return userId;
}
}

View File

@ -32,7 +32,6 @@ import java.util.concurrent.atomic.AtomicInteger;
@Component
public class ServerWebSocketHandle {
private NodeService nodeService;
private static volatile AtomicInteger onlineCount = new AtomicInteger();
private static final ConcurrentHashMap<String, UserModel> USER = new ConcurrentHashMap<>();
@ -84,17 +83,14 @@ public class ServerWebSocketHandle {
}
@OnMessage
public void onMessage(String message, Session session) {
public void onMessage(String message, Session session) throws IOException {
UserModel userModel = USER.get(session.getId());
if (userModel == null) {
SocketSessionUtil.send(session, "回话信息失效,刷新网页再试");
return;
}
ProxySession proxySession = getSession(session);
proxySession.send(message);
// UserModel userModel = USER.get(session.getId());
// if (userModel == null) {
// SocketSessionUtil.send(session, "回话信息失效,刷新网页再试");
// return;
// }
// System.out.println(op);
//
}
private void destroy(Session session) {

View File

@ -1,23 +1,12 @@
package cn.keepbx.jpom.system;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.spring.SpringUtil;
import cn.keepbx.jpom.common.BaseController;
import org.springframework.context.annotation.Configuration;
import java.io.File;
/**
* 配置信息静态变量类
*
* @author jiangzeyin
* @date 2019/1/16
*/
@Configuration
public class ServerConfigBean {
private static ServerConfigBean serverConfigBean;
/**
* 用户数据文件
*/
@ -27,36 +16,4 @@ public class ServerConfigBean {
* 节点数据文件
*/
public static final String NODE = "node.json";
/**
* 证书文件
*/
public static final String CERT = "cert.json";
/**
* 单利模式
*
* @return config
*/
public static ServerConfigBean getInstance() {
if (serverConfigBean == null) {
serverConfigBean = SpringUtil.getBean(ServerConfigBean.class);
}
return serverConfigBean;
}
/**
* 获取当前登录用户的临时文件存储路径如果没有登录则抛出异常
*
* @return 文件夹
*/
public String getTempPathName() {
// File file = getTempPath();
return null;
// return FileUtil.normalize(file.getPath());
}
}

View File

@ -18,7 +18,6 @@ import java.util.concurrent.TimeUnit;
@Configuration
public class ServerExtConfigBean {
/**
* 系统最多能创建多少用户
*/
@ -29,23 +28,6 @@ public class ServerExtConfigBean {
*/
@Value("${user.alwaysLoginError:5}")
public int userAlwaysLoginError;
/**
* 自动备份控制台日志防止日志文件过大目前暂只支持linux 不停服备份 如果配置none 则不自动备份 默认10分钟扫描一次
*/
@Value("${log.autoBackConsoleCron:0 0/10 * * * ?}")
public String autoBackConsoleCron;
/**
* 当文件多大时自动备份
*
* @see ch.qos.logback.core.util.FileSize
*/
@Value("${log.autoBackSize:50MB}")
public String autoBackSize;
/**
* 控制台日志保存时长单位天
*/
@Value("${log.saveDays:7}")
private int logSaveDays;
/**
* 当ip连续登录失败锁定对应IP时长单位毫秒
@ -62,19 +44,6 @@ public class ServerExtConfigBean {
return this.ipErrorLockTimeValue;
}
/**
* 配置错误或者没有默认是7天
*
* @return int
*/
public int getLogSaveDays() {
if (logSaveDays <= 0) {
return 7;
}
return logSaveDays;
}
/**
* 单例
*

View File

@ -40,6 +40,11 @@
layui.each(asyncFn, function () {
this && this();
})
$("button[op='a']").click(function () {
var href = $(this).attr("href");
location.href = appendNodeId(href);
});
});
function appendNodeId(url) {
@ -194,7 +199,7 @@
## 文件上传渲染
function uploadRender(data) {
function uploadRender(data, fn) {
layui.use(['upload'], function () {
var upload = layui.upload;
var newsData = {
@ -206,7 +211,8 @@
data: newsData
};
$.extend(defData, data);
return upload.render(defData);
var uploadResult = upload.render(defData);
fn && fn(uploadResult);
});
}
</script>

View File

@ -48,15 +48,22 @@
<body class="layui-layout-body">
<div class="layui-layout layui-layout-admin">
<div class="layui-header">
<div class="layui-logo">
<a href="../index.html" class="layui-btn layui-btn-sm layui-btn-primary">
<i class="layui-icon">&#xe65c;</i>
</a>
<span title="版本时间:$!jpomManifest.timeStamp进程ID:$!jpomManifest.pid">
<form class="layui-form" action="">
<div class="layui-logo" title="版本时间:$!jpomManifest.timeStamp进程ID:$!jpomManifest.pid">
$node.name #if($jpomManifest)<font style="font-size: 10px;">($jpomManifest.version)</font>#end
</span>
</div>
## <div class="layui-form-item" style="margin-top: 10px;">
## <label class="layui-form-label">节点列表</label>
## <div class="layui-input-block">
## <select name="city" lay-verify="required">
## #foreach($itemNode in $array)
## <option value="$itemNode.id">$itemNode.name</option>
## #end
## </select>
## </div>
## </div>
## </span>
</div>
</form>
<ul class="layui-nav layui-layout-left">
</ul>

View File

@ -34,7 +34,7 @@
<button name="install" data-name="$item.shortKey" data-key="$item.key" data-id="$id"
class="layui-btn layui-btn-danger layui-btn-sm">安装
</button>
<button name="download" href="build_download?key=$item.key&id=$id"
<button op="a" href="build_download?key=$item.key&id=$id"
class="layui-btn layui-btn-warm layui-btn-sm">下载
</button>
</td>
@ -81,11 +81,6 @@
});
});
$("button[name='download']").click(function () {
var href = $(this).attr("href");
location.href = appendNodeId(href);
});
}
</script>
</html>

View File

@ -25,8 +25,8 @@
<body>
<div>
<a class="layui-btn layui-btn-sm layui-btn-normal" href="/manage/stack?tag=$!tag">导出堆栈信息</a>
<a class="layui-btn layui-btn-sm layui-btn-normal" href="/manage/ram?tag=$!tag">导出内存信息</a>
<button op="a" class="layui-btn layui-btn-sm layui-btn-normal" href="./stack?tag=$!tag">导出堆栈信息</button>
<button op="a" class="layui-btn layui-btn-sm layui-btn-normal" href="./ram?tag=$!tag">导出内存信息</button>
</div>
<div class="info">
<label>系统内存</label>
@ -48,20 +48,20 @@
</tr>
</thead>
<tbody>
#if($item)
#if($data.process)
<tr>
<td>$!item.pid</td>
<td>$!item.command</td>
<td>$!item.user</td>
<td>$!item.res</td>
<td>$!item.status</td>
<td>$!item.cpu</td>
<td>$!item.mem</td>
<td>$!item.time</td>
<td>$!item.pr</td>
<td>$!item.ni</td>
<td>$!item.virt</td>
<td>$!item.shr</td>
<td>$!data.process.pid</td>
<td>$!data.process.command</td>
<td>$!data.process.user</td>
<td>$!data.process.res</td>
<td>$!data.process.status</td>
<td>$!data.process.cpu</td>
<td>$!data.process.mem</td>
<td>$!data.process.time</td>
<td>$!data.process.pr</td>
<td>$!data.process.ni</td>
<td>$!data.process.virt</td>
<td>$!data.process.shr</td>
</tr>
#else
<tr>
@ -72,7 +72,7 @@
</table>
</div>
#if($beanMem)
#if($data.beanMem)
<div class="info">
<label> jvm内存</label>
<table class="layui-table" style="margin-top: 10px">
@ -89,13 +89,13 @@
</thead>
<tbody>
<tr>
<td>$!beanMem.heapUsed</td>
<td>$!beanMem.heapProportion</td>
<td>$!beanMem.heapCommitted</td>
<td>$!beanMem.nonHeapUsed</td>
<td>$!beanMem.nonHeapProportion</td>
<td>$!beanMem.nonHeapCommitted</td>
<td>$!beanMem.mount</td>
<td>$!data.beanMem.heapUsed</td>
<td>$!data.beanMem.heapProportion</td>
<td>$!data.beanMem.heapCommitted</td>
<td>$!data.beanMem.nonHeapUsed</td>
<td>$!data.beanMem.nonHeapProportion</td>
<td>$!data.beanMem.nonHeapCommitted</td>
<td>$!data.beanMem.mount</td>
</tr>
</tbody>
</table>
@ -119,19 +119,19 @@
</tr>
</thead>
<tbody>
#if($port)
#foreach($item in $!port)
<tr>
<td>$!item.name</td>
<td>$!item.protocol</td>
<td>$!item.local</td>
<td>$!item.foreign</td>
<td>$!item.status</td>
<td>$!item.receive</td>
<td>$!item.send</td>
</tr>
#end
#else
#foreach($item in $data.netstat)
#set($hashNetStat=true)
<tr>
<td>$!item.name</td>
<td>$!item.protocol</td>
<td>$!item.local</td>
<td>$!item.foreign</td>
<td>$!item.status</td>
<td>$!item.receive</td>
<td>$!item.send</td>
</tr>
#end
#if(!$hashNetStat)
<tr>
<td colspan=7 style="text-align:center">无数据</td>
</tr>

View File

@ -44,7 +44,7 @@
<td>$item.modifytime</td>
<td>$item.filesize</td>
<td>
<button name="download" href="logBack_download?key=$item.filename&id=$data.id"
<button op="a" href="logBack_download?key=$item.filename&id=$data.id"
class="layui-btn layui-btn-warm layui-btn-sm">下载
</button>
<button name="delete" data-name="$item.filename" data-id="$data.id"
@ -91,11 +91,6 @@
});
});
$("button[name='download']").click(function () {
var href = $(this).attr("href");
location.href = appendNodeId(href);
});
}
</script>
</html>

View File

@ -128,14 +128,13 @@
return y + '-' + m + '-' + d + ' ' + h + ':' + minute + ':' + second;
}
var laytpl, upload;
var laytpl;
function loadSuccess() {
var uploadConfig, hashSelectConfig, updateFormData;
layui.use(['laytpl', 'upload'], function () {
layui.use(['laytpl'], function () {
laytpl = layui.laytpl;
upload = layui.upload;
uploadConfig = upload.render({
uploadRender({
elem: '#selectZip',
url: './saveCertificate',
multiple: false,
@ -169,6 +168,8 @@
error: function () {
layer.msg("上传失败");
}
}, function (data) {
uploadConfig = data;
});
tableRender({
id: 'tab_certificate',