Browse Source

实现了管理应用重启,启动和停止的接口

dmaster 已部署到测试环境,从这个版本开始,需要保证 dev 和 test 的数据模型一致,dev 的修改要体现到 test 中
reghao 4 years ago
parent
commit
67cf6f9d15
49 changed files with 942 additions and 500 deletions
  1. 0 4
      common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/AppStatus.java
  2. 4 0
      common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/DeployResult.java
  3. 1 1
      common/src/main/java/cn/reghao/autodop/common/message/MessageType.java
  4. 10 0
      common/src/main/java/cn/reghao/autodop/common/message/ops/DockerOps.java
  5. 9 0
      common/src/main/java/cn/reghao/autodop/common/message/ops/OpsProcessor.java
  6. 0 1
      common/src/main/java/cn/reghao/autodop/common/mqtt/PubActionListener.java
  7. 1 1
      dagent/src/main/java/cn/reghao/autodop/dagent/app/DockerAppServiceImpl.java
  8. 13 9
      dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/DmasterMsgDispatcher.java
  9. 6 4
      dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/processor/app/AppOpsProcessor.java
  10. 70 0
      dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/processor/docker/DockerOpsProcessor.java
  11. 6 4
      dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/processor/machine/MachineOpsProcessor.java
  12. 11 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/constant/StatusOps.java
  13. 19 31
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/AppStatusController.java
  14. 13 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/BuildDeployController.java
  15. 3 6
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/AppConfigController.java
  16. 78 34
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/view/AppPageController.java
  17. 30 10
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/app/AppCrudService.java
  18. 3 8
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/app/ProjCrudService.java
  19. 19 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/query/AppBuildingQuery.java
  20. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/AppBuilding.java
  21. 18 23
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/AppDeploying.java
  22. 41 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/AppProperty.java
  23. 33 23
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/AppRunning.java
  24. 1 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/AppDeployingRepository.java
  25. 6 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/AppRunningRepository.java
  26. 107 9
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppBuildService.java
  27. 67 55
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppStatusService.java
  28. 11 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/entity/RoleType.java
  29. 0 9
      dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/OpsProcessor.java
  30. 27 44
      dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/app/AppDeployResultProcessor.java
  31. 30 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/app/AppOpsProcessor.java
  32. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/dagent/DagentOpsProcessor.java
  33. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/machine/MachineOpsProcessor.java
  34. 11 5
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/HomePageController.java
  35. 65 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/RoleController.java
  36. 3 40
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/RolePageController.java
  37. 58 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserController.java
  38. 10 24
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserPageController.java
  39. 3 3
      dmaster/src/main/resources/templates/app/build.html
  40. 2 2
      dmaster/src/main/resources/templates/app/config/app/index.html
  41. 3 4
      dmaster/src/main/resources/templates/app/deploy.html
  42. 71 42
      dmaster/src/main/resources/templates/app/status.html
  43. 1 1
      dmaster/src/main/resources/templates/main.html
  44. 2 2
      dmaster/src/main/resources/templates/system/role/index.html
  45. 0 0
      dmaster/src/main/resources/templates/system/role/resource.html
  46. 4 13
      dmaster/src/main/resources/templates/system/user/index.html
  47. 36 0
      dmaster/src/main/resources/templates/system/user/roleList.html
  48. 0 78
      dmaster/src/test/java/cn/reghao/autodop/dmaster/app/entity/AppDeployingTest.java
  49. 33 0
      dmaster/src/test/java/cn/reghao/autodop/dmaster/app/service/AppBuildServiceTest.java

+ 0 - 4
common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/AppStatus.java

@@ -19,8 +19,4 @@ public class AppStatus {
     private Boolean isRunning;
     private LocalDateTime startTime;
     private Integer pid;
-
-    public AppStatus vo() {
-        return this;
-    }
 }

+ 4 - 0
common/src/main/java/cn/reghao/autodop/common/dagent/app/api/data/DeployResult.java

@@ -3,6 +3,8 @@ package cn.reghao.autodop.common.dagent.app.api.data;
 import cn.reghao.autodop.common.result.Result;
 import lombok.Data;
 
+import java.time.LocalDateTime;
+
 /**
  * @author reghao
  * @date 2021-05-28 13:48:01
@@ -12,6 +14,7 @@ public class DeployResult {
     private String buildLogId;
     private String machineId;
     private String machineIpv4;
+    private LocalDateTime deployTime;
     private Result result;
     private AppStatus appStatus;
 
@@ -19,5 +22,6 @@ public class DeployResult {
         this.buildLogId = buildLogId;
         this.machineId = machineId;
         this.machineIpv4 = machineIpv4;
+        this.deployTime = LocalDateTime.now();
     }
 }

+ 1 - 1
common/src/main/java/cn/reghao/autodop/common/message/MessageType.java

@@ -5,5 +5,5 @@ package cn.reghao.autodop.common.message;
  * @date 2020-12-25 17:49:44
  */
 public enum MessageType {
-    dagentType, machineType, appType
+    dagentType, machineType, appType, dockerType
 }

+ 10 - 0
common/src/main/java/cn/reghao/autodop/common/message/ops/DockerOps.java

@@ -0,0 +1,10 @@
+package cn.reghao.autodop.common.message.ops;
+
+/**
+ * @author reghao
+ * @date 2020-12-25 19:15:00
+ */
+public enum DockerOps {
+    dockerImage,
+    dockerImageResult,
+}

+ 9 - 0
common/src/main/java/cn/reghao/autodop/common/message/ops/OpsProcessor.java

@@ -0,0 +1,9 @@
+package cn.reghao.autodop.common.message.ops;
+
+/**
+ * @author reghao
+ * @date 2021-06-09 13:43:16
+ */
+public interface OpsProcessor {
+    void process(String ops, String payload) throws Exception;
+}

+ 0 - 1
common/src/main/java/cn/reghao/autodop/common/mqtt/PubActionListener.java

@@ -15,7 +15,6 @@ public class PubActionListener implements IMqttActionListener {
     @Override
     public void onSuccess(IMqttToken pubToken) {
         int msgId = pubToken.getMessageId();
-        log.info("MQTT 消息 {} 发布成功...", msgId);
     }
 
     @Override

+ 1 - 1
dagent/src/main/java/cn/reghao/autodop/dagent/app/DockerAppServiceImpl.java

@@ -64,7 +64,7 @@ public class DockerAppServiceImpl implements AppService {
             appStatus.setStartTime(DateTimeConverter.localDateTime(state.getStartedAt()));
             appStatus.setPid(state.getPid());
         } else {
-            appStatus.setPid(0);
+            appStatus.setPid(-1);
         }
         return appStatus;
     }

+ 13 - 9
dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/DmasterMsgDispatcher.java

@@ -4,6 +4,8 @@ import cn.reghao.autodop.common.message.AsyncMsg;
 import cn.reghao.autodop.common.message.MessageType;
 import cn.reghao.autodop.common.utils.MachineId;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
+import cn.reghao.autodop.dagent.mqttsub.processor.app.AppOpsProcessor;
+import cn.reghao.autodop.dagent.mqttsub.processor.machine.MachineOpsProcessor;
 import lombok.extern.slf4j.Slf4j;
 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
 import org.eclipse.paho.client.mqttv3.MqttCallback;
