Files
aiops/backend/controller/agent_cli_kubernetes.go
2026-07-09 14:16:56 +08:00

112 lines
3.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// agent_cli_kubernetes.go - Agent CLI Kubernetes 模式 WebSocket 支持 // Logan.Li
package controller
import (
"fmt"
"strings"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"ezops/model"
k8sclient "ezops/pkg/kubernetesclient"
)
// kubernetesAgentContext Kubernetes 模式运行上下文 // Logan.Li
type kubernetesAgentContext struct {
cluster model.KubernetesCluster
client *k8sclient.Client
namespace string
podName string
container string
}
// parseKubernetesWSParams 从 WS 查询参数解析 Kubernetes 目标 // Logan.Li
func parseKubernetesWSParams(c *gin.Context) (clusterCode, namespace, podName, container string) {
clusterCode = strings.TrimSpace(c.Query("cluster"))
namespace = strings.TrimSpace(c.Query("namespace"))
podName = strings.TrimSpace(c.Query("pod"))
container = strings.TrimSpace(c.Query("container"))
return
}
// loadKubernetesAgentContext 加载集群客户端并预检 // Logan.Li
func loadKubernetesAgentContext(db *gorm.DB, clusterCode, namespace, podName string) (*kubernetesAgentContext, error) {
if clusterCode == "" {
return nil, fmt.Errorf("缺少 cluster 参数")
}
if namespace == "" {
return nil, fmt.Errorf("缺少 namespace 参数")
}
var cluster model.KubernetesCluster
if err := db.Where("code = ?", clusterCode).First(&cluster).Error; err != nil {
return nil, fmt.Errorf("集群不存在: %s", clusterCode)
}
client, err := buildK8sClient(&cluster)
if err != nil {
return nil, fmt.Errorf("集群连接失败: %w", err)
}
if _, err := client.ListNamespaces(); err != nil {
return nil, fmt.Errorf("集群 API 不可达: %w", err)
}
if podName != "" {
pods, err := client.ListPods()
if err != nil {
return nil, fmt.Errorf("获取 Pod 列表失败: %w", err)
}
found := false
for _, p := range pods.Items {
if p.Metadata.Namespace == namespace && p.Metadata.Name == podName {
found = true
break
}
}
if !found {
return nil, fmt.Errorf("Pod %s/%s 不存在", namespace, podName)
}
}
return &kubernetesAgentContext{
cluster: cluster, client: client,
namespace: namespace, podName: podName,
}, nil
}
// buildKubernetesTargetInfo 构建注入 Prompt 的集群上下文摘要 // Logan.Li
func buildKubernetesTargetInfo(ctx *kubernetesAgentContext) string {
var sb strings.Builder
sb.WriteString(fmt.Sprintf("集群: %s(code=%s)| Namespace: %s", ctx.cluster.Name, ctx.cluster.Code, ctx.namespace))
if ctx.podName != "" {
sb.WriteString(fmt.Sprintf(" | Pod: %s", ctx.podName))
if pods, err := ctx.client.ListPods(); err == nil {
for _, p := range pods.Items {
if p.Metadata.Namespace == ctx.namespace && p.Metadata.Name == ctx.podName {
image := ""
if len(p.Spec.Containers) > 0 {
image = p.Spec.Containers[0].Image
if ctx.container == "" {
ctx.container = p.Spec.Containers[0].Name
}
}
sb.WriteString(fmt.Sprintf(" | 状态: %s | 节点: %s | 镜像: %s", p.Status.Phase, p.Spec.NodeName, image))
break
}
}
}
} else {
sb.WriteString(" | Pod: (未选定,集群/命名空间级任务)")
}
if ctx.container != "" {
sb.WriteString(fmt.Sprintf(" | 容器: %s", ctx.container))
}
return sb.String()
}
// kubernetesEvolveHostKey Evolver 记忆分桶键 // Logan.Li
func kubernetesEvolveHostKey(ctx *kubernetesAgentContext) string {
base := fmt.Sprintf("kubernetes://%s/%s", ctx.cluster.Code, ctx.namespace)
if ctx.podName != "" {
return base + "/" + ctx.podName
}
return base
}