Files
Logan.Li fd60361d93 chore: 统一本地服务器与远程仓库源码
- 合并 main 与 master 历史并以服务器结构为基线
- 保留迁移、数据保留、AWS 账单与部署安全能力
- 建立 SDD 规格和 CI 验证闭环
2026-08-05 20:03:25 +08:00

375 lines
17 KiB
Markdown
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.
# CLAUDE.md — AIOps
本文档为 Claude Code / Hermes 等 AI 编程助手提供在代码库中工作的指导说明。
> 作者:Logan.Li
> 语言:中文(代码注释和文档主要使用中文,注释署名 `// Logan.Li`)
## 规格驱动开发(SDD)
本仓库强制使用 SDD 管理行为变更。开始编码前先按 `docs/specs/README.md` 判定变更级别并完成对应规格;S2/S3 变更使用 `docs/specs/_template.md` 创建规格文件。
执行顺序固定为:**Discover → Specify → Design → Implement → Verify → Deliver**。
- S0:纯文案、格式和无行为变化的机械修改,可不建规格文件。
- S1:局部修复或单模块小改动,任务计划中必须包含问题、约束和可验证验收标准。
- S2:新功能、跨模块流程、API、配置或数据模型变更,必须先落盘规格。
- S3:认证、账单、安全、迁移、清理和生产部署,在 S2 基础上必须提供风险、兼容、可观测、发布和回滚方案。
硬性要求:
1. 规格中的验收标准使用稳定编号 `AC-01`,每条必须映射到测试或人工验证证据。
2. API 先定义请求、响应、错误码和权限;数据库先定义版本化迁移、兼容和回滚;前后端不得各自猜测契约。
3. 实现与规格冲突时先更新规格再编码,禁止静默偏离或夹带范围外重构。
4. 金额明确币种/汇率/精度,时间明确时区/窗口,敏感操作明确权限/审计/失败路径,高频数据明确保留与清理策略。
5. 交付必须报告验证命令、结果、未覆盖项和剩余风险。验收未闭环时不得宣称完成。
`AGENTS.md` 保存完整项目约束;`docs/specs/README.md` 是 SDD 流程的唯一权威来源。若本文与权威规范冲突,以后者为准。
## 项目概述
**AIOps** 是一个企业级智能运维平台,聚焦三大核心能力:
1. **资产管理** — 服务器管理、云资源(云账号/域名/账单)、K8s 集群
2. **监控告警** — Agent 采集指标、告警引擎(资源阈值/离线检测)、告警中心、链路追踪、监控大屏
3. **自动化运维 / AIOps** — 流水线 CI/CD、定时任务/脚本库、远程执行(Go-native SSH)、资源申请审批、AI 智能运维(智能助手/告警分析/容量预测/Agent CLI)
### 核心特性
- **Agent 双通道** — 指标采集通道(10s 上报 `/proc`)+ 远程任务通道(5s 轮询执行命令)
- **LDAP 集成** — 配置管理、用户导入、OU 管理、LDAP 用户 CRUD
- **资源申请审批** — 云服务器申请、应用部署申请,动态表单
- **5 套主题** — CSS 变量驱动,暗色/亮色/紫色/绿色/玫红一键切换
- **WebShell** — WebSocket 终端,在线 SSH 操作服务器
- **凭证系统 v2** — 7 种统一凭证类型(SSH/Docker/TLS/AKSK/DB/API/Generic),加密存储
- **CI/CD 流水线** — GitLab CI 风格可视化,阶段色块进度条,实时日志,文件浏览器
- **Kubectl 终端** — WebSocket + PTY 交互式 K8s 终端,懒加载 kubectl 二进制
- **Agent CLI** — Web 版 AI 运维 Agent(参考 opsxcli 移植),关联主机后自然语言驱动 SSH 排障/部署,ReAct 循环解决错误,WebSocket 实时回传,Evolver 自进化学习
## 技术栈
| 层 | 技术 | 端口 |
|---|---|---|
| 后端 | Go 1.25 + Gin + GORM + MySQL 8.0 + Redis 7 + JWT + Zap | 8080 |
| 前端 | React 19 + TypeScript + Vite + Tailwind + shadcn/ui + Zustand + TanStack Query | 5173 |
| Agent | Go 1.22 模块(Go 1.25 工具链,CGO_ENABLED=0 静态二进制, amd64+arm64) | — |
## 三种部署方式
项目通过统一入口 `./run.sh` 支持三种部署方式,适配不同场景:
### 方式一:独立二进制(`./run.sh build` / `./run.sh binary`)
前端通过 `go:embed` 嵌入后端二进制,生成单一可执行文件。零外部依赖,直接运行。
```bash
./run.sh build # 编译独立二进制 → backend/aiops
./run.sh binary # 编译 + 直接启动
./run.sh build agent # 交叉编译 Agent (amd64+arm64)
```
**二进制用法:**
```bash
./backend/aiops # 默认启动 (SQLite, 端口 8080)
./backend/aiops --port 9090 # 自定义端口
./backend/aiops --db-driver mysql --db-host 10.10.10.75 ... # MySQL 模式(需 --redis-driver redis)
./backend/aiops --config config.yaml # 使用配置文件
```
> ⚠️ MySQL 模式必须显式传 `--redis-driver redis`,否则默认 redka(CGO 依赖)在 `CGO_ENABLED=0` 下静默失败。
### 方式二:Kubernetes(`./run.sh k8s deploy`)
在 K8s 集群 `devops` 命名空间部署,单容器 embed 模式,NodePort 30080 暴露。
```bash
./run.sh k8s deploy # 构建 Dockerfile 镜像 + 全量部署 (MySQL+Redis+App)
./run.sh k8s upgrade # 重新构建 + 滚动更新(不停机)
./run.sh k8s status # 查看 pods/svc/pvc/ingress
./run.sh k8s logs # 应用日志 (follow)
./run.sh k8s exec # 进入容器 Shell
./run.sh k8s mysql # MySQL CLI
./run.sh k8s redis # Redis CLI
./run.sh k8s scale 3 # 扩缩容
./run.sh k8s port-forward # 端口转发 localhost:8080 → svc/aiops
./run.sh k8s delete # 清理资源(保留 PVC)
```
**K8s 部署文件** (`deploy/kubernetes/`): namespace.yaml / secret.yaml / configmap.yaml / mysql.yaml / redis.yaml / deployment.yaml / ingress.yaml / quick-deploy.yaml
> ⚠️ 健康检查用 `/version`(无 DB 依赖),不用 `/health`(启动早期可能不响应)。
### 方式三:Docker Compose(`./run.sh docker up`)
3 容器部署:`aiops` + `aiops-mysql` + `aiops-redis`。前端由后端 embed 服务,单端口 8080。
```bash
./run.sh docker up # 构建 + 启动全部容器
./run.sh docker down # 停止 + 移除容器
./run.sh docker build # 仅构建镜像
./run.sh docker restart # 重启容器
./run.sh docker logs # 实时日志
./run.sh docker ps # 容器状态
./run.sh docker clean # 清理构建缓存
```
**容器清单:**
| 容器 | 镜像 | 端口 | 说明 |
|------|------|------|------|
| `aiops` | `Dockerfile` (3-stage) | 8080 | Go API + embed 前端 |
| `aiops-mysql` | `mysql:8.0` | 3306 | 数据库 |
| `aiops-redis` | `redis:7-alpine` | 6379 | 缓存 |
### 本地开发(`./run.sh dev`)
```bash
./run.sh dev # 前后端热重载 (5173 + 8080)
./run.sh stop # 停止
./run.sh restart # 重启
./run.sh status # 查看状态
./run.sh logs # 实时日志
```
## 常用命令
### 后端 (backend/)
```bash
cd backend
# 编译
unset http_proxy https_proxy && export GOPROXY=https://goproxy.cn,direct && GOTOOLCHAIN=auto CGO_ENABLED=1 go build -o aiops .
# 直接运行
go run .
# 代码检查
go vet ./...
```
### 前端 (frontend/)
```bash
cd frontend
npm run dev # 开发服务器 (端口 5173)
npm run build # 生产构建
npx tsc --noEmit # 类型检查(提交前必须零错误)
```
### Agent (agent/)
```bash
cd agent
# 本地构建
CGO_ENABLED=0 go build -o aiops-agent .
# 交叉编译
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o aiops-agent-linux-amd64 .
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o aiops-agent-linux-arm64 .
# 运行
./aiops-agent --server http://localhost:8080 --token <JWT_TOKEN>
```
## 架构说明
### 项目结构
```
aiops/
├── backend/
│ ├── main.go # 应用入口
│ ├── embed.go # go:embed 前端静态资源
│ ├── seed.go # 种子数据
│ ├── static/ # embed 目标目录 (必须存在)
│ ├── config/config.go # Viper 配置
│ ├── controller/ # HTTP handler(60+ 文件按领域拆分)
│ ├── model/ # GORM 模型(30 文件 86+ 表)
│ ├── dto/ # 请求/响应 DTO
│ ├── service/ # 业务逻辑层
│ ├── repository/ # 数据访问层
│ ├── router/routes.go # 路由注册(~1000 行)
│ ├── middleware/ # JWT + Admin + PipelineAccess
│ ├── seed/ # 种子数据(默认账号、菜单等)
│ ├── pkg/
│ │ ├── database/ # DB 连接 + AutoMigrate
│ │ ├── kubernetesclient/ # 轻量 K8s API 客户端
│ │ ├── remoteexec/ # Go-native SSH 远程执行
│ │ ├── agentcli/ # AI 运维 Agent 引擎(ReAct + 工具 + 安全 + Evolver)
│ │ ├── toolinstaller/ # 工具懒加载 + 镜像回退
│ │ ├── logger/ # Zap 日志
│ │ ├── redis/ # Redis 连接
│ │ └── wshub/ # WebSocket Hub
│ └── Dockerfile # 3 阶段构建 (Frontend→Backend+Agent→Alpine Runtime)
│
├── frontend/
│ ├── src/components/
│ │ ├── dashboard/ # 仪表盘
│ │ ├── server/ # 服务器管理
│ │ ├── cloud/ # 云资源
│ │ ├── k8s/ # K8s 集群管理
│ │ ├── deploy/ # 应用发布(流水线/发布配置/发布权限/工具配置)
│ │ ├── monitor/ # 监控告警(含 log-center 日志中心)
│ │ ├── automation/ # 定时任务/脚本库/远程执行
│ │ ├── approval/ # 资源申请审批
│ │ ├── aiops/ # AI 智能运维(助手/告警分析/容量预测/Agent CLI/大模型设置)
│ │ ├── system/ # 系统管理
│ │ └── layout/ # Sidebar/Header
│ ├── src/api/
│ │ └── monitor/log-center.ts # 日志中心 API(Loki/ES 代理查询)
│ ├── src/i18n/ # 国际化框架 (i18next)
│ ├── src/locales/ # 翻译文件 (zh-CN / en-US)
│ └── Dockerfile # Node build → nginx:alpine
│
├── agent/ # 监控 Agent(独立 Go module)
│ ├── collector/ # /proc 采集器
│ ├── task/ # 远程任务执行器
│ └── reporter/ # HTTP 上报
│
├── deploy/kubernetes/ # K8s 部署清单 (devops 命名空间)
├── Dockerfile # 4 阶段 Embed 镜像 (前端→后端→Agent→Runtime)
├── docker-compose.yml # 4 容器部署 (mysql+redis+backend+frontend)
├── run.sh # 统一入口脚本
└── Makefile # 快捷命令
```
### API 响应格式
```go
// 统一响应
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}
// 列表响应
type ListResponse struct {
List interface{} `json:"list"`
Total int64 `json:"total"`
}
```
**前端 http.ts 已自动提取 `.data`**,组件中拿到的就是 `Response.Data`。列表返回 `{list, total}`。
### 认证流程
```
Login(本地/LDAP fallback) → JWT Token → 前端 Zustand persist + localStorage 双写
→ http.ts 自动注入 Bearer → JWTAuth 中间件 → AdminAuth 中间件(管理类路由)
```
WebSocket 无法设自定义 header → 后端 JWTAuth 支持 `?token=` query param 回退。
### Agent 双通道架构
```
指标通道: ticker(10s) → collect(/proc) → POST /agent/report
任务通道: ticker(5s) → GET /agent/tasks/poll → execute → POST /agent/tasks/:id/result
```
## 开发规范
### ⛔ 文件大小红线
| 类型 | 上限 | 超出处理 |
|------|------|----------|
| Go handler | **400 行** | 按 sub-domain 拆分 |
| Go model | **300 行** | 按模块拆分 |
| React 组件 (.tsx) | **700 行** | 提取子组件 |
| 任何文件 | **700 行(硬上限)** | 必须拆分 |
### ⛔ Go 代码规范
1. **所有 handler 返回必须用 `models.Response{Code:200, Data:...}` 包裹**
2. **编译命令**: `unset proxy + GOPROXY=goproxy.cn + GOTOOLCHAIN=auto + CGO_ENABLED=1`
3. **新增 handler 不绑 model** — 用独立 request struct
4. **GORM 指针字段必须解引用** — `*field` 后再用
5. **Update handler 禁止复用 CreateRequest** — 用 `map[string]interface{}` 接收
6. **高频数据必须有保留策略** — 监控、Agent 上报、日志和审计数据必须可配置保留期、定时清理并记录影响行数和任务结果;不能无限累积。
7. **SQLite 清理必须回收文件空间** — `DELETE` 后文件不会自动变小。备份成功且应用停写的维护窗口内,执行 `PRAGMA wal_checkpoint(TRUNCATE)` 与 `VACUUM`,并验证主库/WAL 体积;高峰期禁止 `VACUUM`。
8. **避免启动期重建大表** — SQLite 下 GORM `AutoMigrate` 可能通过重建表完成结构变更并放大 WAL 写入;大表结构变更必须可追踪、幂等,不得每次启动无条件重建。
### ⛔ React 前端规范
1. **API 列表响应解包** — `http.ts` 自动取 `.data`,列表返回 `{list, total}`
2. **禁止 `window.confirm()`/`alert()`** — 用 `useConfirm()` + `toast`
3. **Radix Dialog 必须有 `<DialogDescription>`**
4. **Token 双保险**: `useUserStore.getState().token || localStorage.getItem('token')`
5. **图标分层**:操作、状态和导航使用 `lucide-react`;云厂商、CI/CD、监控和中间件等产品实体使用本地 `TechnologyBrandIcon` 或 `CloudBrandIcon`。
6. **品牌图标本地化**:技术品牌图标统一从 `simple-icons` 按需导入,禁止使用 jsDelivr、CDN 或远程图片 URL;云厂商缺失图标使用仓库本地 SVG 或官方资源。
### ⛔ UI 设计原则
- **能去掉的都去掉** — 不要多余边框、装饰线
- **按钮文案 2-4 字** — "批量导入" 而非 "批量导入用户"
- **不留占位按钮** — 功能没做好就不放按钮
- **页面打开即用** — 不需要额外"新建"按钮跳转
- **主题感知** — 用 CSS 变量 `var(--dg-xxx)`,不硬编码颜色
### ⛔ 通用开发流程
```
分析需求 → 写代码 → go build + tsc --noEmit → ./run.sh docker up → curl 验证 → git commit + push
```
- **代码改完不算完成,端到端验证通过才算完成**
- **大变更前先 git commit** — 方便回滚
## 默认账号
| 用户名 | 密码 | 角色 |
|--------|------|------|
| admin | 123456 | 超级管理员 |
| ops01 | 123456 | 运维 |
| dev01 | 123456 | 开发 |
| logan | zxc987 | LDAP 用户 |
⚠️ **生产环境请修改默认密码**
## 访问地址
- 前端:`http://localhost:5173` (dev) / `http://localhost:8080` (docker / binary)
- 后端:`http://localhost:8080`
- 健康检查:`http://localhost:8080/version` (推荐) / `http://localhost:8080/health`
- K8s:`http://<NODE_IP>:30080`
## 常见陷阱速查
| # | 陷阱 | 解决 |
|---|------|------|
| Go1 | go build 超时 | `unset proxy + GOPROXY=goproxy.cn + GOTOOLCHAIN=auto` |
| Go2 | handler 不包裹 Response | 必须 `models.Response{Code:200, Data:...}` |
| Go3 | GORM 指针字段 | `*field` 解引用后再用 |
| Go4 | Update 复用 CreateRequest | 用 `map[string]interface{}` |
| Go5 | CGO_ENABLED=0 + redka → 缓存静默失败 | `--redis-driver redis` |
| FE1 | 白屏无堆栈 | 90% 是列表 `{list,total}` 未解包 |
| FE2 | confirm() 冻结自动化 | 用 `useConfirm()` |
| FE3 | Token 获取 | `useUserStore.getState().token` + `localStorage` |
| FE4 | Radix Dialog 警告 | 必须有 `<DialogDescription>` |
| FE5 | Select.Item 空字符串 value | 用 sentinel 值 `__manual` |
| FE6 | API 字段名不匹配 | 检查前后端命名一致性 |
## 注释规范
新增或修改代码必须写中文注释,注释结尾署名 `// Logan.Li`。
## 远程仓库
```
https://gitee.com/attacker/aiops.git
Git 用户: attacker / attacker@gitee.com
分支: master
```
## 关键设计决策
- **凭证驱动管理** — 不在表单手动输入密码/密钥,用凭证下拉关联(7 种类型统一模型)
- **工具懒加载** — kubectl/maven/nodejs/helm 首次使用时自动下载,国内网络自动优先国内镜像
- **远程执行** — Ansible 已替换为 Go-native SSH(`pkg/remoteexec/`),零新增依赖
- **K8s 客户端** — 轻量自研(net/http + crypto/tls),不引入 50MB+ 的 client-go
- **BuildKit cache mount** — Docker 构建从 13min 降至 3sec(二次构建)
- **健康检查用 `/version`** — K8s 中 `/health` 可能依赖 DB,`/version` 始终 200
- **Agent CLI 引擎** — AIOps 原生 Web 智能运维 Agent,核心在 `pkg/agentcli/`(纯引擎库,零业务依赖):ReAct 16 轮循环 + 自适应检查点 + 循环检测;主机工具 `ssh_execute` / `analyze_output`,Kubernetes 工具 `kubernetes_get` / `pod_logs` / `pod_execute` / `kubernetes_action`;Evolver 记忆异步学习并注入下次 Prompt;会话用 GORM 表(`agent_cli_sessions/messages`)多用户隔离;高危命令经 WebSocket `confirm` 事件确认;设计文档见 `docs/ai-agent/`