主要变更: - RDP 远程桌面:新增 backend/pkg/rdp(RDP 引擎 + credssp/display/rle/trace)、 backend/controller/rdp*(连接/凭证/文件/会话/实时)、frontend RDP 组件与 API - Windows SMB 文件传输:backend/pkg/winsmb - 云账单同步:backend/pkg/billingsync + billing_sync/aliyun_billing,前端账单详情 - Agent CLI Kubernetes 工具:kubernetes_action/get、pod_execute/logs - 服务器导入助手:server_import_helpers、ImportCredentialSettings - 国际化与组件重构(cloud/deploy/monitor/server/system 等多模块) - 清理编译产物二进制:移除 backend/server、backend/agent/bin/aiops-agent-* - .gitignore:新增 backend/agent/ 与 .cache/(避免 334MB go-build 缓存误入库) Co-Authored-By: Claude <noreply@anthropic.com>
131 lines
4.6 KiB
Go
131 lines
4.6 KiB
Go
// kubernetes_action.go - Kubernetes 集群变更操作(高风险,需用户确认) // Logan.Li
|
||
package tools
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"strings"
|
||
|
||
k8sclient "ezops/pkg/kubernetesclient"
|
||
)
|
||
|
||
// KubernetesActionTool 执行 Kubernetes 变更动作 // Logan.Li
|
||
type KubernetesActionTool struct {
|
||
client *k8sclient.Client
|
||
namespace string
|
||
}
|
||
|
||
// NewKubernetesActionTool 创建变更工具 // Logan.Li
|
||
func NewKubernetesActionTool(client *k8sclient.Client, namespace string) *KubernetesActionTool {
|
||
return &KubernetesActionTool{client: client, namespace: namespace}
|
||
}
|
||
|
||
// Name 工具名 // Logan.Li
|
||
func (t *KubernetesActionTool) Name() string { return "kubernetes_action" }
|
||
|
||
// Description 给 LLM 的说明 // Logan.Li
|
||
func (t *KubernetesActionTool) Description() string {
|
||
return "对 Kubernetes 资源执行变更操作(高风险,需用户确认)。" +
|
||
"action 支持: restart_deployment, scale_deployment, update_image, restart_statefulset, delete_pod, suspend_cronjob。" +
|
||
"变更前请先用 kubernetes_get 确认当前状态。"
|
||
}
|
||
|
||
// Parameters JSON Schema // Logan.Li
|
||
func (t *KubernetesActionTool) Parameters() map[string]interface{} {
|
||
return map[string]interface{}{
|
||
"type": "object",
|
||
"properties": map[string]interface{}{
|
||
"action": map[string]interface{}{
|
||
"type": "string",
|
||
"description": "操作类型: restart_deployment|scale_deployment|update_image|restart_statefulset|delete_pod|suspend_cronjob",
|
||
},
|
||
"namespace": map[string]interface{}{
|
||
"type": "string",
|
||
"description": "命名空间,默认会话绑定命名空间",
|
||
},
|
||
"name": map[string]interface{}{
|
||
"type": "string",
|
||
"description": "资源名称(Deployment/StatefulSet/CronJob/Pod)",
|
||
},
|
||
"replicas": map[string]interface{}{
|
||
"type": "integer",
|
||
"description": "scale_deployment 目标副本数",
|
||
},
|
||
"image": map[string]interface{}{
|
||
"type": "string",
|
||
"description": "update_image 新镜像地址",
|
||
},
|
||
"container": map[string]interface{}{
|
||
"type": "string",
|
||
"description": "update_image 目标容器名,可省略(默认第一个)",
|
||
},
|
||
"suspend": map[string]interface{}{
|
||
"type": "boolean",
|
||
"description": "suspend_cronjob: true=暂停, false=恢复",
|
||
},
|
||
},
|
||
"required": []string{"action", "name"},
|
||
}
|
||
}
|
||
|
||
// RiskLevel 静态高风险 // Logan.Li
|
||
func (t *KubernetesActionTool) RiskLevel() RiskLevel { return RiskHigh }
|
||
|
||
// Execute 执行变更 // Logan.Li
|
||
func (t *KubernetesActionTool) Execute(ctx context.Context, args map[string]interface{}) (*Result, error) {
|
||
action := strings.ToLower(strings.TrimSpace(StringParam(args, "action")))
|
||
name := strings.TrimSpace(StringParam(args, "name"))
|
||
ns := strings.TrimSpace(StringParam(args, "namespace"))
|
||
if ns == "" {
|
||
ns = t.namespace
|
||
}
|
||
if action == "" || name == "" {
|
||
return &Result{Success: false, Error: "action 和 name 不能为空"}, nil
|
||
}
|
||
|
||
var err error
|
||
var msg string
|
||
switch action {
|
||
case "restart_deployment":
|
||
err = t.client.RestartDeployment(ns, name)
|
||
msg = fmt.Sprintf("已触发 Deployment %s/%s 滚动重启", ns, name)
|
||
case "scale_deployment":
|
||
replicas := IntParam(args, "replicas")
|
||
if replicas < 0 {
|
||
return &Result{Success: false, Error: "replicas 不能为负数"}, nil
|
||
}
|
||
err = t.client.ScaleDeployment(ns, name, replicas)
|
||
msg = fmt.Sprintf("已将 Deployment %s/%s 扩缩容至 %d 副本", ns, name, replicas)
|
||
case "update_image":
|
||
image := strings.TrimSpace(StringParam(args, "image"))
|
||
if image == "" {
|
||
return &Result{Success: false, Error: "update_image 需要 image 参数"}, nil
|
||
}
|
||
container := strings.TrimSpace(StringParam(args, "container"))
|
||
err = t.client.UpdateDeploymentImage(ns, name, container, image)
|
||
msg = fmt.Sprintf("已更新 Deployment %s/%s 镜像为 %s", ns, name, image)
|
||
case "restart_statefulset":
|
||
err = t.client.RestartStatefulSet(ns, name)
|
||
msg = fmt.Sprintf("已触发 StatefulSet %s/%s 滚动重启", ns, name)
|
||
case "delete_pod":
|
||
err = t.client.DeletePod(ns, name)
|
||
msg = fmt.Sprintf("已删除 Pod %s/%s(控制器将视情况重建)", ns, name)
|
||
case "suspend_cronjob":
|
||
suspend := true
|
||
if v, ok := args["suspend"].(bool); ok {
|
||
suspend = v
|
||
}
|
||
err = t.client.SuspendCronJob(ns, name, suspend)
|
||
if suspend {
|
||
msg = fmt.Sprintf("已暂停 CronJob %s/%s", ns, name)
|
||
} else {
|
||
msg = fmt.Sprintf("已恢复 CronJob %s/%s", ns, name)
|
||
}
|
||
default:
|
||
return &Result{Success: false, Error: fmt.Sprintf("不支持的 action: %s", action)}, nil
|
||
}
|
||
if err != nil {
|
||
return &Result{Success: false, Error: fmt.Sprintf("操作失败: %v", err)}, nil
|
||
}
|
||
return &Result{Success: true, Output: msg}, nil
|
||
} |