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
@@ -0,0 +1,160 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"ezops/internal/models"
|
||||
"ezops/pkg/crypto"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// CredentialHandler 凭据管理处理器 // Logan.Li
|
||||
type CredentialHandler struct {
|
||||
db *gorm.DB
|
||||
crypt *crypto.SecretBox
|
||||
}
|
||||
|
||||
func NewCredentialHandler(db *gorm.DB, masterKey string) *CredentialHandler {
|
||||
return &CredentialHandler{
|
||||
db: db,
|
||||
crypt: crypto.NewSecretBox(masterKey),
|
||||
}
|
||||
}
|
||||
|
||||
// preview 内容脱敏预览:前8字符 + ... + 后4字符
|
||||
func preview(s string) string {
|
||||
if len(s) <= 12 {
|
||||
return "****"
|
||||
}
|
||||
return s[:8] + "..." + s[len(s)-4:]
|
||||
}
|
||||
|
||||
// ListCredentials 凭据列表
|
||||
func (h *CredentialHandler) ListCredentials(c *gin.Context) {
|
||||
var creds []models.Credential
|
||||
if err := h.db.Order("updated_at DESC").Find(&creds).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "查询失败"})
|
||||
return
|
||||
}
|
||||
items := make([]models.CredentialListResponse, 0, len(creds))
|
||||
for _, cred := range creds {
|
||||
items = append(items, models.CredentialListResponse{
|
||||
ID: cred.ID,
|
||||
Name: cred.Name,
|
||||
Type: cred.Type,
|
||||
Preview: preview(cred.Content),
|
||||
Description: cred.Description,
|
||||
CreatedAt: cred.CreatedAt,
|
||||
UpdatedAt: cred.UpdatedAt,
|
||||
})
|
||||
}
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Data: models.ListResponse{
|
||||
List: items, Total: int64(len(items)),
|
||||
}})
|
||||
}
|
||||
|
||||
// CreateCredential 创建凭据
|
||||
func (h *CredentialHandler) CreateCredential(c *gin.Context) {
|
||||
var req models.CredentialCreateRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "参数错误: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
encrypted, err := h.crypt.Encrypt(req.Content)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "加密失败"})
|
||||
return
|
||||
}
|
||||
|
||||
cred := models.Credential{
|
||||
Name: req.Name,
|
||||
Type: req.Type,
|
||||
Content: encrypted,
|
||||
Description: req.Description,
|
||||
}
|
||||
if err := h.db.Create(&cred).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "创建失败"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{
|
||||
Code: 200,
|
||||
Message: "创建成功",
|
||||
Data: models.CredentialListResponse{
|
||||
ID: cred.ID,
|
||||
Name: cred.Name,
|
||||
Type: cred.Type,
|
||||
Preview: preview(cred.Content),
|
||||
Description: cred.Description,
|
||||
CreatedAt: cred.CreatedAt,
|
||||
UpdatedAt: cred.UpdatedAt,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateCredential 更新凭据
|
||||
func (h *CredentialHandler) UpdateCredential(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "无效ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var req models.CredentialUpdateRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "参数错误: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
var cred models.Credential
|
||||
if h.db.First(&cred, id).Error != nil {
|
||||
c.JSON(http.StatusNotFound, models.Response{Code: 404, Message: "凭据不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
cred.Name = req.Name
|
||||
cred.Type = req.Type
|
||||
cred.Description = req.Description
|
||||
|
||||
if req.Content != "" {
|
||||
encrypted, err := h.crypt.Encrypt(req.Content)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "加密失败"})
|
||||
return
|
||||
}
|
||||
cred.Content = encrypted
|
||||
}
|
||||
|
||||
if err := h.db.Save(&cred).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "更新失败"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "更新成功"})
|
||||
}
|
||||
|
||||
// DeleteCredential 删除凭据
|
||||
func (h *CredentialHandler) DeleteCredential(c *gin.Context) {
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "无效ID"})
|
||||
return
|
||||
}
|
||||
|
||||
var cred models.Credential
|
||||
if h.db.First(&cred, id).Error != nil {
|
||||
c.JSON(http.StatusNotFound, models.Response{Code: 404, Message: "凭据不存在"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.db.Delete(&cred).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "删除失败"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "删除成功"})
|
||||
}
|
||||
Reference in new issue
Block a user