@@ -23,14 +25,14 @@ import java.lang.management.ManagementFactory;
 public class DmasterMsgDispatcher implements MqttCallback {
     private String machineId;
     private long startTime;
-    private MachineOpsDispatcher machineOpsDispatcher;
-    private AppOpsDispatcher appOpsDispatcher;
+    private MachineOpsProcessor machineOpsProcessor;
+    private AppOpsProcessor appOpsProcessor;
 
-    public DmasterMsgDispatcher(MachineOpsDispatcher machineOpsDispatcher, AppOpsDispatcher appOpsDispatcher) {
+    public DmasterMsgDispatcher(MachineOpsProcessor machineOpsProcessor, AppOpsProcessor appOpsProcessor) {
         this.machineId = MachineId.id();
         this.startTime = ManagementFactory.getRuntimeMXBean().getStartTime();
-        this.machineOpsDispatcher = machineOpsDispatcher;
-        this.appOpsDispatcher = appOpsDispatcher;
+        this.machineOpsProcessor = machineOpsProcessor;
+        this.appOpsProcessor = appOpsProcessor;
     }
 
     @Override
@@ -54,12 +56,14 @@ public class DmasterMsgDispatcher implements MqttCallback {
 
             switch (MessageType.valueOf(type)) {
                 case machineType:
-                    log.info("执行 machine 相关操作...");
-                    machineOpsDispatcher.dispatch(ops, payload);
+                    machineOpsProcessor.process(ops, payload);
                     break;
                 case appType:
-                    log.info("执行 app 相关操作...");
-                    appOpsDispatcher.dispatch(ops, payload);
+                    appOpsProcessor.process(ops, payload);
+                    break;
+                case dagentType:
+                    break;
+                case dockerType:
                     break;
                 default:
             }

+ 6 - 4
dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/AppOpsDispatcher.java → dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/processor/app/AppOpsProcessor.java

@@ -1,9 +1,10 @@
-package cn.reghao.autodop.dagent.mqttsub;
+package cn.reghao.autodop.dagent.mqttsub.processor.app;
 
 import cn.reghao.autodop.common.message.AsyncMsg;
 import cn.reghao.autodop.common.message.CallResult;
 import cn.reghao.autodop.common.message.MessageType;
 import cn.reghao.autodop.common.message.ops.AppOps;
+import cn.reghao.autodop.common.message.ops.OpsProcessor;
 import cn.reghao.autodop.common.mqtt.MqttPub;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dagent.app.App;
@@ -17,18 +18,19 @@ import org.springframework.stereotype.Component;
  */
 @Slf4j
 @Component
-public class AppOpsDispatcher {
+public class AppOpsProcessor implements OpsProcessor {
     private MqttPub mqttPub;
     private String topic;
     private App app;
     
-    public AppOpsDispatcher(MqttPub mqttPub, App app) {
+    public AppOpsProcessor(MqttPub mqttPub, App app) {
         this.mqttPub = mqttPub;
         this.topic = "dmaster";
         this.app = app;
     }
 
-    public void dispatch(String ops, String payload) throws MqttException {
+    @Override
+    public void process(String ops, String payload) throws MqttException {
         AsyncMsg asyncMsg;
         switch (AppOps.valueOf(ops)) {
             case appDeploy:

+ 70 - 0
dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/processor/docker/DockerOpsProcessor.java

@@ -0,0 +1,70 @@
+package cn.reghao.autodop.dagent.mqttsub.processor.docker;
+
+import cn.reghao.autodop.common.message.AsyncMsg;
+import cn.reghao.autodop.common.message.CallResult;
+import cn.reghao.autodop.common.message.MessageType;
+import cn.reghao.autodop.common.message.ops.AppOps;
+import cn.reghao.autodop.common.message.ops.OpsProcessor;
+import cn.reghao.autodop.common.mqtt.MqttPub;
+import cn.reghao.autodop.common.utils.serializer.JsonConverter;
+import cn.reghao.autodop.dagent.app.App;
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author reghao
+ * @date 2020-12-30 10:26:47
+ */
+@Slf4j
+@Component
+public class DockerOpsProcessor implements OpsProcessor {
+    private MqttPub mqttPub;
+    private String topic;
+    private App app;
+
+    public DockerOpsProcessor(MqttPub mqttPub, App app) {
+        this.mqttPub = mqttPub;
+        this.topic = "dmaster";
+        this.app = app;
+    }
+
+    @Override
+    public void process(String ops, String payload) throws MqttException {
+        AsyncMsg asyncMsg;
+        switch (AppOps.valueOf(ops)) {
+            case appDeploy:
+                asyncMsg = AsyncMsg.asyncMsg(MessageType.appType.name(), AppOps.appDeployResult.name(),
+                        JsonConverter.objectToJson(app.deploy(payload)));
+                log.info("部署应用完成...");
+                break;
+            case appStatus:
+                asyncMsg = AsyncMsg.asyncMsg(MessageType.appType.name(), AppOps.appStatusResult.name(),
+                        JsonConverter.objectToJson(app.status(payload)));
+                break;
+            case appRestart:
+                asyncMsg = AsyncMsg.asyncMsg(MessageType.appType.name(), AppOps.appRestartResult.name(),
+                        JsonConverter.objectToJson(app.restart(payload)));
+                break;
+            case appStop:
+                asyncMsg = AsyncMsg.asyncMsg(MessageType.appType.name(), AppOps.appStopResult.name(),
+                        JsonConverter.objectToJson(app.stop(payload)));
+                break;
+            case appStart:
+                asyncMsg = AsyncMsg.asyncMsg(MessageType.appType.name(), AppOps.appStartResult.name(),
+                        JsonConverter.objectToJson(app.start(payload)));
+                break;
+            case appLog:
+                asyncMsg = AsyncMsg.asyncMsg(MessageType.appType.name(), AppOps.appLogResult.name(),
+                        JsonConverter.objectToJson(app.log(payload)));
+                break;
+            default:
+                log.error("AppOps 中没有相应类型...");
+                asyncMsg = AsyncMsg.asyncMsg(MessageType.appType.name(), AppOps.appDeployResult.name(),
+                        JsonConverter.objectToJson(CallResult.error("AppOps 中没有相应类型...")));
+                break;
+        }
+
+        mqttPub.pub(topic, JsonConverter.objectToJson(asyncMsg));
+    }
+}

+ 6 - 4
dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/MachineOpsDispatcher.java → dagent/src/main/java/cn/reghao/autodop/dagent/mqttsub/processor/machine/MachineOpsProcessor.java

@@ -1,8 +1,9 @@
-package cn.reghao.autodop.dagent.mqttsub;
+package cn.reghao.autodop.dagent.mqttsub.processor.machine;
 
 import cn.reghao.autodop.common.dagent.machine.Machine;
 import cn.reghao.autodop.common.message.*;
 import cn.reghao.autodop.common.message.ops.MachineOps;
+import cn.reghao.autodop.common.message.ops.OpsProcessor;
 import cn.reghao.autodop.common.mqtt.MqttPub;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import lombok.extern.slf4j.Slf4j;
@@ -15,18 +16,19 @@ import org.springframework.stereotype.Component;
  */
 @Slf4j
 @Component
-public class MachineOpsDispatcher {
+public class MachineOpsProcessor implements OpsProcessor {
     private MqttPub mqttPub;
     private String topic;
     private Machine machine;
 
-    public MachineOpsDispatcher(MqttPub mqttPub, Machine machine) {
+    public MachineOpsProcessor(MqttPub mqttPub, Machine machine) {
         this.mqttPub = mqttPub;
         this.topic = "dmaster";
         this.machine = machine;
     }
 
-    public void dispatch(String ops, String payload) throws MqttException {
+    @Override
+    public void process(String ops, String payload) throws MqttException {
         AsyncMsg asyncMsg;
         switch (MachineOps.valueOf(ops)) {
             case machineState:

+ 11 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/constant/StatusOps.java

@@ -0,0 +1,11 @@
+package cn.reghao.autodop.dmaster.app.constant;
+
+/**
+ * 应用状态操作
+ *
+ * @author reghao
+ * @date 2019-10-18 14:31:29
+ */
+public enum StatusOps {
+    restart, stop, start
+}

+ 19 - 31
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/StatusController.java → dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/AppStatusController.java

@@ -1,19 +1,18 @@
 package cn.reghao.autodop.dmaster.app.controller;
 
-import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
+import cn.reghao.autodop.dmaster.app.constant.StatusOps;
 import cn.reghao.autodop.dmaster.app.service.AppStatusService;
 import cn.reghao.autodop.dmaster.utils.WebBody;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogFile;
-import cn.reghao.autodop.dmaster.utils.db.PageList;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.MqttException;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * @author reghao
@@ -23,48 +22,44 @@ import java.util.Map;
 @Api(tags = "应用状态管理接口")
 @RestController
 @RequestMapping("/api/app/status")
-public class StatusController {
+public class AppStatusController {
     private AppStatusService statusService;
     
-    public StatusController(AppStatusService statusService) {
+    public AppStatusController(AppStatusService statusService) {
         this.statusService = statusService;
     }
 
     @ApiOperation(value = "重启应用")
-    @PostMapping(value = "/restart/{appId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> restart(@PathVariable("appId") String appId) {
+    @PostMapping(value = "/restart/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public ResponseEntity<String> restart(@PathVariable("appId") String appId,
+                                          @PathVariable("machineId") String machineId) throws MqttException {
+        statusService.changeStatus(appId, machineId, StatusOps.restart);
         return ResponseEntity.ok().body(WebBody.success(appId + " 已重启"));
     }
 
     @ApiOperation(value = "停止应用")
-    @PostMapping(value = "/stop/{appId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> stop(@PathVariable("appId") String appId) {
-        Map<String, AppStatus> map = statusService.stop(appId);
+    @PostMapping(value = "/stop/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public ResponseEntity<String> stop(@PathVariable("appId") String appId,
+                                       @PathVariable("machineId") String machineId) throws MqttException {
+        statusService.changeStatus(appId, machineId, StatusOps.stop);
         return ResponseEntity.ok().body(WebBody.success(appId + " 已停止"));
     }
 
     @ApiOperation(value = "启动应用")
-    @PostMapping(value = "/start/{appId}", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> start(@PathVariable("appId") String appId) {
-        Map<String, AppStatus> map = statusService.start(appId);
+    @PostMapping(value = "/start/{appId}/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public ResponseEntity<String> start(@PathVariable("appId") String appId,
+                                        @PathVariable("machineId") String machineId) throws MqttException {
+        statusService.changeStatus(appId, machineId, StatusOps.start);
         return ResponseEntity.ok().body(WebBody.success(appId + " 已启动"));
     }
 
-    @ApiOperation(value = "刷新已部署应用列表")
+    @ApiOperation(value = "刷新已部署应用状态")
     @PostMapping("/refresh}")
-    public ResponseEntity<String> refreshDeployedApps(@RequestParam("env") String env) {
-        statusService.refreshDeployedApps(env);
+    public ResponseEntity<String> refreshDeployedApps() {
+        statusService.refreshAppStatus();
         return ResponseEntity.ok().body(WebBody.success());
     }
 
-    @ApiOperation(value = "所有已部署应用的运行状态")
-    @GetMapping("/list")
-    public ResponseEntity<String> status(@RequestParam("page") int page, @RequestParam("size") int size,
-                                         @RequestParam("env") String env) {
-        PageList<AppStatus> pageList = statusService.deployedAppStatus(page, size, env);
-        return ResponseEntity.ok().body(WebBody.success(pageList));
-    }
-
     @ApiOperation(value = "获取指定主机上应用的所有日志文件")
     @GetMapping("/log/files")
     public ResponseEntity<String> appLogFiles(@RequestParam("machineId") String machineId,
@@ -83,11 +78,4 @@ public class StatusController {
         List<String> logs = statusService.logContent(appId, logType, logLevel, machineId, logFile);
         return ResponseEntity.ok().body(WebBody.success(logs));
     }
-
-    @ApiOperation(value = "某个已部署应用的运行状态")
-    @GetMapping("/{appId}")
-    public ResponseEntity<String> appStatus(@PathVariable("appId") String appId) {
-        Map<String, AppStatus> map = statusService.appStatus(appId);
-        return ResponseEntity.ok().body(WebBody.success(map));
-    }
 }

+ 13 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/BuildDeployController.java

@@ -55,10 +55,21 @@ public class BuildDeployController {
         return WebBody.success();
     }
 
-    @ApiOperation(value = "刷新应用构建部署列表")
+    @ApiOperation(value = "部署应用")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name="appId", value="应用 ID", paramType="query", dataType = "String"),
+            @ApiImplicitParam(name="commitId", value="代码版本", paramType="query", dataType = "String")
+    })
+    @PostMapping(value = "/deploy/{appId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deployApp(@PathVariable("appId") String appId) {
+        log.info("部署 {}", appId);
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "刷新应用构建, 部署和运行列表")
     @PostMapping(value = "/refresh", produces = MediaType.APPLICATION_JSON_VALUE)
     public String refreshAppBuilding() {
-        buildService.refreshAppBuilding();
+        buildService.refreshing();
         return WebBody.success();
     }
 

+ 3 - 6
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/crud/AppConfigController.java

@@ -40,12 +40,8 @@ public class AppConfigController {
     @ApiOperation(value = "添加/修改应用编排")
     @PostMapping(value = "/app", produces = MediaType.APPLICATION_JSON_VALUE)
     public ResponseEntity<String> addAppOrchestration(@Validated AppOrchestrationValidator validator,
-                                                      AppOrchestration appOrchestration) throws Exception {
-        if (appOrchestration.getId() == null) {
-            appCrudService.insert(appOrchestration);
-        } else {
-            appCrudService.update(appOrchestration);
-        }
+                                                      AppOrchestration app) throws Exception {
+        appCrudService.insertOrUpdate(app);
         return ResponseEntity.ok().body(WebBody.success());
     }
 
@@ -93,6 +89,7 @@ public class AppConfigController {
     @ApiOperation(value = "删除项目编排")
     @DeleteMapping(value = "/proj/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
     public ResponseEntity<String> deleteProjOrchestration(@PathVariable("id") ProjOrchestration proj) {
+        projCrudService.delete(proj);
         return ResponseEntity.ok().body(WebBody.success());
     }
 }

+ 78 - 34
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/view/AppPageController.java

@@ -1,17 +1,23 @@
 package cn.reghao.autodop.dmaster.app.controller.view;
 
+import cn.reghao.autodop.dmaster.app.constant.AppType;
 import cn.reghao.autodop.dmaster.app.constant.EnvType;
 import cn.reghao.autodop.dmaster.app.db.query.AppBuildingQuery;
 import cn.reghao.autodop.dmaster.app.entity.AppDeploying;
 import cn.reghao.autodop.dmaster.app.entity.AppRunning;
+import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
+import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
 import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
 import cn.reghao.autodop.dmaster.app.repository.AppBuildingRepository;
 import cn.reghao.autodop.dmaster.app.repository.AppDeployingRepository;
 import cn.reghao.autodop.dmaster.app.repository.AppRunningRepository;
 import cn.reghao.autodop.dmaster.app.entity.AppBuilding;
+import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.BuildLogRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.DeployLogRepository;
-import cn.reghao.autodop.dmaster.utils.WebBody;
+import cn.reghao.autodop.dmaster.auth.UserContext;
+import cn.reghao.autodop.dmaster.auth.entity.RoleType;
+import cn.reghao.autodop.dmaster.auth.entity.User;
 import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import io.swagger.annotations.Api;
@@ -22,9 +28,7 @@ import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * @author reghao
@@ -35,24 +39,21 @@ import java.util.Map;
 @Controller
 @RequestMapping("/app")
 public class AppPageController {
-    private AppBuildingRepository appBuildingRepository;
-    private AppDeployingRepository appDeployingRepository;
-    private AppRunningRepository appRunningRepository;
+    private AppOrchestrationRepository appRepository;
+    private AppBuildingRepository buildingRepository;
+    private AppDeployingRepository deployingRepository;
+    private AppRunningRepository runningRepository;
     private AppBuildingQuery buildingQuery;
-    private BuildLogRepository buildLogRepository;
-    private DeployLogRepository deployLogRepository;
-
-    public AppPageController(AppBuildingRepository appBuildingRepository,
-                             AppDeployingRepository appDeployingRepository,
-                             AppRunningRepository appRunningRepository,
-                             BuildLogRepository buildLogRepository,
-                             DeployLogRepository deployLogRepository,
+
+    public AppPageController(AppOrchestrationRepository appRepository,
+                             AppBuildingRepository buildingRepository,
+                             AppDeployingRepository deployingRepository,
+                             AppRunningRepository runningRepository,
                              AppBuildingQuery buildingQuery) {
-        this.appBuildingRepository = appBuildingRepository;
-        this.appDeployingRepository = appDeployingRepository;
-        this.appRunningRepository = appRunningRepository;
-        this.buildLogRepository = buildLogRepository;
-        this.deployLogRepository = deployLogRepository;
+        this.appRepository = appRepository;
+        this.buildingRepository = buildingRepository;
+        this.deployingRepository = deployingRepository;
+        this.runningRepository = runningRepository;
         this.buildingQuery = buildingQuery;
     }
 
@@ -78,10 +79,29 @@ public class AppPageController {
             return "/app/build";
         }
 
+        Set<String> set = new HashSet<>();
+        UserContext.currentUser().getAuthorities().forEach(auth -> {
+            set.add(auth.getAuthority());
+        });
+
+        String appType;
+        if (set.contains(RoleType.ROLE_BACKEND.name())) {
+            appType = AppType.dotnetCore.name();
+        } else if (set.contains(RoleType.ROLE_FRONTEND.name())) {
+            appType = AppType.npm.name();
+        } else {
+            appType = AppType.maven.name();
+        }
+
         PageRequest pageRequest = PageSort.pageRequest();
-        Page<AppBuilding> appBuildings = appBuildingRepository.findAllByEnv(env, pageRequest);
-        PageList<AppBuilding> pageList = PageList.pageList(appBuildings);
+        Page<AppBuilding> appBuildings;
+        if (set.contains(RoleType.ROLE_ADMIN.name())) {
+            appBuildings = buildingRepository.findAllByEnv(env, pageRequest);
+        } else {
+            appBuildings = buildingRepository.findAllByEnvAndAppType(env, appType, pageRequest);
+        }
 
+        PageList<AppBuilding> pageList = PageList.pageList(appBuildings);
         model.addAttribute("env", env);
         model.addAttribute("page", appBuildings);
         model.addAttribute("list", pageList.getList());
@@ -89,9 +109,16 @@ public class AppPageController {
     }
 
     @ApiOperation(value = "部署页面")
-    @GetMapping("/deploy/{buildLogId}")
-    public String deployPage(@PathVariable("buildLogId") String buildLogId, Model model) {
-        List<AppDeploying> list = appDeployingRepository.findByBuildLogId(buildLogId);
+    @GetMapping("/deploy/{appId}")
+    public String deployPage(@PathVariable("appId") String appId, Model model) {
+        AppOrchestration app = appRepository.findByIsDeleteFalseAndAppId(appId);
+        List<DeployConfig> deployConfigs = app.getDeployConfigs();
+        List<AppDeploying> list = new ArrayList<>();
+        for (DeployConfig deployConfig : deployConfigs) {
+            AppDeploying deploying = deployingRepository.findByAppIdAndMachineId(appId, deployConfig.getMachineId());
+            list.add(deploying);
+        }
+
         model.addAttribute("list", list);
         return "/app/deploy";
     }
@@ -107,15 +134,32 @@ public class AppPageController {
 
     @ApiOperation(value = "运行状态页面")
     @GetMapping("/status")
-    public String statusPage(Model model) {
-        int page = 1;
-        int size = 10;
-        PageRequest pageRequest =
-                PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC, "updateTime"));
-        Page<AppRunning> appRunningPage = appRunningRepository.findAll(pageRequest);
-        PageList<AppRunning> pageList = PageList.pageList(appRunningPage);
+    public String statusPage(@RequestParam(value = "env", required = false) String env,
+                             @RequestParam(value = "appName", required = false) String appName,
+                             Model model) {
+        if (env == null) {
+            env = EnvType.test.name();
+        }
 
-        model.addAttribute("page", appRunningPage);
+        if (appName != null) {
+            Map<String, String> map = new HashMap<>();
+            map.put("appName", appName);
+            List<AppRunning> list = buildingQuery.queryAppRunning(map);
+            Page<AppRunning> page = new PageImpl<>(list);
+            PageList<AppRunning> pageList = PageList.pageList(page);
+
+            model.addAttribute("env", env);
+            model.addAttribute("page", page);
+            model.addAttribute("list", pageList.getList());
+            return "/app/status";
+        }
+
+        PageRequest pageRequest = PageSort.pageRequest();
+        Page<AppRunning> appRunnings = runningRepository.findAllByEnv(env, pageRequest);
+        PageList<AppRunning> pageList = PageList.pageList(appRunnings);
+
+        model.addAttribute("env", env);
+        model.addAttribute("page", appRunnings);
         model.addAttribute("list", pageList.getList());
         return "/app/status";
     }
@@ -129,7 +173,7 @@ public class AppPageController {
         PageRequest pageRequest =
                 PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC, "updateTime"));
 
-        Page<AppBuilding> appBuildings = appBuildingRepository.findAllByEnv(env, pageRequest);
+        Page<AppBuilding> appBuildings = buildingRepository.findAllByEnv(env, pageRequest);
         PageList<AppBuilding> pageList = PageList.pageList(appBuildings);
 
         model.addAttribute("page", appBuildings);

+ 30 - 10
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/app/AppCrudService.java

@@ -2,9 +2,13 @@ package cn.reghao.autodop.dmaster.app.db.config.app;
 
 import cn.reghao.autodop.dmaster.app.constant.AppType;
 import cn.reghao.autodop.dmaster.app.db.config.SharedEntityChecker;
+import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
+import cn.reghao.autodop.dmaster.app.service.AppBuildService;
 import cn.reghao.autodop.dmaster.common.db.CrudOps;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
 import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
+import cn.reghao.autodop.dmaster.machine.entity.MachineInfo;
+import cn.reghao.autodop.dmaster.machine.repository.MachineInfoRepository;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
 
@@ -19,18 +23,40 @@ import java.util.List;
 @Service
 public class AppCrudService implements CrudOps<AppOrchestration> {
     private AppOrchestrationRepository appRepository;
+    private MachineInfoRepository machineRepository;
     private SharedEntityChecker sharedEntityChecker;
+    private AppBuildService appBuildService;
 
     public AppCrudService(AppOrchestrationRepository appRepository,
-                          SharedEntityChecker sharedEntityChecker) {
+                          MachineInfoRepository machineRepository,
+                          SharedEntityChecker sharedEntityChecker,
+                          AppBuildService appBuildService) {
         this.appRepository = appRepository;
+        this.machineRepository = machineRepository;
         this.sharedEntityChecker = sharedEntityChecker;
+        this.appBuildService = appBuildService;
     }
 
+    // TODO 同时更新 AppBuilding, AppDeploying 和 AppRunning
     @Override
-    public void insert(AppOrchestration app) throws Exception {
-        checkSharedEntity(app);
-        appRepository.save(app);
+    public void insertOrUpdate(AppOrchestration app) {
+        try {
+            checkSharedEntity(app);
+            List<DeployConfig> deployConfigs = app.getDeployConfigs();
+            deployConfigs.forEach(deployConfig -> {
+                String machineId = deployConfig.getMachineId();
+                MachineInfo machineInfo = machineRepository.findByMachineId(machineId);
+                if (machineInfo != null && !machineInfo.getNetworkInfo().isEmpty()) {
+                    deployConfig.setMachineIpv4(machineInfo.getNetworkInfo().get(0).getIpv4());
+                }
+            });
+            appRepository.save(app);
+            appBuildService.refreshAppBuilding(app);
+            appBuildService.refreshAppDeploying(app);
+            appBuildService.refreshAppRunning(app);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 
     public void copy(String from, String to) throws Exception {
@@ -71,12 +97,6 @@ public class AppCrudService implements CrudOps<AppOrchestration> {
         app.setUpdateTime(null);
     }
 
-    @Override
-    public void update(AppOrchestration app) throws Exception {
-        checkSharedEntity(app);
-        appRepository.save(app);
-    }
-
     private void checkSharedEntity(AppOrchestration app) throws Exception {
         if (app.getProj() == null) {
             sharedEntityChecker.checkAndSetBuildConfig(app);

+ 3 - 8
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/config/app/ProjCrudService.java

@@ -28,7 +28,7 @@ public class ProjCrudService implements CrudOps<ProjOrchestration> {
     }
 
     @Override
-    public void insert(ProjOrchestration proj) throws Exception {
+    public void insert(ProjOrchestration proj) {
         /*sharedEntityChecker.checkAndSetBuildConfig(proj.getBuildConfig());
         ProjOrchestration projEntity = projRepository.findByIsDeleteFalseAndProjId(proj.getProjId());
         if (projEntity != null) {
@@ -66,13 +66,8 @@ public class ProjCrudService implements CrudOps<ProjOrchestration> {
     }
 
     @Override
-    public void delete(String uniqueKey) throws Exception {
-        ProjOrchestration projEntity = projRepository.findByIsDeleteFalseAndProjId(uniqueKey);
-        if (projEntity == null) {
-            throw new Exception(uniqueKey + " 不存在");
-        }
-        projEntity.setIsDelete(true);
-        projRepository.save(projEntity);
+    public void delete(ProjOrchestration proj) {
+        projRepository.delete(proj);
     }
 
     @Override

+ 19 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/db/query/AppBuildingQuery.java

@@ -1,7 +1,9 @@
 package cn.reghao.autodop.dmaster.app.db.query;
 
 import cn.reghao.autodop.dmaster.app.entity.AppBuilding;
+import cn.reghao.autodop.dmaster.app.entity.AppRunning;
 import cn.reghao.autodop.dmaster.app.repository.AppBuildingRepository;
+import cn.reghao.autodop.dmaster.app.repository.AppRunningRepository;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
 
@@ -17,9 +19,12 @@ import java.util.Map;
 @Service
 public class AppBuildingQuery {
     private AppBuildingRepository buildingRepository;
+    private AppRunningRepository runningRepository;
 
-    public AppBuildingQuery(AppBuildingRepository buildingRepository) {
+    public AppBuildingQuery(AppBuildingRepository buildingRepository,
+                            AppRunningRepository runningRepository) {
         this.buildingRepository = buildingRepository;
+        this.runningRepository = runningRepository;
     }
 
     /**
@@ -39,4 +44,17 @@ public class AppBuildingQuery {
         };
         return buildingRepository.findAll(specification);
     }
+
+    public List<AppRunning> queryAppRunning(Map<String, String> kv) {
+        Specification<AppRunning> specification = (root, query, cb) -> {
+            List<Predicate> predicates = new ArrayList<>();
+            kv.forEach((name, value) -> {
+                predicates.add(cb.like(root.get(name), "%" + value + "%"));
+            });
+
+            // select * from app_building where app_id like '%test%' and app_name like '%测试%'
+            return cb.and(predicates.toArray(new Predicate[0]));
+        };
+        return runningRepository.findAll(specification);
+    }
 }

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/AppBuilding.java

@@ -25,8 +25,8 @@ import java.time.LocalDateTime;
 public class AppBuilding extends BaseEntity<Integer> {
     private String appId;
     private String appName;
-    private String env;
     private String appType;
+    private String env;
     private String branch;
     private Integer httpPort;
 

+ 18 - 23
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/AppDeploying.java

@@ -1,53 +1,48 @@
 package cn.reghao.autodop.dmaster.app.entity;
 
+import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
 import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
 import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
-import cn.reghao.autodop.dmaster.common.orm.BaseEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
 
 import javax.persistence.Entity;
 import java.time.LocalDateTime;
-import java.util.List;
 
 /**
  * @author reghao
  * @date 2021-05-21 09:57:35
  */
-@Data
+@NoArgsConstructor
 @EqualsAndHashCode(callSuper = false)
+@Data
 @Entity
-public class AppDeploying extends BaseEntity<Integer> {
-    private String appId;
+public class AppDeploying extends AppProperty {
     private String buildLogId;
-    private String machineId;
-    private String machineIpv4;
-    private Boolean isDeploy;
+    private String commitId;
+    private String packagePath;
     private LocalDateTime deployTime;
     private String deployResult;
     private String deployBy;
 
-    public static AppDeploying from(AppOrchestration app) {
-        String appId = app.getAppId();
-        List<DeployConfig> deployLogList = app.getDeployConfigs();
-
-        return null;
+    public AppDeploying(AppOrchestration app, DeployConfig deployConfig) {
+        super(app, deployConfig);
     }
 
-    public static AppDeploying from(String appId, String machineId, String machineIpv4) {
-        AppDeploying appDeploying = new AppDeploying();
-        appDeploying.setAppId(appId);
-        appDeploying.setMachineId(machineId);
-        appDeploying.setMachineIpv4(machineIpv4);
-        appDeploying.setIsDeploy(false);
-        return appDeploying;
+    public AppDeploying refresh(String appName, String machineIpv4) {
+        this.update0(appName, machineIpv4);
+        return this;
     }
 
-    public AppDeploying update(BuildLog buildLog) {
+    public AppDeploying update(BuildLog buildLog, DeployResult deployResult) {
         this.setBuildLogId(buildLog.getId());
-        this.setAppId(buildLog.getAppId());
-        this.setIsDeploy(false);
+        this.setCommitId(buildLog.getCommitInfo().getCommitId());
+        this.setPackagePath(buildLog.getPackagePath());
+        this.setDeployTime(deployResult.getDeployTime());
+        this.setDeployResult(deployResult.getResult().getMsg());
+        this.setDeployBy("某人");
         return this;
     }
 }

+ 41 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/AppProperty.java

@@ -0,0 +1,41 @@
+package cn.reghao.autodop.dmaster.app.entity;
+
+import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
+import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
+import cn.reghao.autodop.dmaster.common.orm.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.MappedSuperclass;
+
+/**
+ * @author reghao
+ * @date 2021-06-10 14:40:13
+ */
+@MappedSuperclass
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class AppProperty extends BaseEntity<Integer> {
+    private String appId;
+    private String appName;
+    private String appType;
+    private String env;
+    private String machineId;
+    private String machineIpv4;
+
+    public AppProperty(AppOrchestration app, DeployConfig deployConfig) {
+        this.appId = app.getAppId();
+        this.appName = app.getAppName();
+        this.appType = app.getAppType();
+        this.env = app.getEnv();
+        this.machineId = deployConfig.getMachineId();
+        this.machineIpv4 = deployConfig.getMachineIpv4();
+    }
+
+    protected void update0(String appName, String machineIpv4) {
+        this.setAppName(appName);
+        this.setMachineIpv4(machineIpv4);
+    }
+}

+ 33 - 23
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/entity/AppRunning.java

@@ -1,10 +1,12 @@
 package cn.reghao.autodop.dmaster.app.entity;
 
 import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
+import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
+import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
 import cn.reghao.autodop.dmaster.app.entity.log.BuildLog;
-import cn.reghao.autodop.dmaster.common.orm.BaseEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
 
 import javax.persistence.Entity;
 import java.time.LocalDateTime;
@@ -13,35 +15,43 @@ import java.time.LocalDateTime;
  * @author reghao
  * @date 2021-05-31 13:36:46
  */
-@Data
+@NoArgsConstructor
 @EqualsAndHashCode(callSuper = false)
+@Data
 @Entity
-public class AppRunning extends BaseEntity<Integer> {
+public class AppRunning extends AppProperty {
     private String buildLogId;
-    private String appId;
-    private String env;
-    private String branch;
-    private String commitId;
-    private String machineId;
-    private String machineIpv4;
+    private String packagePath;
     private Boolean isRunning;
     private LocalDateTime startTime;
     private Integer pid;
     private LocalDateTime lastCheck;
 
-    public static AppRunning from(BuildLog buildLog, AppStatus appStatus) {
-        AppRunning appRunning = new AppRunning();
-        appRunning.setBuildLogId(buildLog.getId());
-        appRunning.setAppId(appStatus.getAppId());
-        appRunning.setEnv(buildLog.getEnv());
-        appRunning.setBranch(buildLog.getBranch());
-        appRunning.setCommitId(buildLog.getCommitInfo().getCommitId());
-        appRunning.setMachineId(appStatus.getMachineId());
-        appRunning.setMachineIpv4(appStatus.getMachineIpv4());
-        appRunning.setStartTime(appStatus.getStartTime());
-        appRunning.setPid(appStatus.getPid());
-        appRunning.setIsRunning(appStatus.getIsRunning());
-        appRunning.setLastCheck(LocalDateTime.now());
-        return appRunning;
+    public AppRunning(AppOrchestration app, DeployConfig deployConfig) {
+        super(app, deployConfig);
+    }
+
+    public AppRunning refresh(String appName, String machineIpv4) {
+        this.update0(appName, machineIpv4);
+        return this;
+    }
+
+    public AppRunning update(BuildLog buildLog, AppStatus appStatus) {
+        this.setBuildLogId(buildLog.getId());
+        this.setPackagePath(buildLog.getPackagePath());
+        this.setIsRunning(appStatus.getIsRunning());
+        this.setStartTime(appStatus.getStartTime());
+        this.setPid(appStatus.getPid());
+        this.setLastCheck(LocalDateTime.now());
+        return this;
+    }
+
+    public AppRunning update(AppStatus appStatus) {
+        this.setPackagePath(appStatus.getPackagePath());
+        this.setIsRunning(appStatus.getIsRunning());
+        this.setStartTime(appStatus.getStartTime());
+        this.setPid(appStatus.getPid());
+        this.setLastCheck(LocalDateTime.now());
+        return this;
     }
 }

+ 1 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/AppDeployingRepository.java

@@ -13,4 +13,5 @@ public interface AppDeployingRepository extends JpaRepository<AppDeploying, Inte
     List<AppDeploying> findByAppId(String appId);
     List<AppDeploying> findByBuildLogId(String buildLogId);
     AppDeploying findByBuildLogIdAndMachineId(String buildLogId, String machineId);
+    AppDeploying findByAppIdAndMachineId(String appId, String machineId);
 }

+ 6 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/repository/AppRunningRepository.java

@@ -1,12 +1,16 @@
 package cn.reghao.autodop.dmaster.app.repository;
 
 import cn.reghao.autodop.dmaster.app.entity.AppRunning;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 
 /**
  * @author reghao
  * @date 2021-05-24 15:20:24
  */
-public interface AppRunningRepository extends JpaRepository<AppRunning, Integer> {
-    AppRunning findByAppId(String appId);
+public interface AppRunningRepository extends JpaRepository<AppRunning, Integer>, JpaSpecificationExecutor<AppRunning> {
+    AppRunning findByAppIdAndMachineId(String appId, String machineId);
+    Page<AppRunning> findAllByEnv(String env, Pageable pageable);
 }

+ 107 - 9
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppBuildService.java

@@ -1,14 +1,19 @@
 package cn.reghao.autodop.dmaster.app.service;
 
 import cn.reghao.autodop.dmaster.app.entity.AppBuilding;
+import cn.reghao.autodop.dmaster.app.entity.AppDeploying;
+import cn.reghao.autodop.dmaster.app.entity.AppRunning;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
+import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
 import cn.reghao.autodop.dmaster.app.repository.AppBuildingRepository;
 import cn.reghao.autodop.dmaster.app.repository.AppDeployingRepository;
+import cn.reghao.autodop.dmaster.app.repository.AppRunningRepository;
 import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * @author reghao
@@ -19,32 +24,125 @@ public class AppBuildService {
     private AppOrchestrationRepository appRepository;
     private AppBuildingRepository buildingRepository;
     private AppDeployingRepository deployingRepository;
+    private AppRunningRepository runningRepository;
 
     public AppBuildService(AppOrchestrationRepository appRepository,
                            AppBuildingRepository buildingRepository,
-                           AppDeployingRepository deployingRepository) {
+                           AppDeployingRepository deployingRepository,
+                           AppRunningRepository runningRepository) {
         this.appRepository = appRepository;
         this.buildingRepository = buildingRepository;
         this.deployingRepository = deployingRepository;
+        this.runningRepository = runningRepository;
+    }
+
+    public void refreshing() {
+        refreshAppBuilding();
+        refreshAppDeploying();
+        refreshAppRunning();
     }
 
     public void refreshAppBuilding() {
         List<AppOrchestration> apps = appRepository.findAllByEnableIsTrue();
-        List<AppBuilding> newList = new ArrayList<>();
-        List<AppBuilding> existingList = new ArrayList<>();
+        List<AppBuilding> list = new ArrayList<>();
         for (AppOrchestration app : apps) {
-            AppBuilding entity = buildingRepository.findByAppId(app.getAppId());
-            if (entity == null) {
-                newList.add(new AppBuilding(app));
+            AppBuilding appBuilding = buildingRepository.findByAppId(app.getAppId());
+            if (appBuilding == null) {
+                list.add(new AppBuilding(app));
             } else {
-                existingList.add(entity.refresh(app));
+                list.add(appBuilding.refresh(app));
             }
         }
+        buildingRepository.saveAll(list);
+    }
 
-        buildingRepository.saveAll(newList);
-        buildingRepository.saveAll(existingList);
+    public void refreshAppBuilding(AppOrchestration app) {
+        AppBuilding appBuilding = buildingRepository.findByAppId(app.getAppId());
+        if (appBuilding == null) {
+            appBuilding = new AppBuilding(app);
+        } else {
+            appBuilding.refresh(app);
+        }
+        buildingRepository.save(appBuilding);
     }
 
     public void refreshAppDeploying() {
+        List<AppOrchestration> apps = appRepository.findAllByEnableIsTrue().stream()
+                .filter(app -> !app.getDeployConfigs().isEmpty())
+                .collect(Collectors.toList());
+
+        List<AppDeploying> list = new ArrayList<>();
+        for (AppOrchestration app : apps) {
+            String appId = app.getAppId();
+            List<DeployConfig> deployConfigs = app.getDeployConfigs();
+            for (DeployConfig deployConfig : deployConfigs) {
+                String machineId = deployConfig.getMachineId();
+                AppDeploying appDeploying = deployingRepository.findByAppIdAndMachineId(appId, machineId);
+                if (appDeploying == null) {
+                    appDeploying = new AppDeploying(app, deployConfig);
+                } else {
+                    appDeploying.refresh(app.getAppName(), deployConfig.getMachineIpv4());
+                }
+                list.add(appDeploying);
+            }
+        }
+        deployingRepository.saveAll(list);
+    }
+
+    public void refreshAppDeploying(AppOrchestration app) {
+        String appId = app.getAppId();
+        List<DeployConfig> deployConfigs = app.getDeployConfigs();
+        List<AppDeploying> list = new ArrayList<>();
+        for (DeployConfig deployConfig : deployConfigs) {
+            String machineId = deployConfig.getMachineId();
+            AppDeploying appDeploying = deployingRepository.findByAppIdAndMachineId(appId, machineId);
+            if (appDeploying == null) {
+                appDeploying = new AppDeploying(app, deployConfig);
+            } else {
+                appDeploying.refresh(app.getAppName(), deployConfig.getMachineIpv4());
+            }
+            list.add(appDeploying);
+        }
+        deployingRepository.saveAll(list);
+    }
+
+    public void refreshAppRunning() {
+        List<AppOrchestration> apps = appRepository.findAllByEnableIsTrue().stream()
+                .filter(app -> !app.getDeployConfigs().isEmpty())
+                .collect(Collectors.toList());
+
+        List<AppRunning> list = new ArrayList<>();
+        for (AppOrchestration app : apps) {
+            String appId = app.getAppId();
+            List<DeployConfig> deployConfigs = app.getDeployConfigs();
+            for (DeployConfig deployConfig : deployConfigs) {
+                String machineId = deployConfig.getMachineId();
+                AppRunning appRunning = runningRepository.findByAppIdAndMachineId(appId, machineId);
+                if (appRunning == null) {
+                    appRunning = new AppRunning(app, deployConfig);
+                } else {
+                    appRunning.refresh(app.getAppName(), deployConfig.getMachineIpv4());
+                }
+                list.add(appRunning);
+            }
+        }
+        runningRepository.saveAll(list);
+    }
+
+    public void refreshAppRunning(AppOrchestration app) {
+        String appId = app.getAppId();
+        List<DeployConfig> deployConfigs = app.getDeployConfigs();
+        List<AppRunning> list = new ArrayList<>();
+        for (DeployConfig deployConfig : deployConfigs) {
+            String machineId = deployConfig.getMachineId();
+            AppRunning appRunning = runningRepository.findByAppIdAndMachineId(appId, machineId);
+            if (appRunning == null) {
+                appRunning = new AppRunning(app, deployConfig);
+            } else {
+                appRunning.refresh(app.getAppName(), deployConfig.getMachineIpv4());
+            }
+            list.add(appRunning);
+        }
+        runningRepository.saveAll(list);
     }
 }

+ 67 - 55
dmaster/src/main/java/cn/reghao/autodop/dmaster/app/service/AppStatusService.java

@@ -4,19 +4,19 @@ import cn.reghao.autodop.common.message.AsyncMsg;
 import cn.reghao.autodop.common.message.MessageType;
 import cn.reghao.autodop.common.message.ops.AppOps;
 import cn.reghao.autodop.common.dagent.app.api.data.AppIdArgs;
-import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
+import cn.reghao.autodop.common.mqtt.MqttPub;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
+import cn.reghao.autodop.dmaster.app.constant.StatusOps;
+import cn.reghao.autodop.dmaster.app.entity.AppRunning;
 import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
-import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
 import cn.reghao.autodop.common.dagent.app.api.data.log.LogFile;
-import cn.reghao.autodop.dmaster.utils.db.PageList;
+import cn.reghao.autodop.dmaster.app.repository.AppRunningRepository;
+import org.eclipse.paho.client.mqttv3.MqttException;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 /**
  * 应用状态管理
@@ -26,24 +26,75 @@ import java.util.Map;
  */
 @Service
 public class AppStatusService {
+    private MqttPub mqttPub;
+    private AppRunningRepository runningRepository;
     private BuildDeployCache cache;
 
-    public AppStatusService(BuildDeployCache cache) {
+    public AppStatusService(MqttPub mqttPub, AppRunningRepository runningRepository, BuildDeployCache cache) {
+        this.mqttPub = mqttPub;
+        this.runningRepository = runningRepository;
         this.cache = cache;
     }
 
-    /**
-     * TODO 刷新已部署的应用列表
-     *
-     * @param
-     * @return
-     * @date 2021-03-04 下午2:09
-     */
-    public void refreshDeployedApps(String env) {
+    public void changeStatus(String appId, String machineId, StatusOps statusOps) {
+        AppOrchestration app = cache.findByAppId(appId);
+        switch (statusOps) {
+            case restart:
+                setAppStatus(app, machineId, AppOps.appRestart);
+                break;
+            case stop:
+                setAppStatus(app, machineId, AppOps.appStop);
+                break;
+            case start:
+                setAppStatus(app, machineId, AppOps.appStart);
+                break;
+            default:
+                ;
+        }
     }
 
-    public PageList<AppStatus> deployedAppStatus(int page, int size, String env) {
-        return null;
+    private void setAppStatus(AppOrchestration app, String machineId, AppOps appOps) {
+        AppIdArgs appIdArgs = new AppIdArgs(app.getPackerConfig().getType(), app.getAppId());
+        AsyncMsg asyncMsg = new AsyncMsg();
+        asyncMsg.setMachineId(machineId);
+        asyncMsg.setSendTime(System.currentTimeMillis());
+        asyncMsg.setType(MessageType.appType.name());
+        asyncMsg.setOps(appOps.name());
+        asyncMsg.setPayload(JsonConverter.objectToJson(appIdArgs));
+
+        String topic = "dagent@" + machineId;
+        try {
+            mqttPub.pub(topic, JsonConverter.objectToJson(asyncMsg));
+        } catch (MqttException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void refreshAppStatus() {
+        List<AppRunning> appRunnings = runningRepository.findAll();
+        appRunnings.forEach(appRunning -> {
+            String appId = appRunning.getAppId();
+            AppOrchestration app = cache.findByAppId(appId);
+            String machineId = appRunning.getMachineId();
+            getStatus(app, machineId);
+        });
+    }
+
+    public void getStatus(AppOrchestration app, String machineId) {
+        AppIdArgs appIdArgs = new AppIdArgs(app.getPackerConfig().getType(), app.getAppId());
+        AsyncMsg asyncMsg = new AsyncMsg();
+        asyncMsg.setMachineId(machineId);
+        asyncMsg.setSendTime(System.currentTimeMillis());
+        asyncMsg.setType(MessageType.appType.name());
+        asyncMsg.setOps(AppOps.appStatus.name());
+        asyncMsg.setPayload(JsonConverter.objectToJson(appIdArgs));
+
+        String topic = "dagent@" + machineId;
+        try {
+            mqttPub.pub(topic, JsonConverter.objectToJson(asyncMsg));
+        } catch (MqttException e) {
+            e.printStackTrace();
+        }
     }
 
     /**
@@ -73,43 +124,4 @@ public class AppStatusService {
     private List<String> getAppLog(String appId, String logType, String logLevel, String machineId, String logFile) {
         return new ArrayList<>();
     }
-
-    public Map<String, AppStatus> appStatus(String appId) {
-        AppOrchestration app = cache.findByAppId(appId);
-        return getAppStatusMap(app, AppOps.appStatus);
-    }
-
-    public Map<String, AppStatus> restart(String appId) {
-        AppOrchestration app = cache.findByAppId(appId);
-        return getAppStatusMap(app, AppOps.appRestart);
-    }
-
-    public Map<String, AppStatus> stop(String appId) {
-        AppOrchestration app = cache.findByAppId(appId);
-        return getAppStatusMap(app, AppOps.appStop);
-    }
-
-    public Map<String, AppStatus> start(String appId) {
-        AppOrchestration app = cache.findByAppId(appId);
-        return getAppStatusMap(app, AppOps.appStart);
-    }
-
-    private Map<String, AppStatus> getAppStatusMap(AppOrchestration app, AppOps appOps) {
-        List<AsyncMsg> asyncMsgs = new ArrayList<>();
-        for (DeployConfig deployConfig : app.getDeployConfigs()) {
-            AppIdArgs appIdArgs = new AppIdArgs(app.getPackerConfig().getType(), app.getAppId());
-
-            AsyncMsg asyncMsg = new AsyncMsg();
-            asyncMsg.setMachineId(deployConfig.getMachineId());
-            asyncMsg.setSendTime(System.currentTimeMillis());
-            asyncMsg.setType(MessageType.appType.name());
-            asyncMsg.setOps(appOps.name());
-            asyncMsg.setPayload(JsonConverter.objectToJson(appIdArgs));
-            asyncMsgs.add(asyncMsg);
-        }
-
-        Map<String, AppStatus> map = new HashMap<>();
-        // TODO 持久化到数据库
-        return map;
-    }
 }

+ 11 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/entity/RoleType.java

@@ -0,0 +1,11 @@
+package cn.reghao.autodop.dmaster.auth.entity;
+
+/**
+ * 角色类型
+ *
+ * @author reghao
+ * @date 2021-04-05 02:22:44
+ */
+public enum RoleType {
+    ROLE_ADMIN,ROLE_BACKEND,ROLE_FRONTEND,ROLE_TEST,ROLE_USER
+}

+ 0 - 9
dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/OpsProcessor.java

@@ -1,9 +0,0 @@
-package cn.reghao.autodop.dmaster.mqttsub.processor;
-
-/**
- * @author reghao
- * @date 2021-06-09 13:43:16
- */
-public interface OpsProcessor {
-    void process(String ops, String payload);
-}

+ 27 - 44
dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/app/AppDeployResultProcessor.java

@@ -1,8 +1,6 @@
 package cn.reghao.autodop.dmaster.mqttsub.processor.app;
 
-import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
 import cn.reghao.autodop.common.dagent.app.api.data.DeployResult;
-import cn.reghao.autodop.common.result.ResultStatus;
 import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
 import cn.reghao.autodop.dmaster.app.entity.AppDeploying;
@@ -15,12 +13,10 @@ import cn.reghao.autodop.dmaster.app.repository.AppDeployingRepository;
 import cn.reghao.autodop.dmaster.app.repository.AppRunningRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.BuildLogRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.DeployLogRepository;
-import cn.reghao.autodop.dmaster.app.service.bd.BuildNotifyMsg;
 import cn.reghao.autodop.dmaster.app.service.bd.DeployNotifyMsg;
 import cn.reghao.autodop.dmaster.utils.notifier.DingMsg;
 import cn.reghao.autodop.dmaster.utils.notifier.NotifyService;
 
-import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Optional;
 
@@ -32,23 +28,23 @@ public class AppDeployResultProcessor implements Runnable {
     private String payload;
     private BuildLogRepository buildLogRepository;
     private DeployLogRepository deployLogRepository;
-    private AppDeployingRepository appDeployingRepository;
-    private AppRunningRepository appRunningRepository;
+    private AppDeployingRepository deployingRepository;
+    private AppRunningRepository runningRepository;
     private BuildDeployCache cache;
     private NotifyService notifyService;
 
     public AppDeployResultProcessor(String payload,
                                     BuildLogRepository buildLogRepository,
                                     DeployLogRepository deployLogRepository,
-                                    AppDeployingRepository appDeployingRepository,
-                                    AppRunningRepository appRunningRepository,
+                                    AppDeployingRepository deployingRepository,
+                                    AppRunningRepository runningRepository,
                                     BuildDeployCache cache,
                                     NotifyService notifyService) {
         this.payload = payload;
         this.buildLogRepository = buildLogRepository;
         this.deployLogRepository = deployLogRepository;
-        this.appDeployingRepository = appDeployingRepository;
-        this.appRunningRepository = appRunningRepository;
+        this.deployingRepository = deployingRepository;
+        this.runningRepository = runningRepository;
         this.cache = cache;
         this.notifyService = notifyService;
     }
@@ -64,49 +60,36 @@ public class AppDeployResultProcessor implements Runnable {
         Optional<BuildLog> optional = buildLogRepository.findById(buildId);
         if (optional.isPresent()) {
             BuildLog buildLog = optional.get();
+            updateDeployingStatus(buildLog, deployResult);
+            updateRunningStatus(buildLog, deployResult);
             deployNotify(buildLog, deployResult);
-            updateDeployStatus(buildLog, deployResult);
-            updateAppStatus(buildLog, deployResult);
-
-            List<NotifyReceiver> notifyReceivers = cache.findByAppId(buildLog.getAppId()).getNotifyReceivers();
-            DingMsg dingMsg = new BuildNotifyMsg(buildLog).dingMsg();
-            notifyReceivers.forEach(notifyReceiver -> notifyService.notify(notifyReceiver, dingMsg));
         }
     }
 
-    private void deployNotify(BuildLog buildLog, DeployResult deployResult) {
-        AppOrchestration app = cache.findByAppId(buildLog.getAppId());
-        DingMsg dingMsg = new DeployNotifyMsg(buildLog, deployResult).dingMsg();
-        List<NotifyReceiver> notifyReceivers = app.getNotifyReceivers();
-        notifyReceivers.forEach(notifyReceiver -> notifyService.notify(notifyReceiver, dingMsg));
+    private void updateDeployingStatus(BuildLog buildLog, DeployResult deployResult) {
+        String appId = buildLog.getAppId();
+        String machineId = deployResult.getMachineId();
+        AppDeploying deploying = deployingRepository.findByAppIdAndMachineId(appId, machineId);
+        if (deploying != null) {
+            deploying.update(buildLog, deployResult);
+            deployingRepository.save(deploying);
+        }
     }
 
-    private void updateDeployStatus(BuildLog buildLog, DeployResult deployResult) {
-        String buildLogId = buildLog.getId();
+    private void updateRunningStatus(BuildLog buildLog, DeployResult deployResult) {
+        String appId = buildLog.getAppId();
         String machineId = deployResult.getMachineId();
-        AppDeploying appDeploying = appDeployingRepository.findByBuildLogIdAndMachineId(buildLogId, machineId);
-        if (appDeploying != null) {
-            if (deployResult.getResult().getCode() == ResultStatus.SUCCESS.getCode()) {
-                appDeploying.setIsDeploy(true);
-                appDeploying.setDeployTime(deployResult.getAppStatus().getStartTime());
-            }
-            appDeploying.setDeployResult(deployResult.getResult().getMsg());
-            appDeployingRepository.save(appDeploying);
+        AppRunning running = runningRepository.findByAppIdAndMachineId(appId, machineId);
+        if (running != null) {
+            running.update(buildLog, deployResult.getAppStatus());
+            runningRepository.save(running);
         }
     }
 
-    private void updateAppStatus(BuildLog buildLog, DeployResult deployResult) {
-        AppStatus appStatus = deployResult.getAppStatus();
-        AppRunning appRunning = AppRunning.from(buildLog, appStatus);
-        appRunning.setLastCheck(LocalDateTime.now());
-
-        String appId = appRunning.getAppId();
-        AppRunning entity = appRunningRepository.findByAppId(appId);
-        if (entity != null) {
-            appRunning.setId(entity.getId());
-            appRunning.setIsDelete(entity.getIsDelete());
-            appRunning.setCreateTime(entity.getCreateTime());
-        }
-        appRunningRepository.save(appRunning);
+    private void deployNotify(BuildLog buildLog, DeployResult deployResult) {
+        AppOrchestration app = cache.findByAppId(buildLog.getAppId());
+        DingMsg dingMsg = new DeployNotifyMsg(buildLog, deployResult).dingMsg();
+        List<NotifyReceiver> notifyReceivers = app.getNotifyReceivers();
+        notifyReceivers.forEach(notifyReceiver -> notifyService.notify(notifyReceiver, dingMsg));
     }
 }

+ 30 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/app/AppOpsProcessor.java

@@ -1,17 +1,23 @@
 package cn.reghao.autodop.dmaster.mqttsub.processor.app;
 
+import cn.reghao.autodop.common.dagent.app.api.data.AppStatus;
+import cn.reghao.autodop.common.message.CallResult;
 import cn.reghao.autodop.common.message.ops.AppOps;
+import cn.reghao.autodop.common.utils.serializer.JsonConverter;
 import cn.reghao.autodop.dmaster.app.cache.BuildDeployCache;
+import cn.reghao.autodop.dmaster.app.entity.AppRunning;
 import cn.reghao.autodop.dmaster.app.repository.AppDeployingRepository;
 import cn.reghao.autodop.dmaster.app.repository.AppRunningRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.BuildLogRepository;
 import cn.reghao.autodop.dmaster.app.repository.log.DeployLogRepository;
 import cn.reghao.autodop.dmaster.common.thread.ThreadPoolWrapper;
-import cn.reghao.autodop.dmaster.mqttsub.processor.OpsProcessor;
+import cn.reghao.autodop.common.message.ops.OpsProcessor;
 import cn.reghao.autodop.dmaster.utils.notifier.NotifyService;
+import com.google.gson.reflect.TypeToken;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
+import java.lang.reflect.Type;
 import java.util.concurrent.ExecutorService;
 
 /**
@@ -50,17 +56,20 @@ public class AppOpsProcessor implements OpsProcessor {
     public void process(String ops, String payload) {
         switch (AppOps.valueOf(ops)) {
             case appDeployResult:
-                log.info("处理部署结果...");
                 threadPool.submit(new AppDeployResultProcessor(payload, buildLogRepository, deployLogRepository,
                         appDeployingRepository, appRunningRepository, cache, notifyService));
                 break;
             case appStatusResult:
+                processAppStatus(payload);
                 break;
             case appRestartResult:
+                processAppStatus(payload);
                 break;
             case appStopResult:
+                processAppStatus(payload);
                 break;
             case appStartResult:
+                processAppStatus(payload);
                 break;
             case appLogResult:
                 break;
@@ -69,4 +78,23 @@ public class AppOpsProcessor implements OpsProcessor {
                 break;
         }
     }
+
+    private void processAppStatus(String payload) {
+        Type type = new TypeToken<CallResult<AppStatus>>(){}.getType();
+        CallResult<AppStatus> callResult = JsonConverter.jsonToObject(payload, type);
+        if (callResult.getCode() != 0) {
+            // TODO 处理调用失败的情况
+            log.error("调用失败...");
+            return;
+        }
+
+        AppStatus appStatus = callResult.getData();
+        String appId = appStatus.getAppId();
+        String machineId = appStatus.getMachineId();
+        AppRunning appRunning = appRunningRepository.findByAppIdAndMachineId(appId, machineId);
+        if (appRunning != null) {
+            appRunning.update(appStatus);
+            appRunningRepository.save(appRunning);
+        }
+    }
 }

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/dagent/DagentOpsProcessor.java

@@ -2,7 +2,7 @@ package cn.reghao.autodop.dmaster.mqttsub.processor.dagent;
 
 import cn.reghao.autodop.common.message.ops.DagentOps;
 import cn.reghao.autodop.dmaster.common.thread.ThreadPoolWrapper;
-import cn.reghao.autodop.dmaster.mqttsub.processor.OpsProcessor;
+import cn.reghao.autodop.common.message.ops.OpsProcessor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/mqttsub/processor/machine/MachineOpsProcessor.java

@@ -4,7 +4,7 @@ import cn.reghao.autodop.common.message.ops.MachineOps;
 import cn.reghao.autodop.dmaster.common.thread.ThreadPoolWrapper;
 import cn.reghao.autodop.dmaster.machine.repository.MachineStatusRepository;
 import cn.reghao.autodop.dmaster.machine.service.MachineCrudService;
-import cn.reghao.autodop.dmaster.mqttsub.processor.OpsProcessor;
+import cn.reghao.autodop.common.message.ops.OpsProcessor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 

+ 11 - 5
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/HomePageController.java

@@ -2,8 +2,9 @@ package cn.reghao.autodop.dmaster.view.controller;
 
 import cn.reghao.autodop.dmaster.auth.UserContext;
 import cn.reghao.autodop.dmaster.auth.entity.Menu;
+import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.User;
-import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
+import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.repository.MenuRepository;
 import io.swagger.annotations.Api;
 import org.springframework.stereotype.Controller;
@@ -20,19 +21,24 @@ import java.util.stream.Collectors;
 @Api("首页页面")
 @Controller
 public class HomePageController {
-    private final UserRepository userRepository;
     private final MenuRepository menuRepository;
+    private final RoleRepository roleRepository;
 
-    public HomePageController(UserRepository userRepository, MenuRepository menuRepository) {
-        this.userRepository = userRepository;
+    public HomePageController(MenuRepository menuRepository, RoleRepository roleRepository) {
         this.menuRepository = menuRepository;
+        this.roleRepository = roleRepository;
     }
 
     @GetMapping("/")
     public String index(Model model) {
         User user = UserContext.currentUser();
+        List<Menu> menus = new ArrayList<>();
+        user.getAuthorities().forEach(auth -> {
+            Role role = roleRepository.findByTitle(auth.getAuthority());
+            menus.addAll(role.getMenus());
+        });
         // TODO 根据用户角色获取相应的 menu
-        List<Menu> menus = menuRepository.findAll();
+        //List<Menu> menus = menuRepository.findAll();
 
         Map<Integer, List<Menu>> map =  menus.stream()
                 .collect(Collectors.groupingBy(Menu::getPid));

+ 65 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/RoleController.java

@@ -0,0 +1,65 @@
+package cn.reghao.autodop.dmaster.view.controller;
+
+import cn.reghao.autodop.dmaster.auth.entity.Menu;
+import cn.reghao.autodop.dmaster.auth.entity.Role;
+import cn.reghao.autodop.dmaster.auth.repository.MenuRepository;
+import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
+import cn.reghao.autodop.dmaster.auth.service.RoleService;
+import cn.reghao.autodop.dmaster.utils.WebBody;
+import io.swagger.annotations.Api;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2021-04-04 21:24:18
+ */
+@Api(tags = "角色接口")
+@RequestMapping("/system/role")
+@Controller
+public class RoleController {
+    private RoleService roleService;
+    private RoleRepository roleRepository;
+    private MenuRepository menuRepository;
+
+    public RoleController(RoleService roleService,
+                          RoleRepository roleRepository,
+                          MenuRepository menuRepository) {
+        this.roleService = roleService;
+        this.roleRepository = roleRepository;
+        this.menuRepository = menuRepository;
+    }
+
+    @GetMapping(value = "/authList", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public String authList(@RequestParam(value = "ids") Role role) {
+        List<Menu> list = menuRepository.findAll();
+        list.forEach(menu -> {
+            if (menu.getRoles().contains(role)) {
+                menu.setRemark("auth:true");
+            }
+        });
+
+        return WebBody.success(list);
+    }
+
+    @PostMapping(value = "/auth", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public String auth(@RequestParam(value = "id", required = true) Role role,
+                       @RequestParam(value = "authId", required = false) HashSet<Menu> menus) {
+        role.setMenus(menus);
+        roleRepository.save(role);
+        return WebBody.success();
+    }
+
+    @PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
+    @ResponseBody
+    public String addRole(Role role) {
+        roleService.addRole(role);
+        return WebBody.success();
+    }
+}

+ 3 - 40
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/RolePageController.java

@@ -1,25 +1,20 @@
 package cn.reghao.autodop.dmaster.view.controller;
 
 import cn.reghao.autodop.dmaster.auth.entity.GrantedAuthorityImpl;
-import cn.reghao.autodop.dmaster.auth.entity.Menu;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.User;
-import cn.reghao.autodop.dmaster.auth.repository.MenuRepository;
 import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
 import cn.reghao.autodop.dmaster.auth.service.RoleService;
 import cn.reghao.autodop.dmaster.utils.db.PageList;
-import cn.reghao.autodop.dmaster.utils.WebBody;
 import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import io.swagger.annotations.Api;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
-import org.springframework.http.MediaType;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.HashSet;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -34,16 +29,13 @@ public class RolePageController {
     private RoleService roleService;
     private UserRepository userRepository;
     private RoleRepository roleRepository;
-    private MenuRepository menuRepository;
 
     public RolePageController(RoleService roleService,
                               UserRepository userRepository,
-                              RoleRepository roleRepository,
-                              MenuRepository menuRepository) {
+                              RoleRepository roleRepository) {
         this.roleService = roleService;
         this.userRepository = userRepository;
         this.roleRepository = roleRepository;
-        this.menuRepository = menuRepository;
     }
 
     @GetMapping
@@ -82,42 +74,13 @@ public class RolePageController {
         return "/system/role/auth";
     }
 
-    @GetMapping("/userList/{id}")
+    @GetMapping("/resource/{id}")
     public String userListWithRole(@PathVariable("id") Role role, Model model) {
         List<User> list = userRepository.findAll().stream()
                 .filter(user -> user.getAuthorities().contains(new GrantedAuthorityImpl(role.getTitle())))
                 .collect(Collectors.toList());
 
         model.addAttribute("list", list);
-        return "/system/role/userList";
-    }
-
-    @GetMapping(value = "/authList", produces = MediaType.APPLICATION_JSON_VALUE)
-    @ResponseBody
-    public String authList(@RequestParam(value = "ids") Role role) {
-        List<Menu> list = menuRepository.findAll();
-        list.forEach(menu -> {
-            if (menu.getRoles().contains(role)) {
-                menu.setRemark("auth:true");
-            }
-        });
-
-        return WebBody.success(list);
-    }
-
-    @PostMapping(value = "/auth", produces = MediaType.APPLICATION_JSON_VALUE)
-    @ResponseBody
-    public String auth(@RequestParam(value = "id", required = true) Role role,
-                       @RequestParam(value = "authId", required = false) HashSet<Menu> menus) {
-        role.setMenus(menus);
-        roleRepository.save(role);
-        return WebBody.success();
-    }
-
-    @PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
-    @ResponseBody
-    public String addRole(Role role) {
-        roleService.addRole(role);
-        return WebBody.success();
+        return "/system/role/resource";
     }
 }

+ 58 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserController.java

@@ -0,0 +1,58 @@
+package cn.reghao.autodop.dmaster.view.controller;
+
+import cn.reghao.autodop.dmaster.auth.entity.Role;
+import cn.reghao.autodop.dmaster.auth.entity.User;
+import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
+import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
+import cn.reghao.autodop.dmaster.auth.service.UserService;
+import cn.reghao.autodop.dmaster.utils.WebBody;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2021-04-04 21:24:18
+ */
+@Api(tags = "用户接口")
+@RequestMapping("/system/user")
+@RestController
+public class UserController {
+    private final UserService userService;
+    private UserRepository userRepository;
+    private RoleRepository roleRepository;
+
+    public UserController(UserService userService, RoleRepository roleRepository, UserRepository userRepository) {
+        this.userService = userService;
+        this.roleRepository = roleRepository;
+        this.userRepository = userRepository;
+    }
+
+    @ApiOperation(value = "新增/修改用户")
+    @PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String addOrUpdateUser(User user) {
+        userService.addOrUpdate(user);
+        return WebBody.success();
+    }
+
+    @ApiOperation(value = "修改用户密码")
+    @PostMapping(value = "/pwd", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String modifyPassword(String password,
+                                 String confirm,
+                                 @RequestParam(value = "ids", required = false) List<Long> ids,
+                                 @RequestParam(value = "ids", required = false) List<User> users) {
+        return WebBody.success("");
+    }
+
+    @ApiOperation(value = "给用户分配角色")
+    @PostMapping(value = "/role", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String assignRole(@RequestParam(value = "id") User user,
+                             @RequestParam(value = "roleId", required = false) HashSet<Role> roles) {
+        userService.modifyUserRoles(user, roles);
+        return WebBody.success();
+    }
+}

+ 10 - 24
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserPageController.java

@@ -1,21 +1,22 @@
 package cn.reghao.autodop.dmaster.view.controller;
 
+import cn.reghao.autodop.dmaster.auth.entity.Menu;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.User;
 import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
 import cn.reghao.autodop.dmaster.auth.service.UserService;
 import cn.reghao.autodop.dmaster.utils.db.PageList;
-import cn.reghao.autodop.dmaster.utils.WebBody;
 import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.HashSet;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -72,6 +73,7 @@ public class UserPageController {
         return "/system/user/pwd";
     }
 
+    @ApiOperation(value = "用户角色分配页面")
     @GetMapping("/role")
     public String assignRolePage(@RequestParam(value = "ids") int userId, Model model) {
         List<Role> roles = roleRepository.findAll();
@@ -83,27 +85,11 @@ public class UserPageController {
         return "/system/user/role";
     }
 
-    @PostMapping("/save")
-    @ResponseBody
-    public String addOrUpdateUser(User user) {
-        userService.addOrUpdate(user);
-        return WebBody.success();
-    }
-
-    @PostMapping("/pwd")
-    @ResponseBody
-    public String modifyPassword(String password,
-                                 String confirm,
-                                 @RequestParam(value = "ids", required = false) List<Long> ids,
-                                 @RequestParam(value = "ids", required = false) List<User> users) {
-        return WebBody.success("");
-    }
-
-    @PostMapping("/role")
-    @ResponseBody
-    public String assignRole(@RequestParam(value = "id") User user,
-                             @RequestParam(value = "roleId", required = false) HashSet<Role> roles) {
-        userService.modifyUserRoles(user, roles);
-        return WebBody.success();
+    @ApiOperation(value = "获取角色列表页面")
+    @GetMapping("/roleList/{userId}")
+    public String roleListWithResource(@PathVariable("userId") User user, Model model) {
+        List<Role> list = userService.getUserRoles(user.getId());
+        model.addAttribute("list", list);
+        return "/system/user/roleList";
     }
 }

+ 3 - 3
dmaster/src/main/resources/templates/app/build.html

@@ -50,7 +50,7 @@
                     <th class="sortable" data-field="appType">类型</th>
                     <th class="sortable" data-field="branch">分支</th>
                     <th class="sortable" data-field="httpPort">HTTP 端口</th>
-                    <th class="sortable" data-field="commitId">版本</th>
+                    <th class="sortable" data-field="commitId">当前构建版本</th>
                     <th class="sortable" data-field="commitTime">提交时间</th>
                     <th class="sortable" data-field="result">构建结果</th>
                     <th class="sortable" data-field="buildTime">构建时间</th>
@@ -70,7 +70,7 @@
                     <td th:text="${item.appType}">类型</td>
                     <td th:text="${item.branch}">分支</td>
                     <td th:text="${item.httpPort}">HTTP 端口</td>
-                    <td th:text="${item.commitId}">版本</td>
+                    <td th:text="${item.commitId}">当前构建版本</td>
                     <td th:text="${item.commitTime}">提交时间</td>
                     <td>
                         <a class="open-popup" data-title="构建结果" data-size="640,480" href="#"
@@ -82,7 +82,7 @@
                     <td>
                         <a class="ajax-post" th:href="@{'/api/app/bd/update?appId='+${item.appId}}">更新</a>
                         <a class="ajax-post" th:href="@{'/api/app/bd/build?appId='+${item.appId}}">构建</a>
-                        <a class="open-popup" data-title="应用部署" th:attr="data-url=@{'/app/deploy/' + ${item.buildLogId}}"
+                        <a class="open-popup" data-title="应用部署" th:attr="data-url=@{'/app/deploy/' + ${item.appId}}"
                            data-size="1000,600" href="#">部署</a>
                     </td>
                 </tr>

+ 2 - 2
dmaster/src/main/resources/templates/app/config/app/index.html

@@ -10,7 +10,7 @@
     <div class="layui-card-header timo-card-header">
         <span><i class="fa fa-bars"></i> 应用配置</span>
         <i class="layui-icon layui-icon-refresh refresh-btn"></i>
-        <a th:href="@{/api/app/config/export}"><i class="fa fa-download"></i></a>
+        <a th:href="@{/api/bak/config/app/export}"><i class="fa fa-download"></i></a>
     </div>
     <div class="layui-card-body">
         <div class="layui-row timo-card-screen put-row">
@@ -40,7 +40,7 @@
             <div class="pull-right screen-btn-group">
                 <div class="btn-group-right">
                     <button type="button" class="layui-btn upload-image" name="file[]"
-                            th:attr="up-url=@{/api/app/config/import}" up-field="path">
+                            th:attr="up-url=@{/api/bak/config/app/import}" up-field="path">
                         <i class="fa fa-upload"></i> 导入
                     </button>
                     <button class="layui-btn open-popup" data-title="添加应用" th:attr="data-url=@{/app/config/app/add}"

+ 3 - 4
dmaster/src/main/resources/templates/app/deploy.html

@@ -9,7 +9,7 @@
                 <thead>
                 <tr>
                     <th class="sortable" data-field="machineIpv4">机器地址</th>
-                    <th class="sortable" data-field="isDeploy">是否已部署</th>
+                    <th class="sortable" data-field="commitId">当前部署版本</th>
                     <th class="sortable" data-field="deployTime">部署时间</th>
                     <th class="sortable" data-field="deployResult">部署结果</th>
                     <th class="sortable" data-field="deployBy">部署用户</th>
@@ -19,13 +19,12 @@
                 <tbody>
                 <tr th:each="item:${list}">
                     <td th:text="${item.machineIpv4}">机器地址</td>
-                    <td th:text="${item.isDeploy}">是否已部署</td>
+                    <td th:text="${item.commitId}">当前部署版本</td>
                     <td th:text="${item.deployTime}">部署时间</td>
                     <td th:text="${item.deployResult}">部署结果</td>
                     <td th:text="${item.deployBy}">部署用户</td>
                     <td>
-                        <a class="open-popup" data-title="部署" th:attr="data-url=@{'/system/user/edit/'+${item.buildLogId}}"
-                           data-size="600,570" href="#">部署</a>
+                        <a class="ajax-post" th:href="@{'/api/app/bd/deploy/'+${item.appId}}">部署</a>
                     </td>
                 </tr>
                 </tbody>

+ 71 - 42
dmaster/src/main/resources/templates/app/status.html

@@ -10,48 +10,77 @@
         <span><i class="fa fa-bars"></i> 应用状态</span>
         <i class="layui-icon layui-icon-refresh refresh-btn"></i>
     </div>
-    <div class="timo-table-wrap">
-        <table class="layui-table timo-table">
-            <thead>
-            <tr>
-                <th class="timo-table-checkbox">
-                    <label class="timo-checkbox"><input type="checkbox">
-                        <i class="layui-icon layui-icon-ok"></i></label>
-                </th>
-                <th class="sortable" data-field="appId">应用</th>
-                <th class="sortable" data-field="branch">分支</th>
-                <th class="sortable" data-field="commitId">版本</th>
-                <th class="sortable" data-field="machineIpv4">节点地址</th>
-                <th class="sortable" data-field="startTime">启动时间</th>
-                <th class="sortable" data-field="pid">PID</th>
-                <th class="sortable" data-field="isRunning">运行状态</th>
-                <th class="sortable" data-field="lastCheck">上次检查时间</th>
-                <th>操作</th>
-            </tr>
-            </thead>
-            <tbody>
-            <tr th:each="item:${list}">
-                <td><label class="timo-checkbox"><input type="checkbox" th:value="${item.appId}">
-                    <i class="layui-icon layui-icon-ok"></i></label></td>
-                <td>
-                    <a class="open-popup" data-title="应用配置详情" data-size="1000,600" href="#"
-                       th:text="${item.appId}" th:attr="data-url=@{'/app/config/app/detail/'+${item.appId}}"></a>
-                </td>
-                <td th:text="${item.branch}">分支</td>
-                <td th:text="${item.commitId}">版本</td>
-                <td th:text="${item.machineIpv4}">节点地址</td>
-                <td th:text="${item.startTime}">启动时间</td>
-                <td th:text="${item.pid}">PID</td>
-                <td th:text="${item.isRunning}">运行状态</td>
-                <td th:text="${item.lastCheck}">上次检查时间</td>
-                <td>
-                    <a class="ajax-post" th:href="@{'/api/app/status/restart/'+${item.appId}}">重启</a>
-                    <a class="ajax-post" th:href="@{'/api/app/status/stop/'+${item.appId}}">停止</a>
-                    <a class="ajax-post" th:href="@{'/api/app/status/start/'+${item.appId}}">启动</a>
-                </td>
-            </tr>
-            </tbody>
-        </table>
+    <div class="layui-card-body">
+        <div class="layui-row timo-card-screen put-row">
+            <div class="pull-left layui-form-pane">
+                <div class="layui-inline">
+                    <label class="layui-form-label">环境</label>
+                    <div class="layui-input-block timo-search-status">
+                        <select id="getPageByEnv" class="timo-search-select" name="env" onchange="getPageByEnv()"
+                                mo:dict="ENVIRONMENT" mo-selected="${env}"></select>
+                    </div>
+                </div>
+                <div class="layui-inline timo-search-box">
+                    <label class="layui-form-label">应用名</label>
+                    <div class="layui-input-block">
+                        <input type="text" name="appName" th:value="${param.appName}" placeholder="请输入应用名"
+                               autocomplete="off" class="layui-input">
+                    </div>
+                </div>
+                <div class="layui-inline">
+                    <button class="layui-btn timo-search-btn">
+                        <i class="fa fa-search"></i>
+                    </button>
+                </div>
+            </div>
+            <div class="pull-right screen-btn-group">
+                <div class="btn-group-right">
+                    <a class="ajax-post" th:href="@{'/api/app/status/refresh'}">刷新状态列表</a>
+                </div>
+            </div>
+        </div>
+        <div class="timo-table-wrap">
+            <table class="layui-table timo-table">
+                <thead>
+                <tr>
+                    <th class="timo-table-checkbox">
+                        <label class="timo-checkbox"><input type="checkbox">
+                            <i class="layui-icon layui-icon-ok"></i></label>
+                    </th>
+                    <th class="sortable" data-field="appName">应用</th>
+                    <th class="sortable" data-field="machineIpv4">节点地址</th>
+                    <th class="sortable" data-field="packagePath">包路径</th>
+                    <th class="sortable" data-field="isRunning">运行状态</th>
+                    <th class="sortable" data-field="startTime">启动时间</th>
+                    <th class="sortable" data-field="pid">PID</th>
+                    <th class="sortable" data-field="lastCheck">上次检查时间</th>
+                    <th>操作</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr th:each="item:${list}">
+                    <td><label class="timo-checkbox"><input type="checkbox" th:value="${item.appId}">
+                        <i class="layui-icon layui-icon-ok"></i></label></td>
+                    <td>
+                        <a class="open-popup" data-title="应用配置详情" data-size="1000,600" href="#"
+                           th:text="${item.appName}" th:attr="data-url=@{'/app/config/app/detail/'+${item.appId}}"></a>
+                    </td>
+                    <td th:text="${item.machineIpv4}">节点地址</td>
+                    <td th:text="${item.packagePath}">包路径</td>
+                    <td th:text="${item.isRunning}">运行状态</td>
+                    <td th:text="${item.startTime}">启动时间</td>
+                    <td th:text="${item.pid}">PID</td>
+                    <td th:text="${item.lastCheck}">上次检查时间</td>
+                    <td>
+                        <a class="ajax-post" th:href="@{'/api/app/status/restart/'+${item.appId}+'/'+${item.machineId}}">重启</a>
+                        <a class="ajax-post" th:href="@{'/api/app/status/stop/'+${item.appId}+'/'+${item.machineId}}">停止</a>
+                        <a class="ajax-post" th:href="@{'/api/app/status/start/'+${item.appId}+'/'+${item.machineId}}">启动</a>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+        <div th:replace="/common/fragment :: page"></div>
     </div>
 </div>
 <script th:replace="/common/template :: script"></script>

+ 1 - 1
dmaster/src/main/resources/templates/main.html

@@ -55,7 +55,7 @@
                      th:src="@{${user.avatarUrl}}" alt="头像">
                 <div>
                     <p class="layui-side-user-name" th:text="${user.nickname}">DevOps</p>
-                    <p class="layui-side-user-designation">管理员</p>
+                    <p class="layui-side-user-designation">在线</p>
                 </div>
             </div>
             <!-- 导航区域 -->

+ 2 - 2
dmaster/src/main/resources/templates/system/role/index.html

@@ -61,8 +61,8 @@
                     <td th:text="${item.createTime}">创建时间</td>
                     <td th:text="${item.updateTime}">更新时间</td>
                     <td>
-                        <a class="open-popup" data-title="用户列表"
-                           th:attr="data-url=@{'/system/role/userList/'+${item.id}}" data-size="800,600"
+                        <a class="open-popup" data-title="可访问的资源"
+                           th:attr="data-url=@{'/system/role/resource/'+${item.id}}" data-size="800,600"
                            href="#">查看</a>
                     </td>
                     <td>

+ 0 - 0
dmaster/src/main/resources/templates/system/role/userList.html → dmaster/src/main/resources/templates/system/role/resource.html


+ 4 - 13
dmaster/src/main/resources/templates/system/user/index.html

@@ -9,18 +9,10 @@
     <div class="layui-card-header timo-card-header">
         <span><i class="fa fa-bars"></i> 用户管理</span>
         <i class="layui-icon layui-icon-refresh refresh-btn"></i>
-        <a th:href="@{/system/user/export}"><i class="fa fa-download"></i></a>
     </div>
     <div class="layui-card-body">
         <div class="layui-row timo-card-screen put-row">
             <div class="pull-left layui-form-pane timo-search-box">
-                <div class="layui-inline">
-                    <label class="layui-form-label">状态</label>
-                    <div class="layui-input-block timo-search-status">
-                        <select class="timo-search-select" name="status" mo:dict="SEARCH_STATUS"
-                                mo-selected="${param.status}"></select>
-                    </div>
-                </div>
                 <div class="layui-inline">
                     <label class="layui-form-label">用户名</label>
                     <div class="layui-input-block">
@@ -55,8 +47,7 @@
                         <button class="layui-btn">操作<span class="caret"></span></button>
                         <dl class="layui-nav-child layui-anim layui-anim-upbit">
                             <dd><a class="ajax-status" th:href="@{/system/user/status/ok}">启用</a></dd>
-                            <dd><a class="ajax-status" th:href="@{/system/user/status/freezed}">冻结</a></dd>
-                            <dd><a class="ajax-status" th:href="@{/system/user/status/delete}">删除</a></dd>
+                            <dd><a class="ajax-status" th:href="@{/system/user/status/freezed}">禁用</a></dd>
                         </dl>
                     </div>
                 </div>
@@ -94,14 +85,14 @@
                     <td th:text="正常">状态</td>
                     <td>
                         <a class="open-popup" data-title="角色列表"
-                           th:attr="data-url=@{'/system/menu/roleList/{{id}}'}" data-size="800,600"
+                           th:attr="data-url=@{'/system/user/roleList/'+${item.id}}" data-size="640,480"
                            href="#">查看</a>
                     </td>
                     <td>
                         <a class="open-popup" data-title="编辑用户" th:attr="data-url=@{'/system/user/edit/'+${item.id}}"
-                           data-size="600,570" href="#">编辑</a>
+                           data-size="640,480" href="#">编辑</a>
                         <a class="open-popup" data-title="详细信息" th:attr="data-url=@{'/system/user/detail/'+${item.id}}"
-                           data-size="800,600" href="#">详细</a>
+                           data-size="640,480" href="#">详细</a>
                         <a class="ajax-get" th:attr="data-msg='您是否删除'+${item.nickname}"
                            th:href="@{/system/user/status/delete(ids=${item.id})}">删除</a>
                     </td>

+ 36 - 0
dmaster/src/main/resources/templates/system/user/roleList.html

@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})">
+    <style>
+        a{
+            color: #009688;
+        }
+        a:hover{
+            color: #004a43;
+            text-decoration: underline;
+        }
+    </style>
+</head>
+<body>
+    <div class="timo-detail-page">
+        <table class="layui-table">
+            <thead>
+            <tr>
+                <th>角色</th>
+                <th>角色名</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr th:each="item:${list}">
+                <td>[[${item.title}]]</td>
+                <td>[[${item.name}]]</td>
+            </tr>
+            <tr th:if="${list.isEmpty()}">
+                <td style="text-align: center" colspan="3">本资源没有分配给任何角色</td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 0 - 78
dmaster/src/test/java/cn/reghao/autodop/dmaster/app/entity/AppDeployingTest.java

@@ -1,78 +0,0 @@
-package cn.reghao.autodop.dmaster.app.entity;
-
-import cn.reghao.autodop.dmaster.DmasterApplication;
-import cn.reghao.autodop.dmaster.app.entity.config.AppOrchestration;
-import cn.reghao.autodop.dmaster.app.entity.config.deploy.DeployConfig;
-import cn.reghao.autodop.dmaster.app.repository.AppBuildingRepository;
-import cn.reghao.autodop.dmaster.app.repository.AppDeployingRepository;
-import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
-import cn.reghao.autodop.dmaster.machine.entity.MachineInfo;
-import cn.reghao.autodop.dmaster.machine.entity.NetworkInfo;
-import cn.reghao.autodop.dmaster.machine.repository.MachineInfoRepository;
-import lombok.extern.slf4j.Slf4j;
-import org.junit.jupiter.api.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@Slf4j
-@ActiveProfiles("dev")
-@SpringBootTest(classes = DmasterApplication.class)
-@RunWith(SpringRunner.class)
-class AppDeployingTest {
-    @Autowired
-    private AppOrchestrationRepository appOrchestrationRepository;
-    @Autowired
-    private MachineInfoRepository machineInfoRepository;
-    @Autowired
-    private AppBuildingRepository buildingRepository;
-    @Autowired
-    private AppDeployingRepository deployingRepository;
-
-    @Test
-    public void appBuilding() {
-        List<AppOrchestration> apps = appOrchestrationRepository.findAll();
-        List<AppBuilding> list = new ArrayList<>();
-        for (AppOrchestration app : apps) {
-            if (!app.getEnable()) {
-                continue;
-            }
-
-            AppBuilding entity = buildingRepository.findByAppId(app.getAppId());
-            if (entity != null) {
-                continue;
-            }
-
-            list.add(new AppBuilding(app));
-        }
-        buildingRepository.saveAll(list);
-    }
-
-    @Test
-    public void appDeploying() {
-        List<AppOrchestration> apps = appOrchestrationRepository.findAll();
-        List<AppDeploying> appDeployings = new ArrayList<>();
-        for (AppOrchestration app : apps) {
-            if (!app.getEnable() || app.getDeployConfigs().isEmpty()) {
-                continue;
-            }
-
-            for (DeployConfig deployConfig : app.getDeployConfigs()) {
-                String machineId = deployConfig.getMachineId();
-                MachineInfo machineInfo = machineInfoRepository.findByMachineId(machineId);
-                if (machineInfo != null && !machineInfo.getNetworkInfo().isEmpty()) {
-                    NetworkInfo networkInfo = machineInfo.getNetworkInfo().get(0);
-                    appDeployings.add(AppDeploying.from(app.getAppId(), machineId, networkInfo.getIpv4()));
-                }
-            }
-        }
-
-        log.info("");
-        //appDeployingRepository.saveAll(appDeployings);
-    }
-}

+ 33 - 0
dmaster/src/test/java/cn/reghao/autodop/dmaster/app/service/AppBuildServiceTest.java

@@ -0,0 +1,33 @@
+package cn.reghao.autodop.dmaster.app.service;
+
+import cn.reghao.autodop.dmaster.DmasterApplication;
+import cn.reghao.autodop.dmaster.app.repository.AppBuildingRepository;
+import cn.reghao.autodop.dmaster.app.repository.AppDeployingRepository;
+import cn.reghao.autodop.dmaster.app.repository.AppRunningRepository;
+import cn.reghao.autodop.dmaster.app.repository.config.AppOrchestrationRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@Slf4j
+@ActiveProfiles("dev")
+@SpringBootTest(classes = DmasterApplication.class)
+@RunWith(SpringRunner.class)
+class AppBuildServiceTest {
+    @Autowired
+    private AppOrchestrationRepository appRepository;
+    @Autowired
+    private AppBuildingRepository buildingRepository;
+    @Autowired
+    private AppDeployingRepository deployingRepository;
+    @Autowired
+    private AppRunningRepository runningRepository;
+
+    @Test
+    void test() {
+    }
+}