feat: Agent采集uptime, 后端持久化kernel/uptime/diskIO, 前端磁盘BPS+IOPS展示
- Agent: system.go 添加 readUptime(), SystemStat 携带 Uptime - Backend: Server 模型新增 Kernel 字段, ReceiveReport 持久化 kernel+uptime - Backend: /agent/latest 返回 kernel/uptime/port_info/disk_io_info/disk_total - Frontend: 磁盘监控改为 BPS+IOPS (4张卡片), 系统信息修复内核/运行时长/监听端口/磁盘容量 - 图表单位从 MB/s 改为 KB/s, 添加 formatBPS 工具函数
This commit is contained in:
1 parent
31c2e338a3
commit
5949ec5d0c
48 files changed
+2182
-956
No files matched your search
@@ -14,7 +14,7 @@ import (
|
||||
// 批量操作域:批量导入 + 批量删除 // Logan.Li
|
||||
|
||||
// BatchCreateServers 批量导入服务器 // Logan.Li
|
||||
// 接收 {servers:[...], region_id, auth_type},逐条校验并创建,跳过重复(主机名或IP已存在)
|
||||
// 接收 {servers:[...], region_id, auth_type, credential_id},逐条校验并创建,跳过重复(主机名或IP已存在)
|
||||
func (h *ServerHandler) BatchCreateServers(c *gin.Context) {
|
||||
var req models.BatchCreateServerRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
@@ -30,6 +30,28 @@ func (h *ServerHandler) BatchCreateServers(c *gin.Context) {
|
||||
authType = "password"
|
||||
}
|
||||
|
||||
// 如果指定了凭据,提前解密 // Logan.Li
|
||||
var decryptedPwd, decryptedKey string
|
||||
if req.CredentialID != nil && *req.CredentialID > 0 {
|
||||
var cred models.Credential
|
||||
if err := h.db.First(&cred, *req.CredentialID).Error; err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "凭据不存在"})
|
||||
return
|
||||
}
|
||||
plain, err := h.crypt.Decrypt(cred.Content)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "凭据解密失败"})
|
||||
return
|
||||
}
|
||||
if cred.Type == "ssh_key" {
|
||||
decryptedKey = plain
|
||||
authType = "key"
|
||||
} else {
|
||||
decryptedPwd = plain
|
||||
authType = "password"
|
||||
}
|
||||
}
|
||||
|
||||
result := models.BatchCreateResult{Errors: []string{}}
|
||||
for i, item := range req.Servers {
|
||||
hostname := strings.TrimSpace(item.Hostname)
|
||||
@@ -63,6 +85,8 @@ func (h *ServerHandler) BatchCreateServers(c *gin.Context) {
|
||||
Port: port,
|
||||
Username: username,
|
||||
AuthType: authType,
|
||||
Password: decryptedPwd,
|
||||
SSHKey: decryptedKey,
|
||||
OS: item.OS,
|
||||
CPU: item.CPU,
|
||||
Memory: item.Memory * 1024, // GB → MB
|
||||
@@ -111,7 +135,13 @@ func (h *ServerHandler) BatchDeleteServers(c *gin.Context) {
|
||||
var servers []models.Server
|
||||
h.db.Where("id IN ?", req.IDs).Find(&servers)
|
||||
|
||||
if err := h.db.Delete(&models.Server{}, req.IDs).Error; err != nil {
|
||||
// 硬删除:先清理每台服务器的 Agent 上报和聚合数据
|
||||
for _, s := range servers {
|
||||
h.db.Unscoped().Where("hostname = ?", s.Hostname).Delete(&models.AgentReport{})
|
||||
h.db.Unscoped().Where("hostname = ?", s.Hostname).Delete(&models.MetricsAggregate{})
|
||||
}
|
||||
|
||||
if err := h.db.Unscoped().Delete(&models.Server{}, req.IDs).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{
|
||||
Code: 500,
|
||||
Message: "删除失败",
|
||||
@@ -126,6 +156,6 @@ func (h *ServerHandler) BatchDeleteServers(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{
|
||||
Code: 200,
|
||||
Message: "删除成功",
|
||||
Message: "服务器已彻底删除",
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user