 tao.chenandClaude
|
be4ca460c9
|
Phase 5 Batch 1 (补): mcp/server + 2 Tool (Batch 1 commit 时漏 stage)
上一个 commit (7056657) 漏 add 的 mcp 包文件:
- internal/mcp/server.go (Streamable HTTP Handler)
- internal/mcp/tools/list_clusters.go (发现入口)
- internal/mcp/tools/spark_submit.go (本地 exec 提交)
- internal/mcp/tools/helpers.go (textResult/errResult/encodeJSON)
deps.go / rm.go 已在 Phase 5 Batch 2 一起 commit, 此处不重复。
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-07-10 17:24:10 +08:00 |
|
 tao.chenandClaude
|
e6411b0dc4
|
Phase 5 Batch 4: analyzer 规则引擎 + 3 个高层 Tool
- internal/analyzer: 纯函数规则引擎
- Finding / Severity / Thresholds / Input / StageMetric / ExecutorMetric
- 3 规则: data_skew (max/min ratio), gc_pressure (GC/CPU ratio),
bottleneck (shuffle read+write GB)
- 严重度阶梯: warning / critical (阈值 ×2)
- Analyze 入口数据驱动 for ... range
- 11 个单测 (3 规则 × normal/warning/critical + 零除防御)
- fetch_spark_metrics: SHS 业务封装, format=summary 触发 analyzer
- fetch_cluster_env: RM /cluster/info + /cluster/metrics 聚合
- analyze_spark_log: RM 日志降级链 + LLM-Ready Prompt 拼装
- prompt 结构: cluster 元信息 + log source + log tail +
heuristic findings + suggested LLM analysis
- findings 是 first-pass filter, LLM 做最终判断
- deps.go: +AnalyzerThresholds
- main.go: 注入 cfg 的 3 个阈值
- 端到端实测: analyze_spark_log 完整 prompt 渲染
完成 11 个 Tool 表面 (list_clusters / spark_submit / 4 RM /
fetch_spark_metrics / fetch_cluster_env / analyze_spark_log /
fetch_url / upload_file)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-07-10 16:53:47 +08:00 |
|
 tao.chenandClaude
|
d4ad97f595
|
Phase 5 Batch 3: fetch_url + upload_file Tool (底层原语)
- fetch_url: 通用 HTTP 原语
- host allowlist 校验 (cluster.URLAllowlist + RM/SHS host 兜底)
- 复用 httpclient.ApplyAuth + DoWithRedirect
- mcp.WithEnum 约束 method
- 单元测试: 9 子测试 (basic auth 透传 + 跨主机 redirect 保留 auth)
- upload_file: 本地文件存储 (供 spark_submit 引用)
- filename sanitize: [a-zA-Z0-9._-], 拒绝路径逃逸
- filepath.Base 二次校验
- 写到 <DataDir>/uploads/<name>, 权限 0640
- 单元测试: 路径遍历全部拒绝
- deps.go: +DataDir
- main.go: 注入 cfg.DataDir
- 端到端实测: upload_file + spark_submit 引用上传脚本
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-07-10 16:52:10 +08:00 |
|
 tao.chenandClaude
|
c4ac3cc354
|
Phase 5 Batch 2: 4 RM Tool + rm 客户端 + 日志降级链
- internal/rm/client.go: YARN RM 客户端
- ListApps / GetApp / KillApp / GetLogs
- GetLogs 降级链数据驱动 (amContainerLogs → aggregated-logs → logs)
- 跨主机 redirect 保留 Authorization (URLAllowlist 兜底)
- 4 Tool: list_applications / get_application_status /
get_application_logs / kill_application
- mcp.WithEnum(state) 约束 YARN app 状态
- tool handler 永远 (result, nil), 业务错误用 NewToolResultError
- deps.go: +HTTPClient + MaxResponseBytes
- main.go: 注入 httpclient.Client
- 端到端实测: mock RM 验证 4 Tool + 降级链 + 错误路径
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-07-10 16:50:27 +08:00 |
|
 tao.chenandClaude
|
705665745e
|
Phase 5 Batch 1: executor + list_clusters + spark_submit + /mcp 路由
- internal/executor: spark-submit 进程执行, exec.Command 切片形式
(绝不 shell) + stdout 10MiB tail-cap + app_id regex
+ 5 个单测覆盖 slice-form 注入防御 + 退出码
- internal/mcp/server.go: NewServer + Streamable HTTP Handler
- internal/mcp/tools/{list_clusters, spark_submit, deps, helpers}.go
- mcp-go API 实测修正: WithArray 用 Items() 声明 item 类型;
StreamableHTTPServer 直接实现 http.Handler, 无 .Handler() 方法
- main.go: 挂 /mcp 路由 (AgentAuth + mcpHandler 手动组合)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-07-10 16:50:02 +08:00 |
|
 tao.chenandClaude
|
2c39091706
|
Phase 3+4: 共享 HTTP 客户端 + admin API + audit log
Phase 3 (httpclient):
- shared Client (Timeout + MaxResponseBytes 截断)
- SSRF: 16 段私网 CIDR (含 169.254/::ffff:0:0/96 IPv4-mapped)
+ hostname allowlist (精确/后缀/*. 通配)
+ scheme 校验 (仅 http/https)
- auth 适配器: none / simple (YARN user.name) / basic (SetBasicAuth)
- DoWithRedirect: 跨主机跳转保留 Authorization, max 5 默认
- 19 个测试全绿 (httptest 模拟)
Phase 4 (admin + audit):
- internal/audit: Entry + Repo.Insert/List + MarshalDetails, snake_case JSON
- internal/middleware: AdminAuth/AgentAuth (constant-time 比对)
- internal/admin: 6 端点 (GET/POST/PUT/DELETE /admin/clusters, GET /admin/audit)
+ 写操作触发 audit_log (含 before/after diff)
+ AuthPassword 空=保留旧密码
+ 校验: 必填字段 + auth_type 枚举 + rate_limit>=0
- main.go: 挂载 storage.Open + admin.Mount
- L fix: audit.Entry 加 json tag (smoke test 发现大写 key 不规范)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-07-10 13:54:24 +08:00 |
|
 tao.chenandClaude
|
a4e2472716
|
Phase 0+1+2 续: 项目骨架 + 配置 + 日志 + 存储层
Phase 0 (项目骨架):
- main.go 改为最小骨架 (config + logging + gin + /healthz + 优雅退出)
- internal/{config,logging,storage,cluster,...}/ 目录占位
Phase 1 (配置 + 日志):
- internal/config: env 解析 + 必填校验 + token 隐藏的 String()
- internal/logging: slog multi-handler 双输出 (终端 text + 主文件 JSON)
+ StartToolCall per-tool 独立文件 (0600), tools 目录 0700
Phase 2 续 (存储层):
- internal/cluster: 16 字段 Cluster struct (AuthPassword json:"-")
- internal/storage: modernc.org/sqlite 接入, WAL 模式, schema 自动迁移
- ClusterRepo CRUD: Create/Get/List/Update/Delete + ErrNotFound
+ AuthPassword 空字符串 = 保留旧密码 (核心约定)
- 7 个单元测试全绿 (:memory: DB)
- created_at/updated_at 改纳秒精度, 消除 List 测试的 sleep 特殊 case
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-07-10 12:12:53 +08:00 |
|
tao.chen
|
1dfef0f598
|
init
|
2026-07-10 10:19:28 +08:00 |
|