// K8s 集群列表统计增强 — 实时拉取资源数量,修复 Ingress 等与详情页不一致 // Logan.Li package controller import ( "log" "ezops/model" ) // enrichClustersForList 列表返回前刷新资源计数与节点均值使用率 // Logan.Li func (h *KubernetesHandler) enrichClustersForList(clusters []model.KubernetesCluster) { for i := range clusters { c := &clusters[i] h.fillClusterCountsFromDB(c) h.refreshClusterCountsLive(c) h.fillClusterUsageFromNodes(c) // 异步落库,避免列表阻塞过久 snap := *c go func(cluster model.KubernetesCluster) { if err := h.db.Model(&model.KubernetesCluster{}).Where("id = ?", cluster.ID).Updates(map[string]interface{}{ "node_count": cluster.NodeCount, "pod_count": cluster.PodCount, "service_count": cluster.ServiceCount, "deployment_count": cluster.DeploymentCount, "ingress_count": cluster.IngressCount, "cpu_usage": cluster.CPUUsage, "memory_usage": cluster.MemoryUsage, }).Error; err != nil { log.Printf("[K8s] enrich cluster %d stats persist error: %v", cluster.ID, err) } }(snap) } } func (h *KubernetesHandler) fillClusterCountsFromDB(c *model.KubernetesCluster) { var nodes, pods, svcs, deps, ings int64 h.db.Model(&model.KubernetesNode{}).Where("cluster_id = ?", c.ID).Count(&nodes) h.db.Model(&model.KubernetesPod{}).Where("cluster_id = ?", c.ID).Count(&pods) h.db.Model(&model.KubernetesService{}).Where("cluster_id = ?", c.ID).Count(&svcs) h.db.Model(&model.KubernetesDeployment{}).Where("cluster_id = ?", c.ID).Count(&deps) h.db.Model(&model.KubernetesIngress{}).Where("cluster_id = ?", c.ID).Count(&ings) if nodes > 0 { c.NodeCount = int(nodes) } if pods > 0 { c.PodCount = int(pods) } if svcs > 0 { c.ServiceCount = int(svcs) } if deps > 0 { c.DeploymentCount = int(deps) } if ings > 0 { c.IngressCount = int(ings) } } func (h *KubernetesHandler) refreshClusterCountsLive(c *model.KubernetesCluster) { client, err := buildK8sClient(c) if err != nil { return } if nodes, err := client.ListNodes(); err == nil { c.NodeCount = len(nodes.Items) } if pods, err := client.ListPods(); err == nil { c.PodCount = len(pods.Items) } if deps, err := client.ListDeployments(); err == nil { c.DeploymentCount = len(deps.Items) } if svcs, err := client.ListServices(); err == nil { c.ServiceCount = len(svcs.Items) } if ings, err := client.ListIngresses(); err == nil { c.IngressCount = len(ings.Items) } else { log.Printf("[K8s] list ingresses for cluster %s error: %v", c.Code, err) } } func (h *KubernetesHandler) fillClusterUsageFromNodes(c *model.KubernetesCluster) { var avgCPU, avgMem float64 row := h.db.Model(&model.KubernetesNode{}).Where("cluster_id = ?", c.ID). Select("COALESCE(AVG(cpu_usage), 0), COALESCE(AVG(memory_usage), 0)").Row() if row != nil { _ = row.Scan(&avgCPU, &avgMem) } if avgCPU > 0 { c.CPUUsage = avgCPU } if avgMem > 0 { c.MemoryUsage = avgMem } } // updateClusterUsageAfterSync 同步后根据节点指标写回集群 CPU/内存均值 // Logan.Li func (h *KubernetesHandler) updateClusterUsageAfterSync(clusterID uint) { var cluster model.KubernetesCluster cluster.ID = clusterID h.fillClusterUsageFromNodes(&cluster) if cluster.CPUUsage > 0 || cluster.MemoryUsage > 0 { h.db.Model(&model.KubernetesCluster{}).Where("id = ?", clusterID).Updates(map[string]interface{}{ "cpu_usage": cluster.CPUUsage, "memory_usage": cluster.MemoryUsage, }) } }