Browse Source

调整机器接口

reghao 4 years ago
parent
commit
08997c3724
22 changed files with 378 additions and 224 deletions
  1. 2 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/app/controller/BuildDeployController.java
  2. 84 2
      dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/db/UserCrud.java
  3. 2 109
      dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/service/UserService.java
  4. 13 8
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/MachineController.java
  5. 111 48
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/MachinePageController.java
  6. 1 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/entity/po/MachineHost.java
  7. 11 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/entity/po/SshAuth.java
  8. 27 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/service/MachineService.java
  9. 1 0
      dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/service/ssh/ws/WebsocketInterceptor.java
  10. 1 1
      dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/WebBody.java
  11. 6 12
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserController.java
  12. 8 10
      dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserPageController.java
  13. 0 1
      dmaster/src/main/resources/templates/app/config/app/notify.html
  14. 31 0
      dmaster/src/main/resources/templates/machine/cpuusage.html
  15. 5 10
      dmaster/src/main/resources/templates/machine/edit.html
  16. 1 1
      dmaster/src/main/resources/templates/machine/host.html
  17. 1 1
      dmaster/src/main/resources/templates/machine/machinenotify.html
  18. 31 0
      dmaster/src/main/resources/templates/machine/networkstatus.html
  19. 3 4
      dmaster/src/main/resources/templates/machine/sshauth.html
  20. 5 5
      dmaster/src/main/resources/templates/machine/status.html
  21. 31 0
      dmaster/src/main/resources/templates/machine/sysload.html
  22. 3 9
      dmaster/src/main/resources/templates/machine/webssh.html

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

