feat(k8s): M14 Namespace 管理看板(资源配额 + 命名空间 CRUD)
- 后端: ListNamespacesDetailed/CreateNamespace/DeleteNamespace/ListResourceQuotas/ListLimitRanges - 后端: GetNamespacesDetail handler (6 API calls aggregate, not N×3) - 后端: CreateNamespaceHandler + DeleteNamespaceHandler (system NS protection) - 前端: NamespaceManagementPage.tsx (~280行) — 表格+概览卡片+创建/删除弹框 - 路由: GET/POST/DELETE /:clusterCode/namespaces + GET /namespace/:ns/detail - 验证: 9/9 通过 (urllib), TS 零错误, Vite 构建成功
This commit is contained in:
1 parent
c7b61968bc
commit
8240a88a84
33 files changed
+2029
-71
No files matched your search
@@ -62,6 +62,7 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
|
||||
report := models.AgentReport{
|
||||
Hostname: req.Hostname,
|
||||
CPUUsage: req.CPU.UsagePercent,
|
||||
CPUIOwait: req.CPU.IOWait,
|
||||
CPUCores: req.CPU.CoreCount,
|
||||
Load1: req.CPU.Load1,
|
||||
Load5: req.CPU.Load5,
|
||||
@@ -69,6 +70,8 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
|
||||
MemTotal: req.Memory.TotalGB,
|
||||
MemUsed: req.Memory.UsedGB,
|
||||
MemUsage: req.Memory.UsagePercent,
|
||||
MemAvailable: req.Memory.AvailableGB,
|
||||
MemSwapUsed: req.Memory.SwapUsedGB,
|
||||
DiskInfo: string(diskJSON),
|
||||
PortInfo: string(portJSON),
|
||||
NetInfo: string(netJSON),
|
||||
@@ -110,7 +113,7 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
|
||||
// 直接 SQL 更新 asset_servers 监控字段
|
||||
// 若 AgentVersion 非空则同步写入,否则保留数据库中已有版本号(防止旧版Agent空字段覆盖已设置的版本)
|
||||
updateSQL := `UPDATE asset_servers SET
|
||||
cpu_usage = ?, memory_usage = ?, disk_usage = ?,
|
||||
cpu_usage = ?, cpu_iowait = ?, memory_usage = ?, disk_usage = ?,
|
||||
cpu = ?, memory = ?, disk = ?,
|
||||
status = ?, agent_status = ?` + func() string {
|
||||
if req.AgentVersion != "" {
|
||||
@@ -121,7 +124,7 @@ func (h *AgentHandler) ReceiveReport(c *gin.Context) {
|
||||
hostname = CASE WHEN hostname != ? AND ip = ? THEN ? ELSE hostname END,
|
||||
updated_at = NOW()`
|
||||
args := []interface{}{
|
||||
req.CPU.UsagePercent, req.Memory.UsagePercent, diskAvg,
|
||||
req.CPU.UsagePercent, req.CPU.IOWait, req.Memory.UsagePercent, diskAvg,
|
||||
req.CPU.CoreCount, memMB, diskGB,
|
||||
"running", "online",
|
||||
}
|
||||
@@ -528,3 +531,94 @@ func avgDiskUsage(disks []models.DiskMetric) float64 {
|
||||
}
|
||||
return math.Round(sum/float64(len(disks))*100) / 100
|
||||
}
|
||||
|
||||
// ── 端口监控策略 ── // Logan.Li
|
||||
|
||||
// GetPortPolicyForAgent Agent 拉取本机端口策略(无需鉴权,通过 hostname 查询)
|
||||
// GET /api/v1/agent/port-policy?hostname=xxx
|
||||
func (h *AgentHandler) GetPortPolicyForAgent(c *gin.Context) {
|
||||
hostname := c.Query("hostname")
|
||||
if hostname == "" {
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "success", Data: models.AgentPortPolicyDTO{
|
||||
PortFilterMode: "blacklist",
|
||||
PortWhitelist: []int{},
|
||||
}})
|
||||
return
|
||||
}
|
||||
|
||||
var policy models.AgentPortPolicy
|
||||
if err := h.db.Where("hostname = ?", hostname).First(&policy).Error; err != nil {
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "success", Data: models.AgentPortPolicyDTO{
|
||||
Hostname: hostname,
|
||||
PortFilterMode: "blacklist",
|
||||
PortWhitelist: []int{},
|
||||
}})
|
||||
return
|
||||
}
|
||||
|
||||
var whitelist []int
|
||||
json.Unmarshal([]byte(policy.PortWhitelist), &whitelist)
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "success", Data: models.AgentPortPolicyDTO{
|
||||
Hostname: policy.Hostname,
|
||||
PortFilterMode: policy.PortFilterMode,
|
||||
PortWhitelist: whitelist,
|
||||
}})
|
||||
}
|
||||
|
||||
// GetPortPolicy 前端获取主机的端口监控策略
|
||||
// GET /api/v1/agent/port-policies/:hostname
|
||||
func (h *AgentHandler) GetPortPolicy(c *gin.Context) {
|
||||
hostname := c.Param("hostname")
|
||||
|
||||
var policy models.AgentPortPolicy
|
||||
var whitelist []int
|
||||
if err := h.db.Where("hostname = ?", hostname).First(&policy).Error; err != nil {
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "success", Data: models.AgentPortPolicyDTO{
|
||||
Hostname: hostname,
|
||||
PortFilterMode: "blacklist",
|
||||
PortWhitelist: []int{},
|
||||
}})
|
||||
return
|
||||
}
|
||||
|
||||
json.Unmarshal([]byte(policy.PortWhitelist), &whitelist)
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "success", Data: models.AgentPortPolicyDTO{
|
||||
Hostname: policy.Hostname,
|
||||
PortFilterMode: policy.PortFilterMode,
|
||||
PortWhitelist: whitelist,
|
||||
}})
|
||||
}
|
||||
|
||||
// SavePortPolicy 更新/创建主机的端口监控策略
|
||||
// PUT /api/v1/agent/port-policies/:hostname
|
||||
func (h *AgentHandler) SavePortPolicy(c *gin.Context) {
|
||||
hostname := c.Param("hostname")
|
||||
|
||||
var dto models.AgentPortPolicyDTO
|
||||
if err := c.ShouldBindJSON(&dto); err != nil {
|
||||
c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "请求格式错误: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
whitelistJSON := "[]"
|
||||
if len(dto.PortWhitelist) > 0 {
|
||||
b, _ := json.Marshal(dto.PortWhitelist)
|
||||
whitelistJSON = string(b)
|
||||
}
|
||||
|
||||
policy := models.AgentPortPolicy{
|
||||
Hostname: hostname,
|
||||
PortFilterMode: dto.PortFilterMode,
|
||||
PortWhitelist: whitelistJSON,
|
||||
}
|
||||
|
||||
if err := h.db.Where(models.AgentPortPolicy{Hostname: hostname}).
|
||||
Assign(policy).
|
||||
FirstOrCreate(&policy).Error; err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.Response{Code: 500, Message: "保存失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{Code: 200, Message: "端口策略已保存"})
|
||||
}
|
||||
Reference in new issue
Block a user