mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-28 05:46:36 +08:00
12 KiB
12 KiB
ATSFlare 开发规范
1. 适用范围
本规范适用于 ATSFlare 第一版与第二版阶段。
项目第一版已完成以下能力:
- 配置发布与同步
- 节点心跳检测
- Nginx 反向代理配置下发
第二版在此基础上新增以下能力:
- HTTPS/TLS 路由支持
- 证书托管(手动导入与文件导入)
- 域名管理与证书自动匹配(支持
*.example.com) - Agent Token 管理
- 路由自定义请求头
- 配置预览与变更摘要
当前明确仍不做:
- 多租户
- WAF、限流、Bot、防刷
- 百分比灰度发布
- 节点分组与差异化下发
- Redis、MQ、对象存储、Prometheus
- 复杂缓存策略、证书自动签发、Purge、审批流
- mid-tier、分层缓存、复杂策略编排
超出以上范围的需求,必须先更新设计文档,再开始编码。
2. 技术基线
2.1 Server
控制中心基于现有 atsf_server 开发:
- Web 框架:Gin
- ORM:GORM
- 数据库:SQLite
- 前端:现有
atsf_server/web - 登录体系:沿用 gin-template 现有能力
约束:
- 默认不配置
SQL_DSN - 默认不配置
REDIS_CONN_STRING - 不为了 MVP 引入新的基础设施依赖
2.2 Agent
Agent 放在 atsf_agent,使用 Go 单体程序开发。
约束:
- 单二进制
- systemd 运行
- 优先调用独立 Nginx,不依赖系统全局 Nginx
- 支持通过
nginx_path显式指定独立 Nginx 可执行文件 - 未指定
nginx_path时,默认通过 Docker 启动独立 Nginx 容器 - Agent 生成资源默认统一放在
./data,可通过data_dir统一覆盖 - 负责本机 Nginx 路由配置写入、校验、reload、状态上报
2.3 Nginx 配置边界
第一版控制面只管理独立生成的 Nginx 路由配置文件,例如 /etc/nginx/conf.d/atsflare_routes.conf。第二版在此基础上增加证书托管能力。
第一版以下内容不纳入控制面:
nginx.conf- 缓存策略
- upstream 高级配置
第二版约束:
- 允许在控制面托管 TLS 证书并下发给节点
- 仅支持证书导入(手动粘贴与文件导入),不做自动签发/续期
nginx.conf、缓存策略、upstream 高级配置仍保持节点本地静态配置
3. 仓库职责划分
3.1 atsf_server
负责:
- 管理端 UI
- 管理端 API
- Agent API
- 数据存储
- 配置渲染
- 版本发布
- 节点状态展示
3.2 atsf_agent
负责:
- 节点注册
- 心跳上报
- 拉取激活版本
- 写入本地 Nginx 路由配置
- 调用
nginx -t和nginx -s reload - 失败回滚
- 上报应用结果
- 管理独立 Nginx 路径或 Docker Nginx 容器
3.3 docs
负责:
- 设计边界
- 开发规范
- 开发计划
- 部署与联调说明
4. 开发原则
所有实现都必须遵守以下原则:
- 先完成闭环,再做抽象。
- 不为了"以后可能会支持"提前引入复杂模型。
- Server 只管状态和配置,不直接 SSH 改节点。
- Agent 是唯一落地入口。
- 所有发布都是"新版本激活",不是在线覆盖编辑。
- 第一版与第二版:所有节点默认拉同一份全量配置,不做节点分组差异化下发。
- 能用 SQLite 解决的问题,不引入额外中间件。
- 新功能优先复用现有 gin-template 结构,不平行造第二套框架。
5. 数据模型规范
第一版核心实体(已实现):
proxy_routesconfig_versionsnodesapply_logs
第二版新增实体:
tls_certificates— 证书托管managed_domains— 域名管理与证书绑定agent_tokens— Agent Token 管理
约束(全版本):
- 不新增
zone、origin_pool、policy、deployment这类平台化对象 proxy_routes一条域名只对应一个origin_urlconfig_versions必须保存完整快照和渲染后的 Nginx 路由配置- 激活版本全局只能有一个,不引入分组维度
- 回滚通过"激活旧版本"实现,不直接修改历史记录
agent_tokens中的 Token 值不可更新,只能创建或撤销- 域名到证书匹配必须支持精确匹配和通配符匹配(如
*.example.com)
如需新增表,必须先证明它服务于当前迭代版本的主链路。
6. Server 开发规范
6.1 分层约束
Server 代码按以下职责拆分:
controller/: 参数解析、调用 service、返回 JSONservice/: 业务逻辑、校验、渲染、版本切换model/: 数据表结构、查询和持久化router/: 路由注册middleware/: 认证、鉴权、限流等横切逻辑common/: 通用工具和配置
禁止行为:
- controller 直接拼接复杂业务逻辑
- controller 直接操作多个 model 形成事务链
- middleware 承担业务逻辑
- 为简单需求引入新的平台层抽象
6.2 API 约定
管理端和 Agent API 统一使用 JSON。
响应结构沿用现有模板风格:
{
"success": true,
"message": "",
"data": {}
}
约束:
- 成功或失败都返回清晰
message - 列表接口返回稳定字段,不临时拼装结构
- 新接口命名优先使用复数资源风格
- Agent API 固定放在
/api/agent/*
6.3 鉴权规范
管理端:
- 继续复用 gin-template 的登录、角色和 session 体系
Agent(第一版):
- 预共享单 Token,来自环境变量
- 请求头统一使用
X-Agent-Token - Agent 与管理端认证逻辑必须分开
Agent(第二版):
- Token 改为查
agent_tokens表验证 - 环境变量 Token 降级为 bootstrap 模式:数据库存在有效 Token 记录时,环境变量 Token 不再有效
- Token 创建时生成随机值,不允许外部传入
- Token 值不可更新,仅支持撤销(设
is_active=false)
注意:
- 不要让 Agent 接口走用户登录态
- 不要把 Nginx 命令暴露成远程管理接口
6.4 数据库规范
SQLite 是唯一默认数据库。
要求:
- 新增模型后必须在
model.InitDB()中加入AutoMigrate - 不写 MySQL/PostgreSQL 特有 SQL
- 不依赖外部迁移工具作为 MVP 前提
- 时间字段统一使用 GORM 常规时间类型
6.5 发布与渲染规范
发布逻辑必须满足:
- 发布时读取全部启用的
proxy_routes - 生成完整的 Nginx 路由配置
- 计算 checksum
- 保存快照到
config_versions - 通过切换
is_active激活版本
版本号格式固定为:
YYYYMMDD-NNN
例如:
20260309-001
7. Agent 开发规范
7.1 模块边界
建议目录如下:
atsf_agent/
cmd/agent/
internal/config/
internal/heartbeat/
internal/sync/
internal/nginx/
internal/state/
internal/httpclient/
职责要求:
config: 本地配置读取heartbeat: 心跳请求和状态组装sync: 检查版本、下载配置、触发应用nginx: 封装 Nginx 校验、reload 和文件写入state: 本地成功版本和运行状态缓存httpclient: Server API 调用
7.2 行为规范
Agent 必须满足以下行为:
- 启动后生成或读取本地
node_id - 周期性心跳
- 周期性检查激活版本
- 发现新版本后先备份旧文件
- 写入新路由配置文件
- 先执行
nginx -t - 校验通过后执行
nginx -s reload - 失败时回滚备份并再次校验和 reload
- 上报最终应用结果
- 优先使用
nginx_path - 未配置
nginx_path时自动准备并使用 Docker Nginx 容器 - 启动时先校验本地路由文件 checksum 与控制面激活版本是否一致
- Docker 模式启动时应重建容器,而不是继续复用异常停止的旧容器
7.3 容错规范
第一版最少保证:
- Server 不可用时,Nginx 继续使用旧配置
- 下载失败时,不修改本地配置
- 配置校验或 reload 失败时,自动尝试回滚
- 本地状态文件损坏时,允许重新初始化,但不能删除正在生效的 Nginx 配置
- Docker 容器异常停止时,启动阶段应自动重建容器并重新校验配置
7.4 外部命令规范
Agent 调用 Nginx 命令时必须:
- 明确记录执行命令和返回错误
- 设置合理超时
- 不依赖交互式输入
- 不通过 shell 拼接不可信参数
8. 前端开发规范
MVP 前端只做最小管理界面,不重做整套后台。
要求:
- 继续使用现有 React 结构和
semantic-ui-react - 页面只增加 MVP 必需页面
- 不额外引入新的大型前端框架
- API 请求统一放在
web/src/helpers/api.js或同类 helper 中 - 页面状态优先保持简单,不提前引入复杂全局状态管理
第一版只需要以下页面:
- 反代规则页
- 发布版本页
- 节点状态页
- 应用记录页
9. 代码风格规范
9.1 Go
- 保持 package 名称简短且小写
- 错误必须显式处理,不允许静默吞错
- 函数尽量只做一件事
- 输入校验放在 controller 或 service 边界
- 业务枚举值使用明确常量,不使用魔法字符串散落代码
- 仅在复杂逻辑前添加简短注释,不写废话注释
9.2 命名
- 表名和模型名使用业务语义,不沿用模板示例语义
- 统一使用
route,version,node,apply log这些术语 - 不混用
client、edge、agent指代同一模块,统一叫agent
9.3 日志
要求记录这些关键事件:
- 发布成功/失败
- Agent 注册
- 心跳异常
- 配置下载失败
- Nginx 校验或 reload 成功/失败
- 回滚触发
日志内容要可定位问题,但不要打印敏感 Token。
10. 测试与验收规范
10.1 第一版最低测试要求(已完成)
Server 至少覆盖:
origin_url校验domain重复校验- Nginx 路由配置渲染结果
- 激活版本切换逻辑
- 节点在线状态判定逻辑
Agent 至少覆盖:
- 版本比较逻辑
- 配置文件备份和回滚逻辑
nginx -t或nginx -s reload失败分支- 本地状态文件读写
10.2 第二版新增测试要求
Server 新增覆盖:
- HTTPS server 块渲染正确性(
enable_https=true时生成 443 块,redirect_http=true时生成重定向块) - HTTP-only 路由渲染结果不受 HTTPS 字段影响
- 证书导入逻辑(手动导入、文件导入)和 PEM 校验逻辑
- 域名证书匹配逻辑(精确匹配与
*.example.com通配符匹配) custom_headers注入到渲染结果的正确性agent_tokens创建与查表验证逻辑- Token 撤销后验证失败
- bootstrap Token 降级行为(数据库有 Token 时环境变量 Token 失效)
- 预览接口不写库
- diff 接口变更摘要计算正确性
10.3 联调验收标准(第一版,已完成)
- 管理端新增反代规则并成功发布版本
- Agent 能检测到新版本并拉取
- Agent 成功写入 Nginx 路由配置文件
- Agent 成功执行
nginx -t和nginx -s reload - 节点页能看到当前版本和最后心跳
- 当 reload 失败时,Agent 能回滚到旧配置并上报失败
10.4 联调验收标准(第二版)
- 创建含 HTTPS 字段的路由并发布,Nginx 能以 HTTPS 正确转发
- 控制面可手动导入和文件导入证书,导入后可被路由选择
- 反代规则输入域名后可自动匹配证书,且支持
*.example.com - 通过管理界面创建 Token,Agent 使用新 Token 成功访问
- 撤销 Token 后 Agent 请求返回 401
- 路由配置自定义头后,渲染结果包含对应指令
- 发布页预览展示正确渲染结果
- 变更摘要正确列出域名变化
11. 文档维护规范
出现以下情况时必须同步更新文档:
- 产品版本范围变化(V1 → V2 → V3)
- API 发生破坏性变更
- 数据模型新增或删除
- Agent 本地文件路径变更
- 部署方式变化
- 新增或撤销对中间件/基础设施的依赖
优先更新:
docs/design.mddocs/development-guidelines.mddocs/development-plan.md