@@ -33,7 +33,7 @@ public class BuildDeployController {
     @PostMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
     @PostMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
     public String buildAndDeploy(@RequestParam("appId") String appId) throws Exception {
     public String buildAndDeploy(@RequestParam("appId") String appId) throws Exception {
         String ret = buildDeployDispatcher.buildAndDeploy(appId, true);
         String ret = buildDeployDispatcher.buildAndDeploy(appId, true);
-        return WebBody.successMsg(ret);
+        return WebBody.successWithMsg(ret);
     }
     }
 
 
     @ApiOperation(value = "构建应用")
     @ApiOperation(value = "构建应用")
@@ -41,7 +41,7 @@ public class BuildDeployController {
     @PostMapping(value = "/build", produces = MediaType.APPLICATION_JSON_VALUE)
     @PostMapping(value = "/build", produces = MediaType.APPLICATION_JSON_VALUE)
     public String build(@RequestParam("appId") String appId) throws Exception {
     public String build(@RequestParam("appId") String appId) throws Exception {
         String ret = buildDeployDispatcher.buildAndDeploy(appId, false);
         String ret = buildDeployDispatcher.buildAndDeploy(appId, false);
-        return WebBody.successMsg(ret);
+        return WebBody.successWithMsg(ret);
     }
     }
 
 
     @ApiOperation(value = "部署应用")
     @ApiOperation(value = "部署应用")

+ 84 - 2
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/db/UserCrud.java

@@ -1,15 +1,24 @@
 package cn.reghao.autodop.dmaster.auth.db;
 package cn.reghao.autodop.dmaster.auth.db;
 
 
+import cn.reghao.autodop.common.utils.security.Cryptor;
+import cn.reghao.autodop.common.utils.security.Md5Cryptor;
+import cn.reghao.autodop.common.utils.security.Salt;
+import cn.reghao.autodop.dmaster.auth.entity.GrantedAuthorityImpl;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.User;
 import cn.reghao.autodop.dmaster.auth.entity.User;
 import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
 import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.data.jpa.domain.Specification;
+import org.springframework.security.core.GrantedAuthority;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
 import javax.persistence.criteria.Join;
 import javax.persistence.criteria.Join;
 import javax.persistence.criteria.JoinType;
 import javax.persistence.criteria.JoinType;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Predicate;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * @author reghao
  * @author reghao
@@ -17,10 +26,83 @@ import java.util.List;
  */
  */
 @Service
 @Service
 public class UserCrud {
 public class UserCrud {
-    private UserRepository userRepository;
+    private final UserRepository userRepository;
+    private final RoleCrud roleCrud;
+    private final Cryptor cryptor;
 
 
-    public UserCrud(UserRepository userRepository) {
+    public UserCrud(UserRepository userRepository, RoleCrud roleCrud) throws NoSuchAlgorithmException {
         this.userRepository = userRepository;
         this.userRepository = userRepository;
+        this.roleCrud = roleCrud;
+        this.cryptor = new Md5Cryptor();
+    }
+
+    public User findById(int id) {
+        return userRepository.findById(id);
+    }
+
+    public void addOrUpdate(User user) {
+        Integer id = user.getId();
+        if (id == null) {
+            addUser(user);
+        } else {
+            updateUser(user);
+        }
+    }
+
+    private void addUser(User user) {
+        String password = user.getPassword();
+        String salt = Salt.get(64);
+        String encryptPwd = cryptor.encrypt(password + salt);
+        user.setPassword(encryptPwd);
+        user.setSalt(salt);
+        user.setAvatarUrl("/imgs/avatar/default.png");
+        userRepository.save(user);
+    }
+
+    private void updateUser(User user) {
+        userRepository.save(user);
+    }
+
+    public void modifyUserRoles(User user, Set<Role> roles) {
+        // 用户当前拥有的角色
+        List<String> roleList = user.getAuthorities().stream()
+                .map(GrantedAuthority::getAuthority).collect(Collectors.toList());
+        if (roleList.isEmpty()) {
+            Set<GrantedAuthorityImpl> authorities = roles.stream()
+                    .map(role -> new GrantedAuthorityImpl(role.getTitle()))
+                    .collect(Collectors.toSet());
+            user.setAuthorities(authorities);
+            userRepository.save(user);
+            return;
+        }
+
+        List<Role> currentRoles = getUserRoles(user.getId());
+        List<Role> tmp = new ArrayList<>(currentRoles);
+        tmp.forEach(role -> {
+            if (roles.remove(role)) {
+                currentRoles.remove(role);
+            }
+        });
+
+        if (!roles.isEmpty()) {
+            Set<GrantedAuthorityImpl> authorities = roles.stream()
+                    .map(role -> new GrantedAuthorityImpl(role.getTitle()))
+                    .collect(Collectors.toSet());
+            user.setAuthorities(authorities);
+            userRepository.save(user);
+        }
+
+        if (!currentRoles.isEmpty()) {
+            List<String> ids = currentRoles.stream().map(Role::getTitle).collect(Collectors.toList());
+            // TODO
+        }
+    }
+
+    public List<Role> getUserRoles(int userId) {
+        User user = userRepository.findById(userId);
+        List<String> roles = user.getAuthorities().stream()
+                .map(GrantedAuthority::getAuthority).collect(Collectors.toList());
+        return roleCrud.findUserRoles(roles);
     }
     }
 
 
     public List<Role> findUserRoles(int userId) {
     public List<Role> findUserRoles(int userId) {

+ 2 - 109
dmaster/src/main/java/cn/reghao/autodop/dmaster/auth/service/UserService.java

@@ -1,116 +1,9 @@
 package cn.reghao.autodop.dmaster.auth.service;
 package cn.reghao.autodop.dmaster.auth.service;
 
 
-import cn.reghao.autodop.common.utils.security.Cryptor;
-import cn.reghao.autodop.common.utils.security.Md5Cryptor;
-import cn.reghao.autodop.common.utils.security.Salt;
-import cn.reghao.autodop.dmaster.auth.db.RoleCrud;
-import cn.reghao.autodop.dmaster.auth.entity.GrantedAuthorityImpl;
-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.utils.db.PageList;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Sort;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.stereotype.Service;
-
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
 /**
 /**
  * @author reghao
  * @author reghao
  * @date 2020-06-19 16:36:53
  * @date 2020-06-19 16:36:53
  */
  */
-@Service
-public class UserService {
-    private final UserRepository userRepository;
-    private final RoleCrud roleCrud;
-    private final Cryptor cryptor;
-
-    public UserService(UserRepository userRepository, RoleCrud roleCrud)
-            throws NoSuchAlgorithmException {
-        this.userRepository = userRepository;
-        this.roleCrud = roleCrud;
-        this.cryptor = new Md5Cryptor();
-    }
-
-    public PageList<User> findByPage(int page, int size) {
-        PageRequest pageRequest =
-                PageRequest.of(page-1, size, Sort.by(Sort.Direction.DESC, "updateTime"));
-        Page<User> list = userRepository.findAll(pageRequest);
-        return PageList.pageList(list);
-    }
-
-    public User findById(int id) {
-        return userRepository.findById(id);
-    }
-
-    public void addOrUpdate(User user) {
-        Integer id = user.getId();
-        if (id == null) {
-            addUser(user);
-        } else {
-            updateUser(user);
-        }
-    }
-
-    private void addUser(User user) {
-        String password = user.getPassword();
-        String salt = Salt.get(64);
-        String encryptPwd = cryptor.encrypt(password + salt);
-        user.setPassword(encryptPwd);
-        user.setSalt(salt);
-        user.setAvatarUrl("/imgs/avatar/default.png");
-        userRepository.save(user);
-    }
-
-    private void updateUser(User user) {
-        userRepository.save(user);
-    }
-
-    public void modifyUserRoles(User user, Set<Role> roles) {
-        // 用户当前拥有的角色
-        List<String> roleList = user.getAuthorities().stream()
-                .map(GrantedAuthority::getAuthority).collect(Collectors.toList());
-        if (roleList.isEmpty()) {
-            Set<GrantedAuthorityImpl> authorities = roles.stream()
-                    .map(role -> new GrantedAuthorityImpl(role.getTitle()))
-                    .collect(Collectors.toSet());
-            user.setAuthorities(authorities);
-            userRepository.save(user);
-            return;
-        }
-
-        List<Role> currentRoles = getUserRoles(user.getId());
-        List<Role> tmp = new ArrayList<>(currentRoles);
-        tmp.forEach(role -> {
-            if (roles.remove(role)) {
-                currentRoles.remove(role);
-            }
-        });
-
-        if (!roles.isEmpty()) {
-            Set<GrantedAuthorityImpl> authorities = roles.stream()
-                    .map(role -> new GrantedAuthorityImpl(role.getTitle()))
-                    .collect(Collectors.toSet());
-            user.setAuthorities(authorities);
-            userRepository.save(user);
-        }
-
-        if (!currentRoles.isEmpty()) {
-            List<String> ids = currentRoles.stream().map(Role::getTitle).collect(Collectors.toList());
-            // TODO
-        }
-    }
-
-    public List<Role> getUserRoles(int userId) {
-        User user = userRepository.findById(userId);
-        List<String> roles = user.getAuthorities().stream()
-                .map(GrantedAuthority::getAuthority).collect(Collectors.toList());
-        return roleCrud.findUserRoles(roles);
-    }
+public interface UserService {
+    void createUser();
 }
 }

+ 13 - 8
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/MachineController.java

@@ -1,5 +1,6 @@
 package cn.reghao.autodop.dmaster.machine.controller;
 package cn.reghao.autodop.dmaster.machine.controller;
 
 
+import cn.reghao.autodop.dmaster.machine.entity.po.SshAuth;
 import cn.reghao.autodop.dmaster.machine.service.MachineService;
 import cn.reghao.autodop.dmaster.machine.service.MachineService;
 import cn.reghao.autodop.dmaster.notification.entity.NotifyGroup;
 import cn.reghao.autodop.dmaster.notification.entity.NotifyGroup;
 import cn.reghao.autodop.dmaster.utils.WebBody;
 import cn.reghao.autodop.dmaster.utils.WebBody;
@@ -10,6 +11,7 @@ import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
 
 
+import javax.validation.Valid;
 import java.util.List;
 import java.util.List;
 
 
 /**
 /**
@@ -32,25 +34,28 @@ public class MachineController {
     @ResponseBody
     @ResponseBody
     public ResponseEntity<String> setMonitorNotify(@PathVariable("machineId") String machineId,
     public ResponseEntity<String> setMonitorNotify(@PathVariable("machineId") String machineId,
                                                    @RequestParam("groupId") List<NotifyGroup> notifyGroups) {
                                                    @RequestParam("groupId") List<NotifyGroup> notifyGroups) {
-        //notifyGroups.forEach(notifyGroup -> monitorService.setNotify(jobId, notifyGroup));
+        machineService.setMachineNotify(machineId, notifyGroups);
         return ResponseEntity.ok().body(WebBody.success());
         return ResponseEntity.ok().body(WebBody.success());
     }
     }
 
 
     @ApiOperation(value = "编辑 SSH 认证信息")
     @ApiOperation(value = "编辑 SSH 认证信息")
-    @PostMapping(value = "/sshauth", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> editSshAuth() {
+    @PostMapping(value = "/sshauth/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public ResponseEntity<String> editSshAuth(@PathVariable("machineId") String machineId, @Valid SshAuth sshAuth) {
+        machineService.setSshAuth(machineId, sshAuth);
         return ResponseEntity.ok().body(WebBody.success());
         return ResponseEntity.ok().body(WebBody.success());
     }
     }
 
 
     @ApiOperation(value = "编辑机器额外信息")
     @ApiOperation(value = "编辑机器额外信息")
-    @PostMapping(value = "/host", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> editExtraMachineInfo() {
+    @PostMapping(value = "/host/extra/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public ResponseEntity<String> editExtraMachineInfo(@PathVariable("machineId") String machineId,
+                                                       @RequestParam("env") String env) {
+        machineService.setEnv(machineId, env);
         return ResponseEntity.ok().body(WebBody.success());
         return ResponseEntity.ok().body(WebBody.success());
     }
     }
 
 
     @ApiOperation(value = "删除机器")
     @ApiOperation(value = "删除机器")
-    @DeleteMapping(value = "/host", produces = MediaType.APPLICATION_JSON_VALUE)
-    public ResponseEntity<String> machine() {
-        return ResponseEntity.ok().body(WebBody.success());
+    @DeleteMapping(value = "/host/{machineId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public ResponseEntity<String> machine(@PathVariable("machineId") String machineId) {
+        return ResponseEntity.ok().body(WebBody.successWithMsg("删除成功"));
     }
     }
 }
 }

+ 111 - 48
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/controller/MachinePageController.java

@@ -1,15 +1,20 @@
 package cn.reghao.autodop.dmaster.machine.controller;
 package cn.reghao.autodop.dmaster.machine.controller;
 
 
+import cn.reghao.autodop.dmaster.app.constant.EnvType;
+import cn.reghao.autodop.dmaster.app.vo.KeyValue;
 import cn.reghao.autodop.dmaster.machine.db.crud.MachineHostCrudService;
 import cn.reghao.autodop.dmaster.machine.db.crud.MachineHostCrudService;
 import cn.reghao.autodop.dmaster.machine.db.crud.MachineInfoCrudService;
 import cn.reghao.autodop.dmaster.machine.db.crud.MachineInfoCrudService;
 import cn.reghao.autodop.dmaster.machine.db.crud.MachineStatCrudService;
 import cn.reghao.autodop.dmaster.machine.db.crud.MachineStatCrudService;
+import cn.reghao.autodop.dmaster.machine.db.query.MachineHostQuery;
 import cn.reghao.autodop.dmaster.machine.entity.SshConnData;
 import cn.reghao.autodop.dmaster.machine.entity.SshConnData;
 import cn.reghao.autodop.dmaster.machine.entity.po.MachineHost;
 import cn.reghao.autodop.dmaster.machine.entity.po.MachineHost;
 import cn.reghao.autodop.dmaster.machine.entity.po.MachineStat;
 import cn.reghao.autodop.dmaster.machine.entity.po.MachineStat;
 import cn.reghao.autodop.dmaster.machine.entity.po.SshAuth;
 import cn.reghao.autodop.dmaster.machine.entity.po.SshAuth;
 import cn.reghao.autodop.dmaster.machine.entity.po.info.MachineInfo;
 import cn.reghao.autodop.dmaster.machine.entity.po.info.MachineInfo;
-import cn.reghao.autodop.dmaster.machine.service.MachineService;
 import cn.reghao.autodop.dmaster.machine.entity.vo.HostInfo;
 import cn.reghao.autodop.dmaster.machine.entity.vo.HostInfo;
+import cn.reghao.autodop.dmaster.machine.service.ssh.Keys;
+import cn.reghao.autodop.dmaster.notification.entity.NotifyGroup;
+import cn.reghao.autodop.dmaster.notification.repository.NotifyGroupRepository;
 import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.utils.db.PageList;
 import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
@@ -24,6 +29,11 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RequestParam;
 
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 /**
 /**
  * @author reghao
  * @author reghao
  * @date 2019-08-30 18:49:15
  * @date 2019-08-30 18:49:15
@@ -35,17 +45,20 @@ import org.springframework.web.bind.annotation.RequestParam;
 public class MachinePageController {
 public class MachinePageController {
     private MachineInfoCrudService infoCrudService;
     private MachineInfoCrudService infoCrudService;
     private MachineHostCrudService hostCrudService;
     private MachineHostCrudService hostCrudService;
+    private MachineHostQuery hostQuery;
     private MachineStatCrudService statCrudService;
     private MachineStatCrudService statCrudService;
-    private MachineService machineService;
+    private NotifyGroupRepository receiverRepository;
 
 
     public MachinePageController(MachineInfoCrudService infoCrudService,
     public MachinePageController(MachineInfoCrudService infoCrudService,
                                  MachineHostCrudService hostCrudService,
                                  MachineHostCrudService hostCrudService,
+                                 MachineHostQuery hostQuery,
                                  MachineStatCrudService statCrudService,
                                  MachineStatCrudService statCrudService,
-                                 MachineService machineService) {
+                                 NotifyGroupRepository receiverRepository) {
         this.infoCrudService = infoCrudService;
         this.infoCrudService = infoCrudService;
         this.hostCrudService = hostCrudService;
         this.hostCrudService = hostCrudService;
+        this.hostQuery = hostQuery;
         this.statCrudService = statCrudService;
         this.statCrudService = statCrudService;
-        this.machineService = machineService;
+        this.receiverRepository = receiverRepository;
     }
     }
 
 
     @ApiOperation(value = "机器列表页面")
     @ApiOperation(value = "机器列表页面")
@@ -64,9 +77,63 @@ public class MachinePageController {
         return "/machine/host";
         return "/machine/host";
     }
     }
 
 
-    @ApiOperation(value = "机器编辑页面")
+    @ApiOperation(value = "机器通知设置页面")
+    @GetMapping("/notify/{machineId}")
+    public String machineNotifyPage(@PathVariable("machineId") String machineId, Model model) {
+        MachineHost machineHost = hostQuery.query(machineId);
+        Set<NotifyGroup> currentSet = new HashSet<>(machineHost.getNotifyGroups());
+        List<NotifyGroup> list = receiverRepository.findAll();
+
+        model.addAttribute("machineId", machineId);
+        model.addAttribute("currentSet", currentSet);
+        model.addAttribute("list", list);
+        return "/machine/machinenotify";
+    }
+
+    @ApiOperation(value = "SSH 认证设置页面")
+    @GetMapping("/sshauth/{machineId}")
+    public String sshAuthPage(@PathVariable("machineId") String machineId, Model model) {
+        MachineHost machineHost = hostQuery.query(machineId);
+        SshAuth sshAuth = machineHost.getSshAuth();
+
+        model.addAttribute("machineId", machineId);
+        model.addAttribute("sshAuth", sshAuth);
+        return "/machine/sshauth";
+    }
+
+    @ApiOperation(value = "SSH 控制台页面")
+    @GetMapping("/webssh/{machineId}")
+    public String webSshPage(@PathVariable("machineId") String machineId, Model model) {
+        MachineHost machineHost = hostQuery.query(machineId);
+        String machineIpv4 = machineHost.getMachineInfo().machineIpv4();
+        SshAuth sshAuth = machineHost.getSshAuth();
+        if (sshAuth == null) {
+            return "先设置 SSH 认证";
+        }
+
+        SshConnData sshConnData = new SshConnData();
+        sshConnData.setOps(Keys.OPS_CONNECT);
+        sshConnData.setHost(machineIpv4);
+        sshConnData.setPort(sshAuth.getPort());
+        sshConnData.setUsername(sshAuth.getUsername());
+        sshConnData.setPassword(sshAuth.getPassword());
+
+        model.addAttribute("sshConnData", sshConnData);
+        return "/machine/webssh";
+    }
+
+    @ApiOperation(value = "机器额外信息编辑页面")
     @GetMapping("/host/edit/{machineId}")
     @GetMapping("/host/edit/{machineId}")
     public String hostEditPage(@PathVariable("machineId") String machineId, Model model) {
     public String hostEditPage(@PathVariable("machineId") String machineId, Model model) {
+        List<KeyValue> envs = new ArrayList<>();
+        for (EnvType envType : EnvType.values()) {
+            envs.add(new KeyValue(envType.name(), envType.name()));
+        }
+
+        MachineHost machineHost = hostQuery.query(machineId);
+        model.addAttribute("machineId", machineId);
+        model.addAttribute("environments", envs);
+        model.addAttribute("env", machineHost.getEnv());
         return "/machine/edit";
         return "/machine/edit";
     }
     }
 
 
@@ -78,32 +145,6 @@ public class MachinePageController {
         return "/machine/detail";
         return "/machine/detail";
     }
     }
 
 
-    @ApiOperation(value = "机器状态详情页面")
-    @GetMapping("/host/status/{machineId}")
-    public String hostStatusPage(@PathVariable("machineId") String machineId, Model model) {
-        return "/machine/status";
-    }
-
-    @ApiOperation(value = "内存使用详情页面")
-    @GetMapping("/host/status/mem/{machineId}")
-    public String memUsagePage(@PathVariable("machineId") String machineId, Model model) {
-        MachineStat machineStat = statCrudService.selectByUk(machineId);
-        if (machineStat != null) {
-            model.addAttribute("memoryUsage", machineStat.getMemoryUsage());
-        }
-        return "/machine/memusage";
-    }
-
-    @ApiOperation(value = "磁盘使用详情页面")
-    @GetMapping("/host/status/disk/{machineId}")
-    public String diskUsagePage(@PathVariable("machineId") String machineId, Model model) {
-        MachineStat machineStat = statCrudService.selectByUk(machineId);
-        if (machineStat != null) {
-            model.addAttribute("diskUsages", machineStat.getDiskUsages());
-        }
-        return "/machine/diskusage";
-    }
-
     @ApiOperation(value = "机器状态列表页面")
     @ApiOperation(value = "机器状态列表页面")
     @GetMapping("/status")
     @GetMapping("/status")
     public String statusPage(@RequestParam(value = "env", required = false) String env,
     public String statusPage(@RequestParam(value = "env", required = false) String env,
@@ -120,27 +161,49 @@ public class MachinePageController {
         return "/machine/status";
         return "/machine/status";
     }
     }
 
 
-    @ApiOperation(value = "机器通知设置页面")
-    @GetMapping("/notify/{machineId}")
-    public String machineNotifyPage(@PathVariable("machineId") String machineId, Model model) {
-        return "/machine/machinenotify";
+    @ApiOperation(value = "机器系统负载页面")
+    @GetMapping("/status/sys/{machineId}")
+    public String hostStatusPage(@PathVariable("machineId") String machineId, Model model) {
+        return "/machine/sysload";
     }
     }
 
 
-    @ApiOperation(value = "SSH 认证设置页面")
-    @GetMapping("/sshauth/{machineId}")
-    public String sshAuthPage(@PathVariable("machineId") String machineId, Model model) {
-        SshAuth sshAuth = new SshAuth();
+    @ApiOperation(value = "网络状态页面")
+    @GetMapping("/status/network/{machineId}")
+    public String networkStatusPage(@PathVariable("machineId") String machineId, Model model) {
+        MachineStat machineStat = statCrudService.selectByUk(machineId);
+        if (machineStat != null) {
+            model.addAttribute("memoryUsage", machineStat.getMemoryUsage());
+        }
+        return "/machine/networkstatus";
+    }
 
 
-        model.addAttribute("machineId", machineId);
-        model.addAttribute("sshAuth", sshAuth);
-        return "/machine/sshauth";
+    @ApiOperation(value = "CPU 使用率页面")
+    @GetMapping("/status/cpu/{machineId}")
+    public String cpuUsagePage(@PathVariable("machineId") String machineId, Model model) {
+        MachineStat machineStat = statCrudService.selectByUk(machineId);
+        if (machineStat != null) {
+            model.addAttribute("memoryUsage", machineStat.getMemoryUsage());
+        }
+        return "/machine/cpuusage";
     }
     }
 
 
-    @ApiOperation(value = "SSH 控制台页面")
-    @GetMapping("/webssh/{machineId}")
-    public String webSshPage(@PathVariable("machineId") String machineId, Model model) {
-        SshConnData sshConnData = new SshConnData();
-        model.addAttribute("sshConnData", sshConnData);
-        return "/machine/webssh";
+    @ApiOperation(value = "内存详情页面")
+    @GetMapping("/status/mem/{machineId}")
+    public String memUsagePage(@PathVariable("machineId") String machineId, Model model) {
+        MachineStat machineStat = statCrudService.selectByUk(machineId);
+        if (machineStat != null) {
+            model.addAttribute("memoryUsage", machineStat.getMemoryUsage());
+        }
+        return "/machine/memusage";
+    }
+
+    @ApiOperation(value = "磁盘详情页面")
+    @GetMapping("/status/disk/{machineId}")
+    public String diskUsagePage(@PathVariable("machineId") String machineId, Model model) {
+        MachineStat machineStat = statCrudService.selectByUk(machineId);
+        if (machineStat != null) {
+            model.addAttribute("diskUsages", machineStat.getDiskUsages());
+        }
+        return "/machine/diskusage";
     }
     }
 }
 }

+ 1 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/entity/po/MachineHost.java

@@ -28,6 +28,7 @@ public class MachineHost extends BaseEntity<Integer> {
     private String env;
     private String env;
     private String status;
     private String status;
     private LocalDateTime lastCheck;
     private LocalDateTime lastCheck;
+    private SshAuth sshAuth;
     @ManyToMany(cascade = CascadeType.REFRESH)
     @ManyToMany(cascade = CascadeType.REFRESH)
     @JoinColumn(name = "notify_group_id", foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
     @JoinColumn(name = "notify_group_id", foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
     @LazyCollection(LazyCollectionOption.FALSE)
     @LazyCollection(LazyCollectionOption.FALSE)

+ 11 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/entity/po/SshAuth.java

@@ -2,14 +2,25 @@ package cn.reghao.autodop.dmaster.machine.entity.po;
 
 
 import lombok.Data;
 import lombok.Data;
 
 
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.Lob;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Positive;
+
 /**
 /**
  * @author reghao
  * @author reghao
  * @date 2021-07-07 17:30:12
  * @date 2021-07-07 17:30:12
  */
  */
 @Data
 @Data
+@Embeddable
 public class SshAuth {
 public class SshAuth {
+    @Positive(message = "SSH 端口必须有效")
     private Integer port;
     private Integer port;
+    @NotBlank(message = "用户名为空白字符串")
     private String username;
     private String username;
     private String password;
     private String password;
+    @Lob
+    @Column(columnDefinition="text")
     private String rsaPrikey;
     private String rsaPrikey;
 }
 }

+ 27 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/service/MachineService.java

@@ -1,17 +1,43 @@
 package cn.reghao.autodop.dmaster.machine.service;
 package cn.reghao.autodop.dmaster.machine.service;
 
 
+import cn.reghao.autodop.dmaster.machine.db.crud.MachineHostCrudService;
 import cn.reghao.autodop.dmaster.machine.db.query.MachineHostQuery;
 import cn.reghao.autodop.dmaster.machine.db.query.MachineHostQuery;
+import cn.reghao.autodop.dmaster.machine.entity.po.MachineHost;
+import cn.reghao.autodop.dmaster.machine.entity.po.SshAuth;
+import cn.reghao.autodop.dmaster.notification.entity.NotifyGroup;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 
 
+import java.util.List;
+
 /**
 /**
  * @author reghao
  * @author reghao
  * @date 2019-11-15 08:48:04
  * @date 2019-11-15 08:48:04
  */
  */
 @Service
 @Service
 public class MachineService {
 public class MachineService {
+    private MachineHostCrudService hostCrudService;
     private MachineHostQuery hostQuery;
     private MachineHostQuery hostQuery;
 
 
-    public MachineService(MachineHostQuery hostQuery) {
+    public MachineService(MachineHostCrudService hostCrudService, MachineHostQuery hostQuery) {
+        this.hostCrudService = hostCrudService;
         this.hostQuery = hostQuery;
         this.hostQuery = hostQuery;
     }
     }
+
+    public void setMachineNotify(String machineId, List<NotifyGroup> notifyGroups) {
+        MachineHost machineHost = hostQuery.query(machineId);
+        machineHost.setNotifyGroups(notifyGroups);
+        hostCrudService.insertOrUpdate(machineHost);
+    }
+
+    public void setSshAuth(String machineId, SshAuth sshAuth) {
+        MachineHost machineHost = hostQuery.query(machineId);
+        machineHost.setSshAuth(sshAuth);
+        hostCrudService.insertOrUpdate(machineHost);
+    }
+
+    public void setEnv(String machineId, String env) {
+        MachineHost machineHost = hostQuery.query(machineId);
+        machineHost.setEnv(env);
+        hostCrudService.insertOrUpdate(machineHost);
+    }
 }
 }

+ 1 - 0
dmaster/src/main/java/cn/reghao/autodop/dmaster/machine/service/ssh/ws/WebsocketInterceptor.java

@@ -19,6 +19,7 @@ public class WebsocketInterceptor implements HandshakeInterceptor {
     @Override
     @Override
     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                    WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
                                    WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
+        // TODO 使用经过 HTTP 认证的用户信息
         if (request instanceof ServletServerHttpRequest) {
         if (request instanceof ServletServerHttpRequest) {
             ServletServerHttpRequest httpRequest = (ServletServerHttpRequest) request;
             ServletServerHttpRequest httpRequest = (ServletServerHttpRequest) request;
             String uuid = UUID.randomUUID().toString();
             String uuid = UUID.randomUUID().toString();

+ 1 - 1
dmaster/src/main/java/cn/reghao/autodop/dmaster/utils/WebBody.java

@@ -56,7 +56,7 @@ public class WebBody {
         return null;
         return null;
     }
     }
 
 
-    public static String successMsg(String msg) {
+    public static String successWithMsg(String msg) {
         WebBody webBody = new WebBody(SUCCESS.getCode(), msg);
         WebBody webBody = new WebBody(SUCCESS.getCode(), msg);
         webBody.setTimestamp(DateTimeConverter.now());
         webBody.setTimestamp(DateTimeConverter.now());
         try {
         try {

+ 6 - 12
dmaster/src/main/java/cn/reghao/autodop/dmaster/view/controller/UserController.java

@@ -1,10 +1,8 @@
 package cn.reghao.autodop.dmaster.view.controller;
 package cn.reghao.autodop.dmaster.view.controller;
 
 
+import cn.reghao.autodop.dmaster.auth.db.UserCrud;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.User;
 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 cn.reghao.autodop.dmaster.utils.WebBody;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
@@ -22,20 +20,16 @@ import java.util.List;
 @RequestMapping("/system/user")
 @RequestMapping("/system/user")
 @RestController
 @RestController
 public class UserController {
 public class UserController {
-    private final UserService userService;
-    private UserRepository userRepository;
-    private RoleRepository roleRepository;
+    private UserCrud userCrud;
 
 
-    public UserController(UserService userService, RoleRepository roleRepository, UserRepository userRepository) {
-        this.userService = userService;
-        this.roleRepository = roleRepository;
-        this.userRepository = userRepository;
+    public UserController(UserCrud userCrud) {
+        this.userCrud = userCrud;
     }
     }
 
 
     @ApiOperation(value = "新增/修改用户")
     @ApiOperation(value = "新增/修改用户")
     @PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
     @PostMapping(value = "/save", produces = MediaType.APPLICATION_JSON_VALUE)
     public String addOrUpdateUser(User user) {
     public String addOrUpdateUser(User user) {
-        userService.addOrUpdate(user);
+        userCrud.addOrUpdate(user);
         return WebBody.success();
         return WebBody.success();
     }
     }
 
 
@@ -52,7 +46,7 @@ public class UserController {
     @PostMapping(value = "/role", produces = MediaType.APPLICATION_JSON_VALUE)
     @PostMapping(value = "/role", produces = MediaType.APPLICATION_JSON_VALUE)
     public String assignRole(@RequestParam(value = "id") User user,
     public String assignRole(@RequestParam(value = "id") User user,
                              @RequestParam(value = "roleId", required = false) HashSet<Role> roles) {
                              @RequestParam(value = "roleId", required = false) HashSet<Role> roles) {
-        userService.modifyUserRoles(user, roles);
+        userCrud.modifyUserRoles(user, roles);
         return WebBody.success();
         return WebBody.success();
     }
     }
 }
 }

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

@@ -1,11 +1,10 @@
 package cn.reghao.autodop.dmaster.view.controller;
 package cn.reghao.autodop.dmaster.view.controller;
 
 
-import cn.reghao.autodop.dmaster.auth.entity.Menu;
+import cn.reghao.autodop.dmaster.auth.db.UserCrud;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.Role;
 import cn.reghao.autodop.dmaster.auth.entity.User;
 import cn.reghao.autodop.dmaster.auth.entity.User;
 import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.repository.RoleRepository;
 import cn.reghao.autodop.dmaster.auth.repository.UserRepository;
 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.db.PageList;
 import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import cn.reghao.autodop.dmaster.utils.db.PageSort;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
@@ -16,7 +15,6 @@ import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.*;
 
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 
 
 /**
 /**
@@ -27,12 +25,12 @@ import java.util.List;
 @RequestMapping("/system/user")
 @RequestMapping("/system/user")
 @Controller
 @Controller
 public class UserPageController {
 public class UserPageController {
-    private final UserService userService;
+    private UserCrud userCrud;
     private UserRepository userRepository;
     private UserRepository userRepository;
     private RoleRepository roleRepository;
     private RoleRepository roleRepository;
 
 
-    public UserPageController(UserService userService, RoleRepository roleRepository, UserRepository userRepository) {
-        this.userService = userService;
+    public UserPageController(UserCrud userCrud, RoleRepository roleRepository, UserRepository userRepository) {
+        this.userCrud = userCrud;
         this.roleRepository = roleRepository;
         this.roleRepository = roleRepository;
         this.userRepository = userRepository;
         this.userRepository = userRepository;
     }
     }
@@ -55,14 +53,14 @@ public class UserPageController {
 
 
     @GetMapping("/edit/{id}")
     @GetMapping("/edit/{id}")
     public String editUserPage(@PathVariable("id") int id, Model model) {
     public String editUserPage(@PathVariable("id") int id, Model model) {
-        User userInfo = userService.findById(id);
+        User userInfo = userCrud.findById(id);
         model.addAttribute("user", userInfo);
         model.addAttribute("user", userInfo);
         return "/system/user/add";
         return "/system/user/add";
     }
     }
 
 
     @GetMapping("/detail/{id}")
     @GetMapping("/detail/{id}")
     public String userDetailPage(@PathVariable("id") int id, Model model) {
     public String userDetailPage(@PathVariable("id") int id, Model model) {
-        User userInfo = userService.findById(id);
+        User userInfo = userCrud.findById(id);
         model.addAttribute("user", userInfo);
         model.addAttribute("user", userInfo);
         return "/system/user/detail";
         return "/system/user/detail";
     }
     }
@@ -77,7 +75,7 @@ public class UserPageController {
     @GetMapping("/role")
     @GetMapping("/role")
     public String assignRolePage(@RequestParam(value = "ids") int userId, Model model) {
     public String assignRolePage(@RequestParam(value = "ids") int userId, Model model) {
         List<Role> roles = roleRepository.findAll();
         List<Role> roles = roleRepository.findAll();
-        List<Role> authRoles = userService.getUserRoles(userId);
+        List<Role> authRoles = userCrud.getUserRoles(userId);
 
 
         model.addAttribute("id", userId);
         model.addAttribute("id", userId);
         model.addAttribute("list", roles);
         model.addAttribute("list", roles);
@@ -88,7 +86,7 @@ public class UserPageController {
     @ApiOperation(value = "获取角色列表页面")
     @ApiOperation(value = "获取角色列表页面")
     @GetMapping("/roleList/{userId}")
     @GetMapping("/roleList/{userId}")
     public String roleListWithResource(@PathVariable("userId") User user, Model model) {
     public String roleListWithResource(@PathVariable("userId") User user, Model model) {
-        List<Role> list = userService.getUserRoles(user.getId());
+        List<Role> list = userCrud.getUserRoles(user.getId());
         model.addAttribute("list", list);
         model.addAttribute("list", list);
         return "/system/user/roleList";
         return "/system/user/roleList";
     }
     }

+ 0 - 1
dmaster/src/main/resources/templates/app/config/app/notify.html

@@ -20,7 +20,6 @@
 </head>
 </head>
 <body>
 <body>
 <div class="layui-form timo-compile">
 <div class="layui-form timo-compile">
-    <!--<form th:action="@{'/api/app/config/app/notify/'+${id}}">-->
     <form th:action="@{/api/app/config/app/notify/}">
     <form th:action="@{/api/app/config/app/notify/}">
         <input type="hidden" name="id" th:value="${id}"/>
         <input type="hidden" name="id" th:value="${id}"/>
         <div class="layui-form-item">
         <div class="layui-form-item">

+ 31 - 0
dmaster/src/main/resources/templates/machine/cpuusage.html

@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+    <div class="timo-detail-page">
+        <div class="timo-detail-title">内存使用情况</div>
+        <table class="layui-table timo-detail-table">
+            <tbody>
+            <tr>
+                <th>内存总量</th>
+                <td th:text="${memoryUsage?.total}"></td>
+                <th>已用内存</th>
+                <td th:text="${memoryUsage?.used}"></td>
+                <th>可用内存</th>
+                <td th:text="${memoryUsage?.avail}"></td>
+            </tr>
+            <tr>
+                <th>交换分区总量</th>
+                <td th:text="${memoryUsage?.swapTotal}"></td>
+                <th>已使用交换分区</th>
+                <td th:text="${memoryUsage?.swapUsed}"></td>
+                <th>可用交换分区</th>
+                <td th:text="${memoryUsage?.swapAvail}"></td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 5 - 10
dmaster/src/main/resources/templates/machine/edit.html

@@ -4,18 +4,13 @@
 
 
 <body>
 <body>
 <div class="layui-form timo-compile">
 <div class="layui-form timo-compile">
-    <form th:action="@{'/api/monitor/job'}">
-        <!--<input type="hidden" name="jobId" th:value="${monitorJob.jobId}"/>-->
+    <form th:action="@{'/api/machine/host/extra/'+${machineId}}">
         <div class="layui-form-item">
         <div class="layui-form-item">
-            <label class="layui-form-label required">任务类名</label>
+            <label class="layui-form-label required">环境</label>
             <div class="layui-input-inline">
             <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="jobClassName" readonly="true" th:value="${monitorJob.jobClassName}">
-            </div>
-        </div>
-        <div class="layui-form-item">
-            <label class="layui-form-label required">CRON 表达式</label>
-            <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="cronExp" placeholder="请输入 CRON 表达式" required th:value="${monitorJob.cronExp}">
+                <select name="env">
+                    <option th:each="item : ${environments}" th:value="${item.key}" th:selected="${env} eq ${item.key}">[[${item.value}]]</option>
+                </select>
             </div>
             </div>
         </div>
         </div>
         <div class="layui-form-item timo-finally">
         <div class="layui-form-item timo-finally">

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

@@ -89,7 +89,7 @@
                         <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/machine/host/edit/'+${item.machineId}}"
                         <a class="open-popup" data-title="编辑" th:attr="data-url=@{'/machine/host/edit/'+${item.machineId}}"
                            data-size="800,600" href="#">编辑</a>
                            data-size="800,600" href="#">编辑</a>
                         <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.machineId} + ' 机器?'"
                         <a class="ajax-delete" th:attr="data-msg='确定要删除 '+ ${item.machineId} + ' 机器?'"
-                           th:href="@{'/api/machine/host' + ${item.machineId}}">删除</a>
+                           th:href="@{'/api/machine/host/' + ${item.machineId}}">删除</a>
                     </td>
                     </td>
                 </tr>
                 </tr>
                 </tbody>
                 </tbody>

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

@@ -20,7 +20,7 @@
 </head>
 </head>
 <body>
 <body>
 <div class="layui-form timo-compile">
 <div class="layui-form timo-compile">
-    <form th:action="@{'/api/monitor/notify/'+ ${jobId}}">
+    <form th:action="@{'/api/machine/notify/'+ ${machineId}}">
         <div class="layui-form-item">
         <div class="layui-form-item">
             <div class="layui-input-block">
             <div class="layui-input-block">
                 <input th:each="item:${list}" type="checkbox" name="groupId" th:title="${item.groupId}"
                 <input th:each="item:${list}" type="checkbox" name="groupId" th:title="${item.groupId}"

+ 31 - 0
dmaster/src/main/resources/templates/machine/networkstatus.html

@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+    <div class="timo-detail-page">
+        <div class="timo-detail-title">磁盘使用情况</div>
+        <table class="layui-table timo-detail-table">
+            <tbody>
+            <tr th:each="item:${diskUsages}">
+                <th>分区挂载路径</th>
+                <td th:text="${item.mountedOn}"></td>
+                <th>文件系统</th>
+                <td th:text="${item.fsType}"></td>
+                <th>总容量</th>
+                <td th:text="${item.total}"></td>
+                <th>已使用</th>
+                <td th:text="${item.used}"></td>
+                <th>可用</th>
+                <td th:text="${item.avail}"></td>
+                <th>inode 总量</th>
+                <td th:text="${item.inodeTotal}"></td>
+                <th>inode 可用量</th>
+                <td th:text="${item.inodeFree}"></td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 3 - 4
dmaster/src/main/resources/templates/machine/sshauth.html

@@ -4,12 +4,11 @@
 
 
 <body>
 <body>
 <div class="layui-form timo-compile">
 <div class="layui-form timo-compile">
-    <form th:action="@{'/api/machine/sshauth'}">
-        <input type="hidden" name="machineId" th:value="${machineId}"/>
+    <form th:action="@{'/api/machine/sshauth/'+${machineId}}">
         <div class="layui-form-item">
         <div class="layui-form-item">
             <label class="layui-form-label required">SSH 端口</label>
             <label class="layui-form-label required">SSH 端口</label>
             <div class="layui-input-inline">
             <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="port" readonly="true" th:value="${sshAuth.port}">
+                <input class="layui-input" type="text" name="port" placeholder="请输入 SSH 端口" th:value="${sshAuth.port}">
             </div>
             </div>
         </div>
         </div>
         <div class="layui-form-item">
         <div class="layui-form-item">
@@ -27,7 +26,7 @@
         <div class="layui-form-item">
         <div class="layui-form-item">
             <label class="layui-form-label required">RSA 私钥</label>
             <label class="layui-form-label required">RSA 私钥</label>
             <div class="layui-input-inline">
             <div class="layui-input-inline">
-                <input class="layui-input" type="text" name="rsaPrikey" placeholder="请输入 RSA 私钥" required th:value="${sshAuth.rsaPrikey}">
+                <textarea class="layui-textarea" name="rsaPrikey" placeholder="请输入 RSA 私钥" required th:text="${sshAuth.rsaPrikey}"></textarea>
             </div>
             </div>
         </div>
         </div>
         <div class="layui-form-item timo-finally">
         <div class="layui-form-item timo-finally">

+ 5 - 5
dmaster/src/main/resources/templates/machine/status.html

@@ -52,27 +52,27 @@
                     <td th:text="${item.machineIpv4}">机器地址</td>
                     <td th:text="${item.machineIpv4}">机器地址</td>
                     <td>
                     <td>
                         <a class="open-popup" data-title="系统负载"
                         <a class="open-popup" data-title="系统负载"
-                           th:attr="data-url=@{'/machine/host/status/mem/'+${item.machineId}}" data-size="800,600"
+                           th:attr="data-url=@{'/machine/status/sys/'+${item.machineId}}" data-size="800,600"
                            href="#">查看</a>
                            href="#">查看</a>
                     </td>
                     </td>
                     <td>
                     <td>
                         <a class="open-popup" data-title="网络状态"
                         <a class="open-popup" data-title="网络状态"
-                           th:attr="data-url=@{'/machine/host/status/mem/'+${item.machineId}}" data-size="800,600"
+                           th:attr="data-url=@{'/machine/status/network/'+${item.machineId}}" data-size="800,600"
                            href="#">查看</a>
                            href="#">查看</a>
                     </td>
                     </td>
                     <td>
                     <td>
                         <a class="open-popup" data-title="CPU 使用率"
                         <a class="open-popup" data-title="CPU 使用率"
-                           th:attr="data-url=@{'/machine/host/status/mem/'+${item.machineId}}" data-size="800,600"
+                           th:attr="data-url=@{'/machine/status/cpu/'+${item.machineId}}" data-size="800,600"
                            href="#">查看</a>
                            href="#">查看</a>
                     </td>
                     </td>
                     <td>
                     <td>
                         <a class="open-popup" data-title="内存详情"
                         <a class="open-popup" data-title="内存详情"
-                           th:attr="data-url=@{'/machine/host/status/mem/'+${item.machineId}}" data-size="800,600"
+                           th:attr="data-url=@{'/machine/status/mem/'+${item.machineId}}" data-size="800,600"
                            href="#">查看</a>
                            href="#">查看</a>
                     </td>
                     </td>
                     <td>
                     <td>
                         <a class="open-popup" data-title="磁盘详情"
                         <a class="open-popup" data-title="磁盘详情"
-                           th:attr="data-url=@{'/machine/host/status/disk/'+${item.machineId}}" data-size="1200,600"
+                           th:attr="data-url=@{'/machine/status/disk/'+${item.machineId}}" data-size="800,600"
                            href="#">查看</a>
                            href="#">查看</a>
                     </td>
                     </td>
                 </tr>
                 </tr>

+ 31 - 0
dmaster/src/main/resources/templates/machine/sysload.html

@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:replace="/common/template :: header(~{::title},~{::link},~{::style})"></head>
+
+<body>
+    <div class="timo-detail-page">
+        <div class="timo-detail-title">内存使用情况</div>
+        <table class="layui-table timo-detail-table">
+            <tbody>
+            <tr>
+                <th>内存总量</th>
+                <td th:text="${memoryUsage?.total}"></td>
+                <th>已用内存</th>
+                <td th:text="${memoryUsage?.used}"></td>
+                <th>可用内存</th>
+                <td th:text="${memoryUsage?.avail}"></td>
+            </tr>
+            <tr>
+                <th>交换分区总量</th>
+                <td th:text="${memoryUsage?.swapTotal}"></td>
+                <th>已使用交换分区</th>
+                <td th:text="${memoryUsage?.swapUsed}"></td>
+                <th>可用交换分区</th>
+                <td th:text="${memoryUsage?.swapAvail}"></td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+<script th:replace="/common/template :: script"></script>
+</body>
+</html>

+ 3 - 9
dmaster/src/main/resources/templates/machine/webssh.html

@@ -11,15 +11,8 @@
 <script type="text/javascript" th:src="@{/js/plugins/jquery-3.4.1.min.js}"></script>
 <script type="text/javascript" th:src="@{/js/plugins/jquery-3.4.1.min.js}"></script>
 <script type="text/javascript" th:src="@{/js/webssh.js}"></script>
 <script type="text/javascript" th:src="@{/js/webssh.js}"></script>
 <script type="text/javascript" th:src="@{/js/xterm.js}"></script>
 <script type="text/javascript" th:src="@{/js/xterm.js}"></script>
-<script type="text/javascript">
-    // TODO 在 controller 的 model 中指定数据
-    var options = {
-        ops:'connect',
-        host: '192.168.0.171',//IP
-        port: '22',//端口号
-        username: 'root',//用户名
-        password: 'azy'//密码
-    }
+<script type="text/javascript" th:inline="javascript">
+    var options = [[${sshConnData}]]
     openTerminal(options);
     openTerminal(options);
 
 
     function openTerminal(options){
     function openTerminal(options){
@@ -51,6 +44,7 @@
             onConnect: function () {
             onConnect: function () {
                 // 连接成功回调
                 // 连接成功回调
                 console.log('WebSocket 连接成功...')
                 console.log('WebSocket 连接成功...')
+                // 发送 SSH 连接数据
                 client.sendInitData(options);
                 client.sendInitData(options);
             },
             },
             onClose: function () {
             onClose: function () {