diff --git a/README.md b/README.md index aba3255f7ded31049f1ffb5bac059b3ce4d29352..bdf48a126121ccd0427bb1773b13c9f8a3611fc2 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,6 @@ nginx本身功能复杂, nginxWebUI并不能涵盖nginx所有功能, 但能覆 本项目是基于springBoot的web系统, 数据库使用sqlite, 因此服务器上不需要安装任何数据库 -项目启动时会释放一个.sqlite.db到系统用户文件夹中, 注意进行备份 - 本系统通过Let's encrypt申请证书, 使用acme.sh脚本进行自动化申请和续签, 开启续签的证书将在每天凌晨2点进行续签, 只有超过60天的证书才会进行续签. 只支持在linux下签发证书. 添加tcp/ip转发配置支持时, 一些低版本的nginx可能需要重新编译,通过添加–with-stream参数指定安装stream模块才能使用, 但在ubuntu 18.04下, 官方软件库中的nginx已经带有stream模块, 不需要重新编译. 本系统如果配置了tcp转发项的话, 会自动引入ngx_stream_module.so的配置项, 如果没有开启则不引入, 最大限度优化ngnix配置文件. @@ -119,7 +117,7 @@ Windows: java -jar -Xmx64m D:/home/nginxWebUI/nginxWebUI.jar --server.port=8080 #### docker安装说明 -本项目制作了docker镜像, 支持 x86/x86_64/arm64/arm v7/arm v6/ppc64 平台,同时包含nginx和nginxWebUI在内, 一体化管理与运行nginx. +本项目制作了docker镜像, 支持 x86_64/arm64/arm v7 平台,同时包含nginx和nginxWebUI在内, 一体化管理与运行nginx. 1.安装docker容器环境 diff --git a/README_EN.md b/README_EN.md index 6df834788e765d13de701e98096ee497b7d93ba4..39215f955d96f4cda0f4aa0b68701d99962ff832 100644 --- a/README_EN.md +++ b/README_EN.md @@ -34,8 +34,6 @@ password: Admin123 This project is a Web system based on springBoot. The database use SQLite, so there is no need to install any database on the server. -sqlite.db will be released into the system user folder when the project starts, so pay attention to backup. - This system applies for the certificate through Let's ENCRYPT and USES acme.sh script to automatically apply for and renew the certificate. Once the certificate is renewed, it will be renewed at 2 am every day, and only certificates exceeding 60 days will be renewed. When adding TCP/IP forwarding configuration support, some lower versions of Nginx may need to be recompiled,You can install the stream module by adding the -with-stream parameter, but under Ubuntu 18.04, the nginx in the official software library already has the stream module, which does not need to be recompiled. If the TCP forwarding item is configured in this system, the configuration item of ngx_stream_module.so will be introduced automatically, and the configuration file of Ngnix will be optimized to the maximum. @@ -112,7 +110,7 @@ Note that the command ends with an & to indicate that the project is running in #### docker installation instructions -Docker image supports x86/x86_64/arm64/arm v7/arm v6/ppc64 platforms. Note that an & sign is added at the end of the command, indicating that the docker image of this project has been produced by the background operation of the project, including nginx and nginxWebUI, for integrated management and operation of Nginx. +Docker image supports x86_64/arm64/arm v7 platforms. Note that an & sign is added at the end of the command, indicating that the docker image of this project has been produced by the background operation of the project, including nginx and nginxWebUI, for integrated management and operation of Nginx. 1.Install the Docker environment diff --git a/pom.xml b/pom.xml index 1c531823742a6468ff9232abdd1e76e69162f068..cabc0613f1e1a46ae7c6e3a01eb02d911adebb5f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.cym nginxWebUI - 2.8.7 + custom org.springframework.boot diff --git a/src/main/java/com/cym/config/AdminInterceptor.java b/src/main/java/com/cym/config/AdminInterceptor.java index 01864cf7f2db4db36e05702220da3d3ffa3cd244..b433d3dca350b6d8baf88137b76363e67b1a88ae 100644 --- a/src/main/java/com/cym/config/AdminInterceptor.java +++ b/src/main/java/com/cym/config/AdminInterceptor.java @@ -122,23 +122,6 @@ public class AdminInterceptor implements HandlerInterceptor { rs = HttpUtil.post(url, body); } -// String remoteDomain = "//" + remote.getIp() + ":" + remote.getPort(); -// String remoteDomainNoPort = "//" + remote.getIp(); -// String localDomain = "//" + request.getServerName() + ":" + request.getServerPort(); -// -// rs = rs.replace(remoteDomain + "/", localDomain + "/")// -// .replace(remoteDomainNoPort + "/", localDomain + "/")// -// .replace(remoteDomain + "/adminPage", localDomain + "/adminPage")// -// .replace(remoteDomainNoPort + "/adminPage", localDomain + "/adminPage")// -// .replace(remoteDomain + "/lib", localDomain + "/lib")// -// .replace(remoteDomainNoPort + "/lib", localDomain + "/lib")// -// .replace(remoteDomain + "/js", localDomain + "/js")// -// .replace(remoteDomainNoPort + "/js", localDomain + "/js")// -// .replace(remoteDomain + "/css", localDomain + "/css")// -// .replace(remoteDomainNoPort + "/css", localDomain + "/css")// -// .replace(remoteDomain + "/img", localDomain + "/img")// -// .replace(remoteDomainNoPort + "/img", localDomain + "/img")// -// ; response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); diff --git a/src/main/java/com/cym/config/ApiInterceptor.java b/src/main/java/com/cym/config/ApiInterceptor.java index 71421e386038d12e9c1aadb63a74f8e815e0ba03..557f6769f7127ffe79f31954dd25b0ee8335b162 100644 --- a/src/main/java/com/cym/config/ApiInterceptor.java +++ b/src/main/java/com/cym/config/ApiInterceptor.java @@ -48,6 +48,10 @@ public class ApiInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception { String token = request.getHeader("token"); Admin admin = adminService.getByToken(token); + if (admin == null) { + String creditKey = request.getParameter("creditKey"); + admin = adminService.getByCreditKey(creditKey); + } if (admin != null && admin.getApi()) { return true; diff --git a/src/main/java/com/cym/config/FrontInterceptor.java b/src/main/java/com/cym/config/FrontInterceptor.java index fbe496e6953d1d3e2eb3798c18c824d64e0a19d7..25b698520ade4d3acca43fd5c07f8e5c2dccf31f 100644 --- a/src/main/java/com/cym/config/FrontInterceptor.java +++ b/src/main/java/com/cym/config/FrontInterceptor.java @@ -84,13 +84,13 @@ public class FrontInterceptor implements HandlerInterceptor { request.setAttribute("showAdmin", request.getParameter("showAdmin")); // 显示版本更新 - if (versionConfig.getVersion() != null) { - request.setAttribute("newVersion", versionConfig.getVersion()); - - if (Integer.parseInt(currentVersion.replace(".", "").replace("v", "")) < Integer.parseInt(versionConfig.getVersion().getVersion().replace(".", "").replace("v", ""))) { - request.setAttribute("hasNewVersion", 1); - } - } +// if (versionConfig.getVersion() != null) { +// request.setAttribute("newVersion", versionConfig.getVersion()); +// +// if (Integer.parseInt(currentVersion.replace(".", "").replace("v", "")) < Integer.parseInt(versionConfig.getVersion().getVersion().replace(".", "").replace("v", ""))) { +// request.setAttribute("hasNewVersion", 1); +// } +// } // 读取配置文件 Properties properties = null; diff --git a/src/main/java/com/cym/config/InitConfig.java b/src/main/java/com/cym/config/InitConfig.java index c1a540a758d31cdffad710c88d90ba386b9ede36..789cd53fc07a9a18dff3af9b588775f074a7fce2 100644 --- a/src/main/java/com/cym/config/InitConfig.java +++ b/src/main/java/com/cym/config/InitConfig.java @@ -13,7 +13,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; -import org.springframework.boot.system.ApplicationHome; import org.springframework.context.ApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/src/main/java/com/cym/controller/adminPage/ConfController.java b/src/main/java/com/cym/controller/adminPage/ConfController.java index b30cad6ae7ab58462d672215a007b15251f544d1..55d5d135397d6f9658bb736c2e4619f5724ae4bb 100644 --- a/src/main/java/com/cym/controller/adminPage/ConfController.java +++ b/src/main/java/com/cym/controller/adminPage/ConfController.java @@ -21,6 +21,7 @@ import com.cym.config.VersionConfig; import com.cym.ext.ConfExt; import com.cym.ext.ConfFile; import com.cym.model.Admin; +import com.cym.service.BakService; import com.cym.service.ConfService; import com.cym.service.ServerService; import com.cym.service.SettingService; @@ -56,6 +57,8 @@ public class ConfController extends BaseController { ConfService confService; @Autowired MainController mainController; + @Autowired + BakService bakService; @Autowired VersionConfig versionConfig; @@ -78,6 +81,9 @@ public class ConfController extends BaseController { String decompose = settingService.get("decompose"); modelAndView.addObject("decompose", decompose); + Boolean applying = bakService.isApplying(null); + modelAndView.addObject("applying", applying); + modelAndView.addObject("tmp", InitConfig.home + "temp/nginx.conf"); modelAndView.setViewName("/adminPage/conf/index"); @@ -98,7 +104,11 @@ public class ConfController extends BaseController { @RequestMapping(value = "replace") @ResponseBody public JsonResult replace(String json, HttpServletRequest request, String adminName) { - + + if(bakService.isApplying(null)) { + return renderError("已有变更正在审批中,请稍后再试"); + } + if (StrUtil.isEmpty(json)) { json = getReplaceJson(); } @@ -132,8 +142,15 @@ public class ConfController extends BaseController { adminName = admin.getName(); } - confService.replace(nginxPath, nginxContent, subContent, subName, true, adminName); - return renderSuccess(m.get("confStr.replaceSuccess")); + String version = jsonObject.getStr("version"); + String changeContent = jsonObject.getStr("changeContent"); + + if(bakService.hasVersion(version)) { + return renderError("该版本号已存在"); + } + + confService.replaceApply(nginxContent, subContent, subName, adminName, version, changeContent); + return renderSuccess(); } catch (Exception e) { logger.error(e.getMessage(), e); return renderError(m.get("confStr.error3") + ":" + e.getMessage()); @@ -428,5 +445,7 @@ public class ConfController extends BaseController { settingService.set(key, val); return renderSuccess(); } + + } diff --git a/src/main/java/com/cym/controller/adminPage/LoginController.java b/src/main/java/com/cym/controller/adminPage/LoginController.java index 96e0ed74edc34d49256b0bbf4b2d0b1881720fe8..fbb3f7ff1b4608f60cb0fbaea2eb1b6712fa0748 100644 --- a/src/main/java/com/cym/controller/adminPage/LoginController.java +++ b/src/main/java/com/cym/controller/adminPage/LoginController.java @@ -18,6 +18,7 @@ import com.cym.config.VersionConfig; import com.cym.model.Admin; import com.cym.model.Remote; import com.cym.service.AdminService; +import com.cym.service.BakService; import com.cym.service.CreditService; import com.cym.service.SettingService; import com.cym.utils.AuthUtils; @@ -51,7 +52,9 @@ public class LoginController extends BaseController { AuthUtils authUtils; @Value("${project.version}") String currentVersion; - + @Autowired + BakService bakService; + @Autowired SettingService settingService; @@ -118,7 +121,7 @@ public class LoginController extends BaseController { httpSession.removeAttribute("imgCode"); // 立刻销毁验证码 // 检查更新 - versionConfig.getNewVersion(); +// versionConfig.getNewVersion(); return renderSuccess(admin); } @@ -227,7 +230,7 @@ public class LoginController extends BaseController { String localType = (String) httpSession.getAttribute("localType"); if (StrUtil.isNotEmpty(localType)) { if ("local".equals(localType)) { - return renderSuccess(m.get("remoteStr.local")); + return renderSuccess("control机"); } else { Remote remote = (Remote) httpSession.getAttribute("remote"); if (StrUtil.isNotEmpty(remote.getDescr())) { @@ -296,4 +299,6 @@ public class LoginController extends BaseController { return renderSuccess(); } + + } diff --git a/src/main/java/com/cym/controller/adminPage/MainController.java b/src/main/java/com/cym/controller/adminPage/MainController.java index 1ccca8536f9a797d4d2e51dbd7a35f038b35e419..14a6e24c75161342eaa2f77a339ba972f12a28fb 100644 --- a/src/main/java/com/cym/controller/adminPage/MainController.java +++ b/src/main/java/com/cym/controller/adminPage/MainController.java @@ -19,6 +19,7 @@ import org.springframework.web.servlet.ModelAndView; import com.cym.config.InitConfig; import com.cym.model.Remote; +import com.cym.service.BakService; import com.cym.service.SettingService; import com.cym.utils.BaseController; import com.cym.utils.JsonResult; @@ -37,6 +38,8 @@ public class MainController extends BaseController { UpdateUtils updateUtils; @Autowired SettingService settingService; + @Autowired + BakService bakService; private static final Logger LOG = LoggerFactory.getLogger(MainController.class); @@ -93,8 +96,7 @@ public class MainController extends BaseController { updateUtils.run(path); return renderSuccess(); } - - + @ResponseBody @RequestMapping("/adminPage/main/changeLang") public JsonResult changeLang() { @@ -106,5 +108,13 @@ public class MainController extends BaseController { return renderSuccess(); } + + + @ResponseBody + @RequestMapping("/adminPage/main/isApply") + public JsonResult isApply() { + return renderSuccess(bakService.isApplying(null)); + } + } \ No newline at end of file diff --git a/src/main/java/com/cym/controller/adminPage/RemoteController.java b/src/main/java/com/cym/controller/adminPage/RemoteController.java index 276c5aa144c5c76411b6c111929bbbdcad0654fb..aca6ed322879263ac138f121c74d01d4310a19c6 100644 --- a/src/main/java/com/cym/controller/adminPage/RemoteController.java +++ b/src/main/java/com/cym/controller/adminPage/RemoteController.java @@ -134,7 +134,7 @@ public class RemoteController extends BaseController { remoteLocal.setIp(""); remoteLocal.setProtocol(""); remoteLocal.setParentId(""); - remoteLocal.setDescr(m.get("remoteStr.local")); + remoteLocal.setDescr("control机"); Map map = version(); remoteLocal.setVersion((String) map.get("version")); remoteLocal.setNginx((Integer) map.get("nginx")); diff --git a/src/main/java/com/cym/controller/api/NginxApiController.java b/src/main/java/com/cym/controller/api/NginxApiController.java index 19078771405d22455dd2797a4d469fadef5ebd0c..fae85f7c9d4fe83c4e7ed86a23707e926805542b 100644 --- a/src/main/java/com/cym/controller/api/NginxApiController.java +++ b/src/main/java/com/cym/controller/api/NginxApiController.java @@ -13,7 +13,11 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.cym.controller.adminPage.ConfController; +import com.cym.model.Admin; +import com.cym.model.Remote; import com.cym.service.AdminService; +import com.cym.service.BakService; +import com.cym.service.ConfService; import com.cym.service.SettingService; import com.cym.utils.BaseController; import com.cym.utils.JsonResult; @@ -21,6 +25,7 @@ import com.cym.utils.NginxUtils; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HtmlUtil; +import cn.hutool.http.server.HttpServerRequest; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -35,6 +40,10 @@ public class NginxApiController extends BaseController { AdminService adminService; @Autowired SettingService settingService; + @Autowired + ConfService confService; + @Autowired + BakService bakService; @ApiOperation("获取nginx状态") @PostMapping("nginxStatus") @@ -46,17 +55,48 @@ public class NginxApiController extends BaseController { } } - @ApiOperation("替换conf文件") - @PostMapping("replace") - public JsonResult replace(@RequestHeader String token, HttpServletRequest request) { - JsonResult jsonResult = confController.replace(confController.getReplaceJson(), request, null); - if (jsonResult.isSuccess()) { - return renderSuccess("替换成功"); - } else { - return renderError("替换失败"); + @ApiOperation("下发审批结果") + @PostMapping("applyResult") + public JsonResult applyResult(HttpServletRequest request, @RequestParam @ApiParam("审批编号") String applyNumber, // + @RequestParam @ApiParam("审批结果 1已通过 2未通过") Integer status, // + @RequestParam(required = false) @ApiParam("机器别名(不填为本地)") String remoteName// + ) { + if (!bakService.isApplying(remoteName)) { + return renderError("当前没有申请中的更改"); } + + Admin admin = getAdmin(request); + confService.replaceApplyOver(applyNumber, status, admin.getName(), remoteName); + + return renderSuccess("下发成功"); } + @ApiOperation("查看是否有审批") + @PostMapping("isApplying") + public JsonResult isApplying(HttpServletRequest request) { + + return renderSuccess(bakService.isApplying(null)); + } + + + @ApiOperation("获取全部远程机器") + @PostMapping("getAllRemote") + public JsonResult> getAllRemote(HttpServletRequest request) { + + return renderSuccess(sqlHelper.findAll(Remote.class)); + } + +// @ApiOperation("替换conf文件") +// @PostMapping("replace") +// public JsonResult replace(@RequestHeader String token, HttpServletRequest request) { +// JsonResult jsonResult = confController.replace(confController.getReplaceJson(), request, null); +// if (jsonResult.isSuccess()) { +// return renderSuccess("替换成功"); +// } else { +// return renderError("替换失败"); +// } +// } + @ApiOperation("效验conf文件") @PostMapping("check") public JsonResult checkBase() { @@ -127,27 +167,4 @@ public class NginxApiController extends BaseController { return jsonResult; } -// @ApiOperation("停止nginx") -// @PostMapping("stop") -// public synchronized JsonResult stop() { -// JsonResult jsonResult = confController.stop(null, null); -// -// if (jsonResult.isSuccess()) { -// return renderSuccess("停止成功"); -// } else { -// return renderError("停止失败"); -// } -// } -// -// @ApiOperation("启动nginx") -// @PostMapping("start") -// public synchronized JsonResult start() { -// JsonResult jsonResult = confController.start(null, null, null); -// -// if (jsonResult.isSuccess()) { -// return renderSuccess("启动成功"); -// } else { -// return renderError("启动失败"); -// } -// } } diff --git a/src/main/java/com/cym/model/Bak.java b/src/main/java/com/cym/model/Bak.java index 2c352d7976d7ad022d65e3b8c205f072862e6e7e..6634450de7e1a42da235a8c8c6ecface5d572b90 100644 --- a/src/main/java/com/cym/model/Bak.java +++ b/src/main/java/com/cym/model/Bak.java @@ -1,18 +1,61 @@ package com.cym.model; import cn.craccd.sqlHelper.bean.BaseModel; +import cn.craccd.sqlHelper.config.InitValue; import cn.craccd.sqlHelper.config.Table; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; @ApiModel("备份文件") @Table -public class Bak extends BaseModel{ +public class Bak extends BaseModel { @ApiModelProperty("时间") String time; @ApiModelProperty("主文件内容") String content; + @ApiModelProperty("版本号") + String version; + + @ApiModelProperty("审批编号") + String applyNumber; + @ApiModelProperty("变更内容") + String changeContent; + @InitValue("0") + @ApiModelProperty("状态 0审批中 1已通过 2未通过") + Integer status; + + public String getChangeContent() { + return changeContent; + } + + public void setChangeContent(String changeContent) { + this.changeContent = changeContent; + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getApplyNumber() { + return applyNumber; + } + + public void setApplyNumber(String applyNumber) { + this.applyNumber = applyNumber; + } public String getContent() { return content; diff --git a/src/main/java/com/cym/model/Remote.java b/src/main/java/com/cym/model/Remote.java index f8c91d6173cf7fa4de2e0999d15772e58fc56707..abc900132a3c5dfa1cd07a954214c50c349fcab6 100644 --- a/src/main/java/com/cym/model/Remote.java +++ b/src/main/java/com/cym/model/Remote.java @@ -3,25 +3,39 @@ package com.cym.model; import cn.craccd.sqlHelper.bean.BaseModel; import cn.craccd.sqlHelper.config.InitValue; import cn.craccd.sqlHelper.config.Table; +import io.swagger.annotations.ApiModelProperty; @Table public class Remote extends BaseModel{ + @ApiModelProperty("访问协议") String protocol; + @ApiModelProperty("ip") String ip; + @ApiModelProperty("端口") Integer port; + @ApiModelProperty("状态 0 掉线 1在线") @InitValue("0") Integer status; // 0 掉线 1在线 + @ApiModelProperty("授权码") String creditKey; + @ApiModelProperty("用户名") String name; + @ApiModelProperty("密码") String pass; + @ApiModelProperty("版本") String version; + @ApiModelProperty("操作系统") String system; + @ApiModelProperty("别名") String descr; + @ApiModelProperty("是否监控") @InitValue("0") Integer monitor; - + @ApiModelProperty("父id") String parentId; + @ApiModelProperty("类型 0 服务器 1分组") Integer type; //0 服务器 1分组 + @ApiModelProperty("nginx状态") Integer nginx; //0未运行 1在运行 2未知 diff --git a/src/main/java/com/cym/service/BakService.java b/src/main/java/com/cym/service/BakService.java index 19c7c5eb752eea612da884797e2e50ae9ad59eef..d4f53c5f145b371d54cc5508301451a51838eaa0 100644 --- a/src/main/java/com/cym/service/BakService.java +++ b/src/main/java/com/cym/service/BakService.java @@ -1,23 +1,33 @@ package com.cym.service; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.cym.model.Bak; import com.cym.model.BakSub; +import com.cym.model.Remote; +import com.cym.utils.JsonResult; import cn.craccd.sqlHelper.bean.Page; import cn.craccd.sqlHelper.bean.Sort; import cn.craccd.sqlHelper.bean.Sort.Direction; import cn.craccd.sqlHelper.utils.ConditionAndWrapper; import cn.craccd.sqlHelper.utils.SqlHelper; +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; @Service public class BakService { @Autowired SqlHelper sqlHelper; + @Autowired + RemoteService remoteService; public Page getList(Page page) { return sqlHelper.findPage(new ConditionAndWrapper(), new Sort(Bak::getTime, Direction.DESC), page, Bak.class); @@ -44,4 +54,30 @@ public class BakService { return pre; } + public boolean hasApplyNumber(String applyNumber) { + return sqlHelper.findCountByQuery(new ConditionAndWrapper().eq(Bak::getApplyNumber, applyNumber), Bak.class) > 0; + } + + public boolean hasVersion(String version) { + return sqlHelper.findCountByQuery(new ConditionAndWrapper().eq(Bak::getVersion, version), Bak.class) > 0; + } + + public Boolean isApplying(String remoteName) { + if(StrUtil.isEmpty(remoteName)) { + return sqlHelper.findCountByQuery(new ConditionAndWrapper().eq(Bak::getStatus, 0), Bak.class) > 0; + } else { + Remote remote = remoteService.findByName(remoteName); + if (remote != null) { + Map map = new HashMap<>(); + map.put("creditKey", remote.getCreditKey()); + String rs = HttpUtil.post("http://" + remote.getIp() + ":" + remote.getPort() + "/api/nginx/isApplying", map); + System.out.println(rs); + JsonResult jsonResult = JSONUtil.toBean(rs, JsonResult.class); + return (Boolean) jsonResult.getObj(); + } + return false; + } + + } + } diff --git a/src/main/java/com/cym/service/ConfService.java b/src/main/java/com/cym/service/ConfService.java index 0057773be0f7d46f27012d5c384507156e7a460c..880f66d89a6de460c59d1159257af2c6a904005d 100644 --- a/src/main/java/com/cym/service/ConfService.java +++ b/src/main/java/com/cym/service/ConfService.java @@ -1,12 +1,13 @@ package com.cym.service; import java.io.File; -import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,6 +26,7 @@ import com.cym.model.Http; import com.cym.model.Location; import com.cym.model.Param; import com.cym.model.Password; +import com.cym.model.Remote; import com.cym.model.Server; import com.cym.model.Stream; import com.cym.model.Template; @@ -43,8 +45,9 @@ import cn.craccd.sqlHelper.utils.ConditionAndWrapper; import cn.craccd.sqlHelper.utils.SqlHelper; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.RuntimeUtil; import cn.hutool.core.util.StrUtil; -import cn.hutool.core.util.ZipUtil; +import cn.hutool.http.HttpUtil; @Service public class ConfService { @@ -65,6 +68,10 @@ public class ConfService { TemplateService templateService; @Autowired OperateLogService operateLogService; + @Autowired + BakService bakService; + @Autowired + RemoteService remoteService; public synchronized ConfExt buildConf(Boolean decompose, Boolean check) { ConfExt confExt = new ConfExt(); @@ -639,9 +646,64 @@ public class ConfService { return ToolUtils.handleConf(new NgxDumper(ngxConfig).dump()); } + public void replaceApply(String nginxContent, List subContent, List subName, String adminName, String version, String changeContent) { + Bak bak = new Bak(); + bak.setTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); + bak.setContent(nginxContent); + bak.setVersion(version); + bak.setChangeContent(changeContent); + sqlHelper.insert(bak); + + // 子文件 + for (int i = 0; i < subContent.size(); i++) { + BakSub bakSub = new BakSub(); + bakSub.setBakId(bak.getId()); + bakSub.setName(subName.get(i)); + bakSub.setContent(subContent.get(i)); + sqlHelper.insert(bakSub); + } + } + + public void replaceApplyOver(String applyNumber, Integer status, String adminName, String remoteName) { + if (StrUtil.isEmpty(remoteName)) { + // 本地替换 + Bak bak = sqlHelper.findOneByQuery(new ConditionAndWrapper().eq(Bak::getStatus, 0), Bak.class); + if (bak != null) { + bak.setApplyNumber(applyNumber); + bak.setStatus(status); + sqlHelper.updateById(bak); + + List subList = bakService.getSubList(bak.getId()); + List subName = new ArrayList<>(); + List subContent = new ArrayList<>(); + for (BakSub bakSub : subList) { + subName.add(bakSub.getName()); + subContent.add(bakSub.getContent()); + } + + if (status == 1) { + // 审批通过, 执行替换 + String nginxPath = settingService.get("nginxPath"); + replace(nginxPath, bak.getContent(), subContent, subName, true, adminName); + } + } + } else { + // 远程替换 + Remote remote = remoteService.findByName(remoteName); + if (remote != null) { + Map map = new HashMap<>(); + map.put("applyNumber", applyNumber); + map.put("status", status); + map.put("creditKey", remote.getCreditKey()); + String rs = HttpUtil.post("http://" + remote.getIp() + ":" + remote.getPort() + "/api/nginx/applyResult", map); + System.out.println(rs); + } + } + } + @Transactional public void replace(String nginxPath, String nginxContent, List subContent, List subName, Boolean isReplace, String adminName) { - + String beforeConf = null; if (isReplace) { // 先读取已有的配置 @@ -667,28 +729,46 @@ public class ConfService { } } - // 备份文件 - if (isReplace) { - Bak bak = new Bak(); - bak.setTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); - bak.setContent(nginxContent); - sqlHelper.insert(bak); - - // 备份子文件 - for (int i = 0; i < subContent.size(); i++) { - BakSub bakSub = new BakSub(); - bakSub.setBakId(bak.getId()); + // 重载Nginx + String nginxExe = settingService.get("nginxExe"); + String nginxDir = settingService.get("nginxDir"); - bakSub.setName(subName.get(i)); - bakSub.setContent(subContent.get(i)); - sqlHelper.insert(bakSub); + try { + String cmd = nginxExe + " -s reload -c " + nginxPath; + if (StrUtil.isNotEmpty(nginxDir)) { + cmd += " -p " + nginxDir; } + RuntimeUtil.execForStr(cmd); + } catch (Exception e) { + logger.info(e.getMessage(), e); + } - // 写入操作日志 - if (StrUtil.isNotEmpty(adminName)) { - operateLogService.addLog(beforeConf, nginxContent, adminName); - } + if (StrUtil.isNotEmpty(adminName)) { + operateLogService.addLog(beforeConf, nginxContent, adminName); } + + // 备份文件 +// if (isReplace) { +// Bak bak = new Bak(); +// bak.setTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss")); +// bak.setContent(nginxContent); +// sqlHelper.insert(bak); +// +// // 备份子文件 +// for (int i = 0; i < subContent.size(); i++) { +// BakSub bakSub = new BakSub(); +// bakSub.setBakId(bak.getId()); +// +// bakSub.setName(subName.get(i)); +// bakSub.setContent(subContent.get(i)); +// sqlHelper.insert(bakSub); +// } +// +// // 写入操作日志 +// if (StrUtil.isNotEmpty(adminName)) { +// operateLogService.addLog(beforeConf, nginxContent, adminName); +// } +// } } public AsycPack getAsycPack(String[] asycData) { diff --git a/src/main/java/com/cym/service/RemoteService.java b/src/main/java/com/cym/service/RemoteService.java index 0c29ce669141e72c43676f1961712bb894e0b034..ff312c01d724c9c38ff77b9e50f1ece679da7ed8 100644 --- a/src/main/java/com/cym/service/RemoteService.java +++ b/src/main/java/com/cym/service/RemoteService.java @@ -97,4 +97,8 @@ public class RemoteService { } + public Remote findByName(String remoteName) { + return sqlHelper.findOneByQuery(new ConditionAndWrapper().eq(Remote::getDescr, remoteName), Remote.class); + } + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 35b6ac12a7d9b2a9d5b081581b936ea778d766df..ab7a50bd339d4f03be423a1a7ec4aa273573c6d8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -37,4 +37,4 @@ logging: knife4j: enable: true - production: true # 生产环境屏蔽 \ No newline at end of file + production: false # 生产环境屏蔽 \ No newline at end of file diff --git a/src/main/resources/static/js/adminPage/bak/index.js b/src/main/resources/static/js/adminPage/bak/index.js index a9680c20f2550e5bade57cdcdeff9291d5e13eab..e3e7686dd74148e27151ef3a858c10e2651d0b6e 100644 --- a/src/main/resources/static/js/adminPage/bak/index.js +++ b/src/main/resources/static/js/adminPage/bak/index.js @@ -116,7 +116,7 @@ function diffUsingJS(pre, bak){ layer.open({ type : 1, title: false, - area : [ '90%', '90%' ], //宽高 + area : [ '1000px', '90%' ], //宽高 content : $('#diffoutput') }); } diff --git a/src/main/resources/static/js/adminPage/base.js b/src/main/resources/static/js/adminPage/base.js index 02933b4d1672ada9c9e9ce4516521536ed9e5871..05fc6acce5932caa2f50b5437c2c429b3747519f 100644 --- a/src/main/resources/static/js/adminPage/base.js +++ b/src/main/resources/static/js/adminPage/base.js @@ -62,6 +62,24 @@ $(function() { $("a[href='" + ctx + url.substr(1) + "']").parent().addClass("layui-this"); + //申请中判断 + $.ajax({ + type: 'POST', + url: ctx + '/adminPage/main/isApply', + dataType: 'json', + success: function(data) { + if (data.success && data.obj) { + $(".apply").attr("href","javascript:void(0)"); + $(".apply").css("color","gray"); + + $(".apply").unbind(); + } + }, + error: function() { + //layer.alert(commonStr.errorInfo); + } + }); + $.ajax({ type: 'POST', url: ctx + 'adminPage/login/getLocalType', diff --git a/src/main/resources/static/js/adminPage/conf/index.js b/src/main/resources/static/js/adminPage/conf/index.js index 8cce66f9fcb8d2a50830d6020ed11ff1eefeebfb..490071b0c5e7c27a056eb6bbac6d3e3d29811730 100644 --- a/src/main/resources/static/js/adminPage/conf/index.js +++ b/src/main/resources/static/js/adminPage/conf/index.js @@ -60,13 +60,43 @@ function buildJson(){ return json; } -function replace() { +function replaceApply() { + if($("#replaceApplyBtn").html().trim() == "等待审核"){ + layer.msg("审批已提交,请等待审核"); + return; + } + + $("#version").val(""); + $("#changeContent").val(""); + + layer.open({ + type : 1, + title : confStr.replaceFile, + area : [ '600px', '450px' ], // 宽高 + content : $('#applyForm') + }); +} + + +function replaceOver() { if ($("#nginxPath").val() == '') { layer.msg(confStr.jserror2); return; } + + if ($("#version").val() == '') { + layer.msg("未填写版本号"); + return; + } + if ($("#changeContent").val() == '') { + layer.msg("未填写变更内容"); + return; + } var json = buildJson(); + json.version = $("#version").val(); + json.applyNumber = $("#applyNumber").val(); + json.changeContent = $("#changeContent").val(); $.ajax({ type : 'POST', @@ -77,9 +107,10 @@ function replace() { dataType : 'json', success : function(data) { if (data.success) { - layer.msg(data.obj); - loadOrg(); - + layer.closeAll(); + //layer.msg("审批已提交,请等待审核"); + //$("#replaceApplyBtn").html("等待审核"); + location.reload(); } else { layer.alert(data.msg); } @@ -456,8 +487,8 @@ function showBak(){ layer.open({ type: 2, - title: bakStr.bakFile, - area : [ '900px', '90%' ], + title: '回滚', + area : [ '80%', '90%' ], content: ctx + "/adminPage/bak" }); } \ No newline at end of file diff --git a/src/main/resources/templates/adminPage/bak/index.html b/src/main/resources/templates/adminPage/bak/index.html index cb92dac6590cf9fe5b5a1966fc518f6c3fb99bdb..016e5997484c956a05b00b66fab0e7935deb66e8 100644 --- a/src/main/resources/templates/adminPage/bak/index.html +++ b/src/main/resources/templates/adminPage/bak/index.html @@ -3,14 +3,19 @@ <#include "/adminPage/common.html"/> +
-
+ @@ -20,6 +25,10 @@ ${commonStr.createTime} + 版本号 + 审批编号 + 变更内容 + 状态 ${commonStr.operation} @@ -27,11 +36,19 @@ <#list page.records as bak> ${bak.time} + ${bak.version} + ${bak.applyNumber} + ${bak.changeContent} + + <#if bak.status == 0>审批中 + <#if bak.status == 1>已通过 + <#if bak.status == 2>未通过 + - + diff --git a/src/main/resources/templates/adminPage/conf/index.html b/src/main/resources/templates/adminPage/conf/index.html index ea578ed19f9843b81834f0d45898a94c78b6f15c..0939555d6ca5a64bd348a7f8f58a318412f7c878 100644 --- a/src/main/resources/templates/adminPage/conf/index.html +++ b/src/main/resources/templates/adminPage/conf/index.html @@ -13,8 +13,8 @@ .title { margin-top: 5px; margin-bottom: 5px; - height:30px; - line-height:30px; + height: 30px; + line-height: 30px; cursor: pointer; } @@ -22,20 +22,17 @@ table.diff { width: 100%; } - -.long{ - width: 150px!important; +.long { + width: 150px !important; } - -.layui-form-radio{ +.layui-form-radio { width: 700px; } -input[type='radio']{ +input[type='radio'] { width: 1000px; } - @@ -78,20 +75,23 @@ input[type='radio']{
- +
- +
- +
- +
- +
@@ -109,7 +109,7 @@ input[type='radio']{
- +
@@ -118,18 +118,18 @@ input[type='radio']{
-
- +
+
- +
- +
@@ -137,8 +137,8 @@ input[type='radio']{
- - + +
@@ -151,25 +151,22 @@ input[type='radio']{
- -
+ + + - <#include '/adminPage/script.html'/> - <#include '/adminPage/select_root.html'/> - - - - - + <#include '/adminPage/script.html'/> + <#include '/adminPage/select_root.html'/> + + + + + diff --git a/src/main/resources/templates/adminPage/menu.html b/src/main/resources/templates/adminPage/menu.html index a1a7db8a9e8d7aa6caeef4d486a9c6e5181d5cb5..96a7ff50fa51564eb7e12f2e223b41cedd300176 100644 --- a/src/main/resources/templates/adminPage/menu.html +++ b/src/main/resources/templates/adminPage/menu.html @@ -15,19 +15,19 @@
- ${menuStr.basic} + ${menuStr.basic}
- ${menuStr.http} + ${menuStr.http}
- ${menuStr.stream} + ${menuStr.stream}
- ${menuStr.server} + ${menuStr.server}
- ${menuStr.upstream} + ${menuStr.upstream}
@@ -38,9 +38,12 @@
${menuStr.template}
-
+ + + +
${menuStr.password}
@@ -84,3 +87,4 @@
+