2026-06-04 23:01:03 +08:00
|
|
|
|
# Nexus 6.0 — 功能开发指南(SSOT)
|
|
|
|
|
|
|
|
|
|
|
|
> **版本**: 2026-06-04
|
|
|
|
|
|
> **读者**: 接续开发工程师、AI Agent
|
|
|
|
|
|
> **定位**: 后续功能开发的**主参考文档**(比 handoff 更细、比 changelog 更稳)
|
|
|
|
|
|
> **关联**: [linux-dev-paths.md](linux-dev-paths.md) · [local-integration-test.md](local-integration-test.md) · [risk-acceptance-single-operator.md](risk-acceptance-single-operator.md)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 目录
|
|
|
|
|
|
|
|
|
|
|
|
1. [项目概述](#1-项目概述)
|
|
|
|
|
|
2. [技术栈与仓库结构](#2-技术栈与仓库结构)
|
|
|
|
|
|
3. [启动模式与配置](#3-启动模式与配置)
|
|
|
|
|
|
4. [架构分层与请求生命周期](#4-架构分层与请求生命周期)
|
|
|
|
|
|
5. [认证、会话与安全](#5-认证会话与安全)
|
|
|
|
|
|
6. [数据模型(19 表)](#6-数据模型19-表)
|
|
|
|
|
|
7. [Redis 与实时数据流](#7-redis-与实时数据流)
|
|
|
|
|
|
8. [后台任务(Primary Worker)](#8-后台任务primary-worker)
|
|
|
|
|
|
9. [后端 API 全览](#9-后端-api-全览)
|
|
|
|
|
|
10. [核心业务模块详解](#10-核心业务模块详解)
|
|
|
|
|
|
11. [前端 SPA 架构](#11-前端-spa-架构)
|
|
|
|
|
|
12. [14 个业务页面功能说明](#12-14-个业务页面功能说明)
|
|
|
|
|
|
13. [Composables 与状态管理](#13-composables-与状态管理)
|
|
|
|
|
|
14. [WebSocket 与 WebSSH](#14-websocket-与-webssh)
|
|
|
|
|
|
15. [Agent 与子机协议](#15-agent-与子机协议)
|
|
|
|
|
|
16. [安装向导](#16-安装向导)
|
|
|
|
|
|
17. [本地开发、测试与门控](#17-本地开发测试与门控)
|
|
|
|
|
|
18. [部署与运维](#18-部署与运维)
|
|
|
|
|
|
19. [扩展开发指南](#19-扩展开发指南)
|
|
|
|
|
|
20. [不可改项与已接受风险](#20-不可改项与已接受风险)
|
|
|
|
|
|
21. [文档索引](#21-文档索引)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 项目概述
|
|
|
|
|
|
|
|
|
|
|
|
Nexus 是面向 **2000+ 子服务器** 的运维管理平台(中心机 + Agent 架构),核心能力:
|
|
|
|
|
|
|
|
|
|
|
|
| 能力域 | 说明 |
|
|
|
|
|
|
|--------|------|
|
|
|
|
|
|
| **服务器资产** | CRUD、分类、Platform/Node、心跳监控、健康检查 |
|
|
|
|
|
|
| **文件管理** | SSH 远程浏览/编辑/chmod/压缩,sudo 提权 |
|
|
|
|
|
|
| **批量推送** | Nexus 主机 rsync → 子机,4 种 sync 模式,ZIP 上传,调度与重试 |
|
|
|
|
|
|
| **脚本执行** | 脚本库 + 临时命令,SSH 并行或 Agent 长任务 |
|
|
|
|
|
|
| **WebSSH** | 浏览器终端,多 Tab,命令日志 |
|
|
|
|
|
|
| **告警** | CPU/内存/磁盘阈值,WebSocket + Telegram,恢复通知 |
|
|
|
|
|
|
| **审计** | 全 CUD + 登录/WebSSH/推送 审计 |
|
|
|
|
|
|
| **安全** | JWT + TOTP + IP 白名单 + Fernet 凭据加密 |
|
|
|
|
|
|
|
|
|
|
|
|
**生产域名**: `https://api.synaglobal.vip`
|
|
|
|
|
|
**后端端口**: `8600`
|
|
|
|
|
|
**前端入口**: `/app/`(Vue 3 SPA,Vite 构建到 `web/app/`)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 技术栈与仓库结构
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
| 层 | 技术 |
|
|
|
|
|
|
|----|------|
|
|
|
|
|
|
| 后端 | Python 3.11+ · FastAPI · Async SQLAlchemy · Pydantic v2 |
|
|
|
|
|
|
| 数据库 | MySQL 8.x |
|
|
|
|
|
|
| 缓存/实时 | Redis 7(心跳、告警、WS 跨 worker、脚本执行状态) |
|
|
|
|
|
|
| SSH | asyncssh 连接池 |
|
|
|
|
|
|
| 前端 | Vue 3 · TypeScript · Vuetify 4 · Pinia · Vite |
|
|
|
|
|
|
| 编辑器/终端 | Monaco Editor · xterm.js |
|
|
|
|
|
|
| 进程守护 | Supervisor + Python self_monitor + Shell health_monitor |
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 目录结构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
Nexus/
|
|
|
|
|
|
├── server/ # FastAPI 后端(Clean Architecture)
|
|
|
|
|
|
│ ├── main.py # 入口、lifespan、中间件、路由挂载
|
|
|
|
|
|
│ ├── config.py # Pydantic Settings + DB 覆盖
|
|
|
|
|
|
│ ├── api/ # 路由层(JWT、校验、审计)
|
|
|
|
|
|
│ ├── application/services/ # 业务编排
|
|
|
|
|
|
│ ├── domain/models/ # SQLAlchemy ORM(19 表)
|
|
|
|
|
|
│ ├── infrastructure/ # DB/Redis/SSH/Telegram 实现
|
|
|
|
|
|
│ └── background/ # 后台循环任务
|
|
|
|
|
|
├── frontend/ # Vue 3 SPA 源码
|
|
|
|
|
|
│ └── src/
|
|
|
|
|
|
│ ├── pages/ # 14 个页面
|
|
|
|
|
|
│ ├── components/ # 按模块分子目录
|
|
|
|
|
|
│ ├── composables/ # 业务逻辑(files/push/terminal…)
|
|
|
|
|
|
│ ├── stores/ # Pinia(auth、files)
|
|
|
|
|
|
│ ├── api/index.ts # HTTP 客户端
|
|
|
|
|
|
│ └── router/index.ts # Hash 路由
|
|
|
|
|
|
├── web/app/ # 静态挂载点(index.html + assets/)
|
|
|
|
|
|
│ └── install.html # 安装向导(独立静态页,非 Vue)
|
|
|
|
|
|
├── deploy/ # Supervisor、nginx、门控、部署脚本
|
|
|
|
|
|
├── docker/ # compose 环境生成
|
|
|
|
|
|
├── scripts/ # 本地 dev、验收、MCP
|
|
|
|
|
|
├── tests/ # pytest API 测试
|
|
|
|
|
|
└── docs/ # 设计、审计、changelog
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2.3 架构分层(禁止跨层直连)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
frontend/pages → api/index.ts → server/api/*.py
|
|
|
|
|
|
→ application/services/*.py
|
|
|
|
|
|
→ infrastructure/*
|
|
|
|
|
|
→ domain/models
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- **API 层**: 路由 + Pydantic + `Depends(get_current_admin)`,不写裸 SQL
|
|
|
|
|
|
- **Service 层**: 业务编排,经 Repository 访问 DB
|
|
|
|
|
|
- **Infrastructure**: SSH 池、Redis、Telegram、Fernet
|
|
|
|
|
|
- **Domain**: ORM 模型,无 FastAPI 依赖
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 启动模式与配置
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 两种启动模式
|
|
|
|
|
|
|
|
|
|
|
|
| 模式 | 条件 | 可用能力 |
|
|
|
|
|
|
|------|------|----------|
|
|
|
|
|
|
| **安装模式** | 仓库根无 `.env` | `/api/install/*`、`/app/install.html`、静态文件;其他 API **503** |
|
|
|
|
|
|
| **正常模式** | 存在 `.env` 且 `SECRET_KEY` / `API_KEY` / `ENCRYPTION_KEY` / `DATABASE_URL` 齐全 | 全功能 + 后台任务 |
|
|
|
|
|
|
|
|
|
|
|
|
`is_install_mode()` 在 **运行时** 检测 `.env`,安装向导写入后可立即切换(需重启 worker 加载完整 lifespan)。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 配置三写(安装向导 Step 3)
|
|
|
|
|
|
|
|
|
|
|
|
安装成功时**同时写入**:
|
|
|
|
|
|
|
|
|
|
|
|
| 目标 | 内容 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| `web/data/config.json` | 共享配置(API_BASE_URL、DB、API_KEY) |
|
|
|
|
|
|
| `.env` | `NEXUS_*` 前缀,Python 启动必需 |
|
|
|
|
|
|
| MySQL `settings` 表 | 可热覆盖的动态项(阈值、Telegram、pool 等) |
|
|
|
|
|
|
|
|
|
|
|
|
**不可从 DB 覆盖**(仅 `.env`):`SECRET_KEY`、`API_KEY`、`ENCRYPTION_KEY`、`DATABASE_URL`。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.3 重要环境变量(`NEXUS_` 前缀)
|
|
|
|
|
|
|
|
|
|
|
|
| 变量 | 说明 | 可 DB 覆盖 |
|
|
|
|
|
|
|------|------|------------|
|
|
|
|
|
|
| `NEXUS_DATABASE_URL` | `mysql+aiomysql://...` | ❌ |
|
|
|
|
|
|
| `NEXUS_SECRET_KEY` | JWT HS256 | ❌ |
|
|
|
|
|
|
| `NEXUS_API_KEY` | Agent 全局密钥 | ❌ |
|
|
|
|
|
|
| `NEXUS_ENCRYPTION_KEY` | Fernet 凭据加密 | ❌ |
|
|
|
|
|
|
| `NEXUS_REDIS_URL` | 默认 `redis://127.0.0.1:6379/0` | ✅ |
|
|
|
|
|
|
| `NEXUS_API_BASE_URL` | 公网 URL(Agent curl 安装) | ✅ |
|
|
|
|
|
|
| `NEXUS_CORS_ORIGINS` | 逗号分隔 | ✅ |
|
|
|
|
|
|
| `NEXUS_DEPLOY_PATH` | 部署根路径 | ✅ |
|
|
|
|
|
|
| `NEXUS_DB_POOL_SIZE` / `MAX_OVERFLOW` | 连接池 | ✅ |
|
|
|
|
|
|
| `NEXUS_CPU/MEM/DISK_ALERT_THRESHOLD` | 告警阈值 % | ✅ |
|
|
|
|
|
|
| `NEXUS_TELEGRAM_BOT_TOKEN` / `CHAT_ID` | 告警推送 | ✅ |
|
|
|
|
|
|
| `NEXUS_LOGIN_ALLOWLIST_*` | 登录 IP 白名单 | ✅ |
|
|
|
|
|
|
| `NEXUS_JWT_ACCESS_TOKEN_EXPIRE_MINUTES` | 默认 60 | ✅ |
|
|
|
|
|
|
| `NEXUS_TEST_ADMIN_PASSWORD` | 本地测试登录(不入 git) | — |
|
|
|
|
|
|
|
|
|
|
|
|
完整映射见 `server/config.py` 的 `DB_OVERRIDE_MAP`。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 架构分层与请求生命周期
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 HTTP 请求(普通 API)
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
Client → CORS → JwtAuthMiddleware → DbSessionMiddleware → Router
|
|
|
|
|
|
→ request.state.db
|
|
|
|
|
|
→ Service → Repo → MySQL
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- **DbSessionMiddleware**: 每请求一个 `AsyncSession`,请求结束 close
|
|
|
|
|
|
- **例外**: WebSocket、`/api/install/` 自建 session
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 Primary Worker 锁
|
|
|
|
|
|
|
|
|
|
|
|
多 worker uvicorn 时,**仅一个** worker 运行后台任务:
|
|
|
|
|
|
|
|
|
|
|
|
1. Redis `SETNX nexus:primary_worker`(TTL 30s,续期)
|
|
|
|
|
|
2. Redis 不可用时 fallback:`flock /tmp/nexus-primary.lock`
|
|
|
|
|
|
|
|
|
|
|
|
后台任务列表见 [§8](#8-后台任务primary-worker)。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.3 静态文件与 SPA
|
|
|
|
|
|
|
|
|
|
|
|
- FastAPI 挂载 `web/app/` → `/app/`
|
|
|
|
|
|
- Vue 使用 **Hash 路由** `#/servers`,刷新不依赖 nginx try_files
|
|
|
|
|
|
- 构建: `cd frontend && npx vite build` → 输出 `web/app/index.html` + `assets/`
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 认证、会话与安全
|
|
|
|
|
|
|
|
|
|
|
|
### 5.1 管理端 JWT
|
|
|
|
|
|
|
|
|
|
|
|
| 项目 | 说明 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| 登录 | `POST /api/auth/login`(username + password + 可选 TOTP) |
|
|
|
|
|
|
| Access Token | 响应 body,**仅存内存**(Pinia `auth.ts`) |
|
|
|
|
|
|
| Refresh Token | HttpOnly Cookie `nexus_refresh`,`POST /api/auth/refresh` |
|
|
|
|
|
|
| 过期 | Access 默认 60min;前端过期前 5min 主动 refresh |
|
|
|
|
|
|
| 失效 | 改密/TOTP 变更 → `token_version` 递增,旧 JWT 失效 |
|
|
|
|
|
|
| 防暴破 | 5 次失败 / 15min → HTTP 429 |
|
|
|
|
|
|
| 会话空闲 | 8 小时(refresh 重用检测) |
|
|
|
|
|
|
|
|
|
|
|
|
**JWT 中间件公开前缀**(无需 Bearer):
|
|
|
|
|
|
|
|
|
|
|
|
`/api/auth/login` · `/api/auth/refresh` · `/api/auth/logout` · `/api/agent/` · `/api/install/` · `/api/settings/bing-wallpapers` · `/health` · `/ws/` · OpenAPI
|
|
|
|
|
|
|
|
|
|
|
|
### 5.2 TOTP
|
|
|
|
|
|
|
|
|
|
|
|
| API | 说明 |
|
|
|
|
|
|
|-----|------|
|
|
|
|
|
|
| `POST /api/auth/totp/setup` | 返回 QR + secret |
|
|
|
|
|
|
| `POST /api/auth/totp/enable` | 验证码确认 |
|
|
|
|
|
|
| `POST /api/auth/totp/disable` | 需当前密码 + TOTP |
|
|
|
|
|
|
|
|
|
|
|
|
### 5.3 敏感操作二次验证(Re-auth)
|
|
|
|
|
|
|
|
|
|
|
|
| 场景 | API | 需当前密码 |
|
|
|
|
|
|
|------|-----|------------|
|
|
|
|
|
|
| 查看 API Key | `POST /api/settings/api-key/reveal` | ✅ |
|
|
|
|
|
|
| 查看 Telegram Token | `POST /api/settings/telegram/reveal-token` | ✅ |
|
|
|
|
|
|
| 查看 Agent Key | `POST /api/servers/{id}/agent-key` | ✅ |
|
|
|
|
|
|
| 生成安装命令 | `POST /api/servers/{id}/agent-install-cmd` | ✅ |
|
|
|
|
|
|
| 改密 | `PUT /api/auth/password` | ✅ |
|
|
|
|
|
|
|
|
|
|
|
|
### 5.4 Agent API Key
|
|
|
|
|
|
|
|
|
|
|
|
| 层级 | 行为 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| Per-server | `servers.agent_api_key`(`nxs-*`),优先 |
|
|
|
|
|
|
| 全局回退 | `NEXUS_API_KEY`(legacy,单人运维已接受) |
|
|
|
|
|
|
| 未知 server_id | **拒绝**(batch 安装仍可能用 global key) |
|
|
|
|
|
|
|
|
|
|
|
|
Header: `X-API-Key` 或 query(Agent 脚本约定)。
|
|
|
|
|
|
|
|
|
|
|
|
### 5.5 凭据存储
|
|
|
|
|
|
|
|
|
|
|
|
- `Server.password` / `ssh_key_private` → Fernet(`ENCRYPTION_KEY`)
|
|
|
|
|
|
- API 响应: `password_set: true`,**不返明文**
|
|
|
|
|
|
- 密码预设: `encrypted_pw` 字段,前端 POST 后不入 localStorage
|
|
|
|
|
|
|
|
|
|
|
|
### 5.6 登录 IP 白名单
|
|
|
|
|
|
|
|
|
|
|
|
- `settings` + `.env`: `LOGIN_ALLOWLIST_ENABLED`
|
|
|
|
|
|
- 手动 IP + 订阅 URL 解析(`ip_allowlist_refresh` 每 2h)
|
|
|
|
|
|
- 登录 API 在 JWT 之前校验客户端 IP
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 数据模型(19 表)
|
|
|
|
|
|
|
|
|
|
|
|
定义文件: `server/domain/models/__init__.py`
|
|
|
|
|
|
|
|
|
|
|
|
| ORM | 表名 | 用途 | 关键字段 |
|
|
|
|
|
|
|-----|------|------|----------|
|
|
|
|
|
|
| `Platform` | `platforms` | 资产模板 | `name`, `category`, `default_protocols` |
|
|
|
|
|
|
| `Node` | `nodes` | 资产树节点 | `parent_id`, `sort_order` |
|
|
|
|
|
|
| `Server` | `servers` | 子服务器 | `domain`, `port`, SSH 凭据, `target_path`, `agent_api_key`, `is_online`, `system_info`, `files_elevation` |
|
|
|
|
|
|
| `SyncLog` | `sync_logs` | 推送历史 | `status`, `sync_mode`, 字节/文件统计, `operator` |
|
|
|
|
|
|
| `Admin` | `admins` | 管理员 | `password_hash`, `totp_*`, `token_version` |
|
|
|
|
|
|
| `LoginAttempt` | `login_attempts` | 登录尝试 | 防暴破 |
|
|
|
|
|
|
| `Setting` | `settings` | KV 配置 | `key` PK, `value` |
|
|
|
|
|
|
| `PasswordPreset` | `password_presets` | SSH 密码模板 | `encrypted_pw` |
|
|
|
|
|
|
| `SshKeyPreset` | `ssh_key_presets` | SSH 密钥模板 | `encrypted_private_key` |
|
|
|
|
|
|
| `PushSchedule` | `push_schedules` | 定时任务 | `cron_expr`, `server_ids`, `schedule_type` push/script |
|
|
|
|
|
|
| `PushRetryJob` | `push_retry_jobs` | 失败重试 | 指数退避, `max_retries=3` |
|
|
|
|
|
|
| `AuditLog` | `audit_logs` | 审计 | `action`, `target_*`, `ip_address` |
|
|
|
|
|
|
| `Script` | `scripts` | 脚本库 | `content`, `category` |
|
|
|
|
|
|
| `ScriptExecution` | `script_executions` | 执行记录 | `results` JSON, `status` |
|
|
|
|
|
|
| `DbCredential` | `db_credentials` | DB 凭据 | 脚本内 `$DB_*` 替换 |
|
|
|
|
|
|
| `AlertLog` | `alert_logs` | 告警历史 | `is_recovery` |
|
|
|
|
|
|
| `SshSession` | `ssh_sessions` | WebSSH 会话 | UUID `id` |
|
|
|
|
|
|
| `CommandLog` | `command_logs` | 终端命令 | `command` ≤2000 字符 |
|
|
|
|
|
|
| `QuickCommand` | `quick_commands` | 终端快捷命令 | `sort_order` |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. Redis 与实时数据流
|
|
|
|
|
|
|
|
|
|
|
|
### 7.1 Key 约定
|
|
|
|
|
|
|
|
|
|
|
|
| Key 模式 | TTL | 内容 |
|
|
|
|
|
|
|----------|-----|------|
|
|
|
|
|
|
| `heartbeat:{server_id}` | 600s | 最新心跳字段(HSET) |
|
|
|
|
|
|
| `alerts:{server_id}` | 3600s | 活跃告警集合 |
|
|
|
|
|
|
| `sync:cancel:{batch_id}` | — | 推送取消标记 |
|
|
|
|
|
|
| `nexus:alerts` | Pub/Sub | 跨 worker WS 广播 |
|
|
|
|
|
|
| `script:exec:{id}` | — | 脚本执行实时状态 |
|
|
|
|
|
|
| `nexus:primary_worker` | 30s | Primary 锁 |
|
|
|
|
|
|
|
|
|
|
|
|
### 7.2 心跳数据流
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
Agent(60s) → POST /api/agent/heartbeat
|
|
|
|
|
|
→ Redis 实时写入
|
|
|
|
|
|
→ 前端 Dashboard 读 API(overlay Redis)
|
|
|
|
|
|
→ 每 600s heartbeat_flush → MySQL servers 历史字段
|
|
|
|
|
|
→ 超阈值 → WebSocket alert + Telegram(5min 防抖)
|
|
|
|
|
|
→ 恢复 → recovery 通知
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 8. 后台任务(Primary Worker)
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 间隔 | 文件 | 职责 |
|
|
|
|
|
|
|------|------|------|------|
|
|
|
|
|
|
| `heartbeat_flush` | 600s | `background/heartbeat_flush.py` | Redis → MySQL 心跳持久化 |
|
|
|
|
|
|
| `script_execution_flush` | 60s | `background/script_execution_flush.py` | 脚本状态 Redis → MySQL;stuck 检测 |
|
|
|
|
|
|
| `self_monitor` | 30s | `background/self_monitor.py` | Redis/MySQL/WS 自检;Telegram |
|
|
|
|
|
|
| `schedule_runner` | 60s | `background/schedule_runner.py` | Cron/once 调度 → 推送或脚本 |
|
|
|
|
|
|
| `retry_runner` | 300s | `background/retry_runner.py` | `push_retry_jobs` SKIP LOCKED 重试 |
|
|
|
|
|
|
| `ip_allowlist_refresh` | 7200s | `background/ip_allowlist_refresh.py` | 订阅 URL 更新白名单 |
|
|
|
|
|
|
| `upload_staging_cleanup` | 3600s | `background/upload_staging_cleanup.py` | 清理 `/tmp/nexus_upload_*` >24h |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 9. 后端 API 全览
|
|
|
|
|
|
|
|
|
|
|
|
### 9.1 认证 `/api/auth`
|
|
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 鉴权 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| POST | `/login` | 公开 |
|
|
|
|
|
|
| POST | `/refresh` | Cookie |
|
|
|
|
|
|
| POST | `/logout` | 公开 |
|
|
|
|
|
|
| POST | `/totp/setup|enable|disable` | JWT |
|
|
|
|
|
|
| PUT | `/password` | JWT + re-auth |
|
|
|
|
|
|
| POST | `/webssh-token` | JWT |
|
|
|
|
|
|
| GET | `/me` | JWT |
|
|
|
|
|
|
|
|
|
|
|
|
### 9.2 Agent `/api/agent`
|
|
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 鉴权 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| POST | `/heartbeat` | X-API-Key |
|
|
|
|
|
|
| POST | `/script-callback` | X-API-Key + job token |
|
|
|
|
|
|
|
|
|
|
|
|
### 9.3 服务器 `/api/servers`
|
|
|
|
|
|
|
|
|
|
|
|
CRUD、stats、categories、logs、CSV import/export、batch agent install/upgrade/uninstall、health check、files-capability、setup-files-sudo、单台 agent 操作。
|
|
|
|
|
|
|
|
|
|
|
|
### 9.4 同步 `/api/sync`(`sync_v2.py`,核心)
|
|
|
|
|
|
|
|
|
|
|
|
| 分类 | 端点示例 |
|
|
|
|
|
|
|------|----------|
|
|
|
|
|
|
| 推送 | `POST /files`, `/preview`, `/cancel` |
|
|
|
|
|
|
| 远程文件 | `/browse`, `/file-ops`, `/read-file`, `/write-file`, `/chmod`, `/compress`… |
|
|
|
|
|
|
| 本机文件 | `/browse-local`, `/local-file-ops`, `/upload`, `/upload-zip` |
|
|
|
|
|
|
| 工具 | `/validate-source-path`, `/diagnose`, `/reconcile-stale-logs` |
|
|
|
|
|
|
|
|
|
|
|
|
### 9.5 文件浏览 `/api/files`
|
|
|
|
|
|
|
|
|
|
|
|
| 方法 | 路径 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| GET | `/browse?server_id=&path=` | JWT + ETag 缓存 |
|
|
|
|
|
|
|
|
|
|
|
|
### 9.6 脚本 `/api/scripts`
|
|
|
|
|
|
|
|
|
|
|
|
脚本 CRUD、`POST /exec`、executions 停止/重试/stuck、DB 凭据 CRUD。
|
|
|
|
|
|
|
|
|
|
|
|
### 9.7 设置族 `/api/settings` + 子路由
|
|
|
|
|
|
|
|
|
|
|
|
| 路由器 | 前缀 | 内容 |
|
|
|
|
|
|
|--------|------|------|
|
|
|
|
|
|
| settings | `/api/settings` | 系统 KV、Telegram、IP 白名单、bing 壁纸 |
|
|
|
|
|
|
| schedule | `/api/schedules` | 调度 CRUD |
|
|
|
|
|
|
| preset | `/api/presets` | 密码预设 |
|
|
|
|
|
|
| ssh_key_preset | `/api/ssh-key-presets` | SSH 密钥预设 |
|
|
|
|
|
|
| alert_history | `/api/alert-history` | 告警列表/统计 |
|
|
|
|
|
|
| audit | `/api/audit` | 审计分页 |
|
|
|
|
|
|
| retry | `/api/retries` | 重试队列 |
|
|
|
|
|
|
|
|
|
|
|
|
### 9.8 其他
|
|
|
|
|
|
|
|
|
|
|
|
| 模块 | 前缀 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| assets | `/api/assets` | Platform/Node/ssh-sessions/command-logs |
|
|
|
|
|
|
| terminal | `/api/terminal` | 快捷命令 CRUD |
|
|
|
|
|
|
| search | `/api/search` | 全局搜索 |
|
|
|
|
|
|
| install | `/api/install` | 安装向导 |
|
|
|
|
|
|
| health | `/health`, `/health/detail` | 探活 |
|
|
|
|
|
|
|
|
|
|
|
|
### 9.9 WebSocket
|
|
|
|
|
|
|
|
|
|
|
|
| 路径 | Token | 用途 |
|
|
|
|
|
|
|------|-------|------|
|
|
|
|
|
|
| `/ws/alerts` | Access JWT | 告警/恢复/系统 |
|
|
|
|
|
|
| `/ws/sync` | Access JWT | 推送进度 |
|
|
|
|
|
|
| `/ws/terminal/{id}` | WebSSH JWT | 终端 Koko 协议 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 10. 核心业务模块详解
|
|
|
|
|
|
|
|
|
|
|
|
### 10.1 推送引擎 SyncEngineV2
|
|
|
|
|
|
|
|
|
|
|
|
文件: `server/application/services/sync_engine_v2.py`
|
|
|
|
|
|
|
|
|
|
|
|
| 概念 | 说明 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| 执行位置 | **Nexus 中心机** 上执行 `rsync`,SSH 到子机 |
|
|
|
|
|
|
| 并发 | `asyncio.Semaphore`,默认 max 10 |
|
|
|
|
|
|
| 超时 | rsync 300s + 30s grace |
|
|
|
|
|
|
| 认证 | sshpass -e(密码)或临时 key 文件 0600 |
|
|
|
|
|
|
| 失败 | 写 `sync_logs` + 可选 `push_retry_jobs` |
|
|
|
|
|
|
| 取消 | Redis `sync:cancel:{batch_id}` |
|
|
|
|
|
|
| 预览 | `rsync --dry-run --stats` |
|
|
|
|
|
|
|
|
|
|
|
|
**Sync 模式**(`sync_mode`):
|
|
|
|
|
|
|
|
|
|
|
|
| 模式 | rsync 参数 | 行为 |
|
|
|
|
|
|
|------|------------|------|
|
|
|
|
|
|
| `incremental` | `-az` | 默认增量 |
|
|
|
|
|
|
| `full` | `-az --delete` | 删除目标多余文件 |
|
|
|
|
|
|
| `checksum` | `-az --checksum` | 校验和 |
|
|
|
|
|
|
| `overwrite` | `-az --inplace` | 原地覆盖 |
|
|
|
|
|
|
|
|
|
|
|
|
**源路径安全**: `resolve_nexus_push_source_path()` 禁止 `/etc` 等系统路径;ZIP 解压至 `UPLOAD_STAGING_PREFIX` 下暂存目录。
|
|
|
|
|
|
|
|
|
|
|
|
### 10.2 远程文件浏览
|
|
|
|
|
|
|
|
|
|
|
|
- `GET /api/files/browse` → `files_browse_service.list_remote_directory`
|
|
|
|
|
|
- 远程命令: `ls -la` + `shlex.quote(path)`
|
|
|
|
|
|
- ETag: 目录 mtime + 条目数,支持 `If-None-Match` → 304
|
|
|
|
|
|
- 前端: `useFilesStore` 内存缓存 + TTL
|
|
|
|
|
|
|
|
|
|
|
|
**Files elevation**(`files_elevation` 字段):
|
|
|
|
|
|
|
|
|
|
|
|
| 值 | 行为 |
|
|
|
|
|
|
|----|------|
|
|
|
|
|
|
| `off` | 不 sudo |
|
|
|
|
|
|
| `auto` | 写失败时尝试 sudo |
|
|
|
|
|
|
| `always_sudo` | 始终 sudo |
|
|
|
|
|
|
|
|
|
|
|
|
`POST /api/servers/{id}/setup-files-sudo` 远程配置 sudoers(密码走 stdin)。
|
|
|
|
|
|
|
|
|
|
|
|
### 10.3 脚本执行
|
|
|
|
|
|
|
|
|
|
|
|
文件: `server/application/services/script_service.py`
|
|
|
|
|
|
|
|
|
|
|
|
| 模式 | 条件 | 路径 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| SSH 短命令 | 超时内完成 | asyncssh 并行,Semaphore |
|
|
|
|
|
|
| Agent 长任务 | 超时 > 阈值 | nohup + callback URL + Redis 状态 |
|
|
|
|
|
|
|
|
|
|
|
|
- DB 凭据: 脚本内 `$DB_HOST` 等占位符替换
|
|
|
|
|
|
- 危险命令: `check_dangerous_command()` WARN 日志(不阻断)
|
|
|
|
|
|
- 停止: `POST /scripts/executions/{id}/stop`
|
|
|
|
|
|
|
|
|
|
|
|
### 10.4 服务器 Agent
|
|
|
|
|
|
|
|
|
|
|
|
| 操作 | API | 方式 |
|
|
|
|
|
|
|------|-----|------|
|
|
|
|
|
|
| 安装 | batch/single install | SSH curl agent 脚本 |
|
|
|
|
|
|
| 升级 | upgrade-agent | SSH 拉取 agent.py |
|
|
|
|
|
|
| 卸载 | uninstall-agent | SSH systemctl stop |
|
|
|
|
|
|
| 安装命令 | agent-install-cmd | 返回 curl(**禁止**暴露 global API_KEY) |
|
|
|
|
|
|
|
|
|
|
|
|
Agent 心跳 JSON 含 CPU/内存/磁盘/负载;变化 >10% 或超阈值时主动告警。
|
|
|
|
|
|
|
|
|
|
|
|
### 10.5 告警与 Telegram
|
|
|
|
|
|
|
|
|
|
|
|
- 阈值: `CPU/MEM/DISK_ALERT_THRESHOLD`(默认 80%)
|
|
|
|
|
|
- 防抖: WebSocket 5min;Telegram 同类型去重
|
|
|
|
|
|
- 恢复: 指标回落 → recovery 事件
|
|
|
|
|
|
- 推送完成: `send_telegram_sync_complete`
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 11. 前端 SPA 架构
|
|
|
|
|
|
|
|
|
|
|
|
### 11.1 构建与开发
|
|
|
|
|
|
|
|
|
|
|
|
| 项 | 值 |
|
|
|
|
|
|
|----|-----|
|
|
|
|
|
|
| 开发 | `cd frontend && npm run dev` → `http://localhost:3000/app/` |
|
|
|
|
|
|
| API 代理 | Vite proxy `/api`、`/ws` → `127.0.0.1:8600` |
|
|
|
|
|
|
| 构建输出 | `web/app/`(`base: '/app/'`) |
|
|
|
|
|
|
| 路由 | Hash `#/path` |
|
|
|
|
|
|
|
|
|
|
|
|
### 11.2 入口链路
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
main.ts → App.vue(侧栏/搜索)→ router-view
|
|
|
|
|
|
→ pages/*.vue
|
|
|
|
|
|
→ composables → api/index.ts → /api/*
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 11.3 HTTP 客户端(`src/api/index.ts`)
|
|
|
|
|
|
|
|
|
|
|
|
| 能力 | 实现 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| Token | 内存 access JWT |
|
|
|
|
|
|
| 401 | 自动 refresh 一次 |
|
|
|
|
|
|
| 202 | `TotpRequiredError` |
|
|
|
|
|
|
| 429 | 锁定文案 |
|
|
|
|
|
|
| 304 | 文件 browse ETag |
|
|
|
|
|
|
| Upload | FormData 不设 JSON Content-Type |
|
|
|
|
|
|
|
|
|
|
|
|
### 11.4 Pinia Stores
|
|
|
|
|
|
|
|
|
|
|
|
| Store | 职责 |
|
|
|
|
|
|
|-------|------|
|
|
|
|
|
|
| `auth` | token、admin、login/logout/refresh |
|
|
|
|
|
|
| `files` | selectedServer、currentPath、browse 缓存 |
|
|
|
|
|
|
|
|
|
|
|
|
其余状态在 composable 或页面 `ref` 中。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 12. 14 个业务页面功能说明
|
|
|
|
|
|
|
|
|
|
|
|
> 路由均位于 `#/` 下;除 Login 外需 JWT。
|
|
|
|
|
|
|
|
|
|
|
|
### 12.1 DashboardPage `/`
|
|
|
|
|
|
|
|
|
|
|
|
| 功能 | API/机制 |
|
|
|
|
|
|
|------|----------|
|
|
|
|
|
|
| 统计卡片 | `GET /servers/stats` |
|
|
|
|
|
|
| 服务器分页表 | `useServerPagination` |
|
|
|
|
|
|
| 告警摘要 | `GET /alert-history/?limit=5` |
|
|
|
|
|
|
| 资源概览 | 拉 200 台算 CPU/内存均值 |
|
|
|
|
|
|
| 分类分布 | stats.categories |
|
|
|
|
|
|
| 最近审计 | `GET /audit/?limit=10` |
|
|
|
|
|
|
| 实时刷新 | `useWebSocket` → 告警时 reload stats |
|
|
|
|
|
|
| 快捷跳转 | 终端/文件 `?server_id=` |
|
|
|
|
|
|
|
|
|
|
|
|
### 12.2 ServersPage `/servers`
|
|
|
|
|
|
|
|
|
|
|
|
| 功能 | API |
|
|
|
|
|
|
|------|-----|
|
|
|
|
|
|
| CRUD | `/servers/` |
|
2026-06-06 23:50:05 +08:00
|
|
|
|
| **快速添加(仅 IP)** | `POST /servers/add-by-ip` — 轮询全部密码/SSH 预设;成功返回 `matched_preset` / `matched_username` |
|
|
|
|
|
|
| **连接失败列表** | `GET /servers/pending` |
|
|
|
|
|
|
| **失败重试 / 删除** | `POST /servers/pending/{id}/retry`、`DELETE /servers/pending/{id}` |
|
2026-06-04 23:01:03 +08:00
|
|
|
|
| 批量选择 | 安装/升级/卸载 Agent、健康检查、删除 |
|
|
|
|
|
|
| CSV 导出 | 客户端生成(无密码列) |
|
|
|
|
|
|
| CSV 导入 | `POST /servers/import` FormData |
|
|
|
|
|
|
| 详情面板 | 系统信息 + `GET /servers/{id}/logs` |
|
|
|
|
|
|
| 表单 | `ServerFormDialog` + `useServerFormDialog` |
|
|
|
|
|
|
|
2026-06-06 23:50:05 +08:00
|
|
|
|
详见附录 J(凭据轮询契约)。
|
|
|
|
|
|
|
2026-06-04 23:01:03 +08:00
|
|
|
|
### 12.3 TerminalPage `/terminal`
|
|
|
|
|
|
|
|
|
|
|
|
| 功能 | 说明 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| 多 Tab | `useTerminalSessions` |
|
|
|
|
|
|
| WebSSH | `POST /auth/webssh-token` → `WS /ws/terminal/{id}?token=` |
|
|
|
|
|
|
| xterm | FitAddon、256 色 |
|
|
|
|
|
|
| 命令栏 | shell 高亮、`sendCmd`/`sendCtrl` |
|
|
|
|
|
|
| 快捷命令 | `GET /terminal/quick-commands` |
|
|
|
|
|
|
| 路由入参 | `#/terminal?server_id=123` 自动开 Tab |
|
|
|
|
|
|
| 清理 | `onBeforeUnmount` → `disposeAllSessions` |
|
|
|
|
|
|
|
|
|
|
|
|
### 12.4 FilesPage `/files`
|
|
|
|
|
|
|
|
|
|
|
|
薄编排页,逻辑在 composables:
|
|
|
|
|
|
|
|
|
|
|
|
| 子模块 | 能力 |
|
|
|
|
|
|
|--------|------|
|
|
|
|
|
|
| Toolbar | 上传、刷新、上级目录 |
|
|
|
|
|
|
| List | 排序、多选、双击进目录 |
|
|
|
|
|
|
| Editor | Monaco,`POST /sync/read-file|write-file` |
|
|
|
|
|
|
| 权限 | files-capability 检测、sudo 提示 |
|
|
|
|
|
|
| 热键 | 复制/粘贴/删除(`useFilesHotkeys`) |
|
|
|
|
|
|
|
|
|
|
|
|
### 12.5 PushPage `/push`
|
|
|
|
|
|
|
|
|
|
|
|
| 功能 | API/WS |
|
|
|
|
|
|
|------|--------|
|
|
|
|
|
|
| 源/目标路径 | 表单校验 |
|
|
|
|
|
|
| ZIP 上传 | `POST /sync/upload-zip` |
|
|
|
|
|
|
| 服务器网格 | 分类全选 |
|
|
|
|
|
|
| 预览 | `POST /sync/preview` 并发 |
|
|
|
|
|
|
| 推送 | `POST /sync/files` + `/ws/sync` 进度 |
|
|
|
|
|
|
| 取消 | `POST /sync/cancel` |
|
|
|
|
|
|
| 历史 | sync_logs 分页、诊断、对账 |
|
|
|
|
|
|
|
|
|
|
|
|
### 12.6 ScriptsPage `/scripts`
|
|
|
|
|
|
|
|
|
|
|
|
| 功能 | API |
|
|
|
|
|
|
|------|-----|
|
|
|
|
|
|
| 脚本 CRUD | `/scripts/` |
|
|
|
|
|
|
| Monaco 编辑 | content 字段 |
|
|
|
|
|
|
| 执行 | `POST /scripts/exec` + 轮询 executions |
|
|
|
|
|
|
| 临时命令 | quick exec 面板 |
|
|
|
|
|
|
| 停止 | `POST /scripts/executions/{id}/stop` |
|
|
|
|
|
|
|
|
|
|
|
|
### 12.7 CredentialsPage `/credentials`
|
|
|
|
|
|
|
|
|
|
|
|
三 Tab:密码预设、SSH 密钥、DB 凭据;编辑时空密码表示不修改。
|
|
|
|
|
|
|
2026-06-06 23:50:05 +08:00
|
|
|
|
| Tab | API | 契约要点 |
|
|
|
|
|
|
|-----|-----|----------|
|
|
|
|
|
|
| 密码预设 | `GET/POST /presets/`、`PUT/DELETE /presets/{id}` | 字段 `name`、`username`(默认 `root`)、`encrypted_pw`;列表返回 `username` |
|
|
|
|
|
|
| SSH 密钥 | `GET/POST /ssh-key-presets/`、`PUT/DELETE /ssh-key-presets/{id}` | 同上 `username`;私钥 `private_key` 仅创建/更新时传 |
|
|
|
|
|
|
| DB 凭据 | `GET/POST /scripts/credentials`、`PUT/DELETE /scripts/credentials/{id}` | 脚本执行用 DB 连接,与 SSH 轮询无关 |
|
|
|
|
|
|
|
|
|
|
|
|
`username` 供 `credential_poller` 在 `add-by-ip` / retry 时与预设密码或私钥组合尝试 SSH。
|
|
|
|
|
|
|
2026-06-04 23:01:03 +08:00
|
|
|
|
### 12.8 SchedulesPage `/schedules`
|
|
|
|
|
|
|
|
|
|
|
|
Cron 调度推送;`runNow` → `POST /sync/files`;cron 前端正则校验。
|
|
|
|
|
|
|
|
|
|
|
|
### 12.9 RetriesPage `/retries`
|
|
|
|
|
|
|
|
|
|
|
|
失败推送重试队列;`POST /retries/{id}/retry`。
|
|
|
|
|
|
|
|
|
|
|
|
### 12.10 CommandsPage `/commands`
|
|
|
|
|
|
|
|
|
|
|
|
命令视图 / 会话视图;`GET /assets/command-logs|ssh-sessions`。
|
|
|
|
|
|
|
|
|
|
|
|
### 12.11 AlertsPage `/alerts`
|
|
|
|
|
|
|
|
|
|
|
|
告警统计 + 分页;按 type/status 过滤。
|
|
|
|
|
|
|
|
|
|
|
|
### 12.12 AuditPage `/audit`
|
|
|
|
|
|
|
|
|
|
|
|
操作审计;action/user/date 过滤;`normalizeAuditList`。
|
|
|
|
|
|
|
|
|
|
|
|
### 12.13 SettingsPage `/settings`
|
|
|
|
|
|
|
|
|
|
|
|
系统名/阈值/连接池、Telegram、改密、TOTP、API Key reveal、IP 白名单、终端快捷命令设置。
|
|
|
|
|
|
|
|
|
|
|
|
### 12.14 LoginPage `/login`
|
|
|
|
|
|
|
|
|
|
|
|
JWT 登录、TOTP、429 锁定、开放重定向防护(`//` 拒绝)、bing 壁纸背景。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 13. Composables 与状态管理
|
|
|
|
|
|
|
|
|
|
|
|
### 13.1 模块索引
|
|
|
|
|
|
|
|
|
|
|
|
| 目录 | 入口 | 用途 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| `composables/files/` | `useFilesPage` | 文件页总编排 |
|
|
|
|
|
|
| `composables/push/` | `usePushPage` | 推送页总编排 |
|
|
|
|
|
|
| `composables/terminal/` | `useTerminalSessions` | WebSSH 会话 |
|
|
|
|
|
|
| `composables/servers/` | `useServerFormDialog` | 服务器表单 |
|
|
|
|
|
|
| `composables/useWebSocket.ts` | — | 告警 WS |
|
|
|
|
|
|
| `composables/useServerPagination.ts` | — | 分页表 |
|
|
|
|
|
|
|
|
|
|
|
|
### 13.2 新增页面 Checklist
|
|
|
|
|
|
|
|
|
|
|
|
1. `frontend/src/pages/XxxPage.vue`
|
|
|
|
|
|
2. `router/index.ts` 注册路由
|
|
|
|
|
|
3. `App.vue` 侧栏 nav 项
|
|
|
|
|
|
4. `types/api.ts` 补充类型
|
|
|
|
|
|
5. 后端 API + 审计日志
|
|
|
|
|
|
6. E2E: `frontend/e2e/full-acceptance.spec.mjs`
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 14. WebSocket 与 WebSSH
|
|
|
|
|
|
|
|
|
|
|
|
### 14.1 告警 WS `/ws/alerts`
|
|
|
|
|
|
|
|
|
|
|
|
- 连接: `buildWebSocketUrl('/ws/alerts', { token: accessToken })`
|
|
|
|
|
|
- 消息类型: alert / recovery / system
|
|
|
|
|
|
- App.vue 或 Dashboard 订阅
|
|
|
|
|
|
|
|
|
|
|
|
### 14.2 推送 WS `/ws/sync`
|
|
|
|
|
|
|
|
|
|
|
|
- batch_id 维度进度
|
|
|
|
|
|
- `usePushProgress` 维护 per-server 状态
|
|
|
|
|
|
|
|
|
|
|
|
### 14.3 WebSSH
|
|
|
|
|
|
|
|
|
|
|
|
- 独立 JWT: `purpose=webssh`, `server_id`, 15min
|
|
|
|
|
|
- 绑定路径 server_id,防 IDOR
|
|
|
|
|
|
- Koko 消息: `TERMINAL_INIT`, `DATA`, `RESIZE`, `CLOSE`
|
|
|
|
|
|
- 命令日志: Enter 时写 `command_logs`
|
|
|
|
|
|
|
|
|
|
|
|
**已接受风险**: JWT 走 query string(ADR-011),见 risk-acceptance 文档。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 15. Agent 与子机协议
|
|
|
|
|
|
|
|
|
|
|
|
### 15.1 网络模型
|
|
|
|
|
|
|
|
|
|
|
|
| 方向 | 端口 | 用途 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| 子机 → 中心 | 443 出站 | 心跳、script callback |
|
|
|
|
|
|
| 中心 → 子机 | 22 | 推送、文件、脚本、Agent 安装 |
|
|
|
|
|
|
| 子机本机 | 127.0.0.1:8601 | Agent HTTP(可选) |
|
|
|
|
|
|
|
|
|
|
|
|
### 15.2 心跳 Payload(摘要)
|
|
|
|
|
|
|
|
|
|
|
|
`server_id`, `cpu`, `memory`, `disk`, `load`, `uptime`, `agent_version`, `system_info`, ...
|
|
|
|
|
|
|
|
|
|
|
|
### 15.3 脚本回调
|
|
|
|
|
|
|
|
|
|
|
|
长任务完成后 Agent `POST /api/agent/script-callback`,携带 job id 与 per-server 结果。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 16. 安装向导
|
|
|
|
|
|
|
|
|
|
|
|
| 步骤 | UI | API |
|
|
|
|
|
|
|------|-----|-----|
|
|
|
|
|
|
| 1 | 环境检查 | `GET /install/env-check` |
|
|
|
|
|
|
| 2 | MySQL/Redis 配置 | `POST /install/init-db` |
|
|
|
|
|
|
| 3 | 三写配置 | 同上(写 .env + config.json + settings) |
|
|
|
|
|
|
| 4 | 创建管理员 | `POST /install/create-admin`(install_token) |
|
|
|
|
|
|
| 5 | 锁定 | `POST /install/lock` |
|
|
|
|
|
|
|
|
|
|
|
|
静态页: `web/app/install.html`(Tailwind,非 Vue SPA)。
|
|
|
|
|
|
锁定后 `/install/status` → 404,防止信息泄露。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 17. 本地开发、测试与门控
|
|
|
|
|
|
|
|
|
|
|
|
### 17.1 快速启动
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Docker MySQL + Redis
|
|
|
|
|
|
docker compose up -d mysql redis
|
|
|
|
|
|
|
|
|
|
|
|
# 生成 .env(若无)
|
|
|
|
|
|
python3 docker/generate_env.py && python3 docker/sync_root_env.py
|
|
|
|
|
|
|
|
|
|
|
|
# 启动 API
|
|
|
|
|
|
bash scripts/start-dev.sh # → http://127.0.0.1:8600
|
|
|
|
|
|
|
|
|
|
|
|
# 前端
|
|
|
|
|
|
cd frontend && npm run dev # → http://localhost:3000/app/
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 17.2 验证命令
|
|
|
|
|
|
|
|
|
|
|
|
| 级别 | 命令 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| L2b | `bash scripts/local_verify.sh` |
|
|
|
|
|
|
| L2c | `.venv/bin/pytest tests/ -q` |
|
|
|
|
|
|
| L3 | `bash deploy/pre_deploy_check.sh` |
|
|
|
|
|
|
| L4 | `python3 scripts/run_nexus_acceptance.py --base http://127.0.0.1:8600 --with-ui` |
|
|
|
|
|
|
| E2E | `cd frontend && NEXUS_E2E_BASE=http://127.0.0.1:8600 npm run test:e2e` |
|
|
|
|
|
|
|
|
|
|
|
|
### 17.3 七道门控
|
|
|
|
|
|
|
|
|
|
|
|
见 `deploy/pre_deploy_check.sh`:Changelog、Audit、Test、Ruff、Import、Bandit、Review。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 18. 部署与运维
|
|
|
|
|
|
|
|
|
|
|
|
### 18.1 生产部署
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
git push origin main
|
|
|
|
|
|
bash deploy/pre_deploy_check.sh
|
|
|
|
|
|
bash deploy/deploy-production.sh
|
|
|
|
|
|
# 或手动: ssh nexus "cd $DEPLOY && git reset --hard origin/main && supervisorctl restart nexus"
|
|
|
|
|
|
# 前端: bash deploy/deploy-frontend.sh
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 18.2 三层守护
|
|
|
|
|
|
|
|
|
|
|
|
| 层 | 机制 |
|
|
|
|
|
|
|----|------|
|
|
|
|
|
|
| 1 | Supervisor 进程重启 |
|
|
|
|
|
|
| 2 | `self_monitor` 30s |
|
|
|
|
|
|
| 3 | `health_monitor.sh` cron 1min → 连续失败 restart + Telegram |
|
|
|
|
|
|
|
|
|
|
|
|
### 18.3 健康检查
|
|
|
|
|
|
|
|
|
|
|
|
- `GET /health` → 纯文本 `ok`
|
|
|
|
|
|
- `GET /health/detail` → JSON(需 JWT)
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 19. 扩展开发指南
|
|
|
|
|
|
|
|
|
|
|
|
### 19.1 新增 REST API
|
|
|
|
|
|
|
|
|
|
|
|
1. 设计文档 `docs/design/specs/YYYY-MM-DD-*.md`
|
|
|
|
|
|
2. Service + Repository(若需)
|
|
|
|
|
|
3. `server/api/xxx.py` + `Depends(get_current_admin)`
|
|
|
|
|
|
4. `main.py` include_router
|
|
|
|
|
|
5. 审计: `AuditLog` 写入
|
|
|
|
|
|
6. `tests/test_api.py` 或专项测试
|
|
|
|
|
|
7. Changelog + 审计 8 步
|
|
|
|
|
|
|
|
|
|
|
|
### 19.2 新增前端功能
|
|
|
|
|
|
|
|
|
|
|
|
1. 明确页面 vs 对话框 vs composable 边界
|
|
|
|
|
|
2. 类型先进 `types/api.ts`
|
|
|
|
|
|
3. 错误用 `formatApiError` + snackbar,**禁止静默吞错**
|
|
|
|
|
|
4. 敏感数据不进 localStorage
|
|
|
|
|
|
5. Playwright 抽测关键路径
|
|
|
|
|
|
|
|
|
|
|
|
### 19.3 新增后台任务
|
|
|
|
|
|
|
|
|
|
|
|
1. 仅 primary worker 注册(`main.py` lifespan)
|
|
|
|
|
|
2. 循环内 try/except + logger,不可空 pass
|
|
|
|
|
|
3. 需可关闭(CancelledError)
|
|
|
|
|
|
4. 文档 + changelog
|
|
|
|
|
|
|
|
|
|
|
|
### 19.4 数据库变更
|
|
|
|
|
|
|
|
|
|
|
|
1. 修改 `domain/models`
|
|
|
|
|
|
2. 启动时 `init_db` 或手写迁移 SQL(生产谨慎)
|
|
|
|
|
|
3. 不可破坏 `ENCRYPTION_KEY` 下已有密文
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 20. 不可改项与已接受风险
|
|
|
|
|
|
|
|
|
|
|
|
### 20.1 不可改(架构/安全一致性)
|
|
|
|
|
|
|
|
|
|
|
|
| 项 | 原因 |
|
|
|
|
|
|
|----|------|
|
|
|
|
|
|
| `API_KEY` | Agent 与加密回退一致 |
|
|
|
|
|
|
| `SECRET_KEY` | JWT 与已有 token |
|
|
|
|
|
|
| `ENCRYPTION_KEY` | 已加密凭据 |
|
|
|
|
|
|
| `DATABASE_URL` | 启动绑定 |
|
|
|
|
|
|
|
|
|
|
|
|
### 20.2 已接受风险(单人运维)
|
|
|
|
|
|
|
|
|
|
|
|
见 `docs/project/risk-acceptance-single-operator.md`:
|
|
|
|
|
|
|
|
|
|
|
|
- WebSocket / WebSSH JWT 在 query
|
|
|
|
|
|
- Agent global API_KEY 回退
|
|
|
|
|
|
- 危险命令仅 WARN 不阻断
|
|
|
|
|
|
- dev docker-compose 默认密码
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 21. 文档索引
|
|
|
|
|
|
|
|
|
|
|
|
| 文档 | 用途 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| **本文** | 功能开发 SSOT(架构 + 模块概览) |
|
|
|
|
|
|
| **[附录](nexus-functional-development-guide-appendix.md)** | API 字段表、Files/Push/Terminal 调用链、E2E/L4 对照、组件映射 |
|
|
|
|
|
|
| [AI-HANDOFF-2026-06-03.md](AI-HANDOFF-2026-06-03.md) | 会话接续 |
|
|
|
|
|
|
| [linux-dev-paths.md](linux-dev-paths.md) | Linux 路径 |
|
|
|
|
|
|
| [local-integration-test.md](local-integration-test.md) | 本地验收 |
|
|
|
|
|
|
| [script-execution.md](script-execution.md) | 脚本执行细节 |
|
|
|
|
|
|
| [alert-push-policy.md](alert-push-policy.md) | 告警策略 |
|
|
|
|
|
|
| [deploy.md](deploy.md) | 部署补充 |
|
|
|
|
|
|
| [development-acceptance-standard.md](development-acceptance-standard.md) | L0–L5 验收 |
|
|
|
|
|
|
| `docs/design/specs/` | 新功能设计 |
|
|
|
|
|
|
| `docs/changelog/` | 每次变更记录 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 22. 详细参考(附录摘要)
|
|
|
|
|
|
|
|
|
|
|
|
完整查表见 **[nexus-functional-development-guide-appendix.md](nexus-functional-development-guide-appendix.md)**。
|
|
|
|
|
|
|
|
|
|
|
|
| 附录 | 内容 |
|
|
|
|
|
|
|------|------|
|
|
|
|
|
|
| **A** | `/api/sync` 全 21 端点 + Pydantic 字段 + WS 推送时序 |
|
|
|
|
|
|
| **B** | Files 页组件树、composable 依赖图、操作→API 映射 |
|
|
|
|
|
|
| **C** | Push 页 composable 与推送时序 |
|
|
|
|
|
|
| **D** | Terminal / WebSSH 调用链 |
|
|
|
|
|
|
| **E** | schedules/retries/audit/scripts/agent/search API 明细 |
|
|
|
|
|
|
| **F** | 14 页 ↔ composable ↔ 组件对照表 |
|
|
|
|
|
|
| **G** | L4 验收 + Playwright 15 用例对照 |
|
|
|
|
|
|
| **H** | HTTP 错误码与前端处理 |
|
|
|
|
|
|
| **I** | 扩展开发检查清单 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
**维护约定**: 新增模块或变更 API/页面时,**同步更新本文 + 附录对应章节** + changelog(≥10 行)。
|