新增插件
CertHub 是元数据驱动的:插件清单由后端注册表决定,前端表单、授权下拉、任务选择器全部自动生成。所以加功能不需要动前端。
新增部署插件
第 1 步:写 handler
在 backend/app/services/deploy.py(或对应的 deploy_*.py)里实现:
python
def deploy_to_xxx(ctx: CertContext, config: dict, log: Callable) -> None:
log("开始部署 ...")
# ctx.crt / ctx.key / ctx.pfx / ctx.domain / ctx.domains
# 路径里的变量用 ctx.render("...{{cert.domain}}...")两个约定
config里已经有授权内容。任务表单只存accessId,引擎执行前会把授权里的地址、账号、密钥合并进config(授权为底稿、任务入参覆盖),所以直接读config["url"]/config["username"]即可,不要再自己去查授权表。- 内网面板统一用
_panel_request()发请求。它会关掉trust_env—— 宿主机上若配了HTTP_PROXY,httpx 默认会把192.168.x.x的内网请求也丢给代理,表现成「连不上」却看不出原因;同时把连接类异常翻成中文。公网云厂商接口不要用它,那些场景反而需要走代理。
第 2 步:注册 handler
python
DEPLOY_HANDLERS["DeployToXxx"] = deploy_to_xxx第 3 步:登记元数据
在 backend/app/plugins.py 的 TASK_PLUGINS 里加一条(名称、描述、inputs、category、logo),前端会自动出现这个插件。
inputs 里用 f("key", "标题", "password") 这样的工厂函数声明字段:
| 参数 | 作用 |
|---|---|
component | input / password / select / switch / number / textarea / access / notification |
options | select 的选项 |
showWhen | 条件显示(例如只有开启两步验证才显示密钥字段) |
accessTypes | 授权字段只接受哪些精确类型 |
action | 字段下方的动作按钮(例如群晖「获取设备 ID」) |
三个必须做的检查
accessId字段必须带accessTypes:只按accessCategory过滤会让「部署到群晖」的下拉里出现宝塔授权。注册表见_DEPLOY_ACCESS_TYPES。inputs必须覆盖 handler 真正读的配置:把 handler 里所有config.get("xxx")的键抄出来对齐。群晖就踩过这个坑 —— handler 早就读asDefault,但表单里没有这个开关,用户只能吃默认值。- 字段标题要写清楚去哪找,例如「两步验证密钥:DSM → 个人设置 → 双重验证」。
第 4 步:加 logo(可选)
厂商图标要本地化,不要让前端直连 CDN(内网、离线环境下会变成空白块)。图标文件放在 frontend/public/logos/,元数据里给相对路径 logoFile。
新增 DNS 服务商
- 继承
BaseDnsProvider,实现add_txt/remove_txt。 - 注册到
dns.PROVIDERS。 plugins.py的ACCESS_TYPES增加授权类型,DNS_PROVIDERS增加条目。- 如果该服务商能做 DNS-01 验证,把它的 key 加进
_DNS_CAPABLE,否则证书任务的「DNS 授权」下拉里不会出现它。
新增通知渠道
notify.py实现send_xxx(config, title, content)。- 注册到
SENDERS。 plugins.py的NOTIFY_TYPES增加配置项。- 必须做业务码校验:很多国内渠道 token 错了也返回 HTTP 200,只在响应体里给
errcode/code。只判状态码会把「没发出去」记成成功。错误信息里只保留主机名,别把带 token 的完整 URL 写进日志。
新增 CA
CA 的名称、目录地址、是否要 EAB 只有 plugins.ACME_PROVIDERS 一份。引擎统一走 _ca_name() / _ca_directory() / _ca_needs_eab(),不要在引擎里手抄字典 —— 以前抄过,新增 FreeSSL 时漏改,表现是「选了 FreeSSL 却报『自定义 ACME 需要填写 ACME 目录地址』」。
验收标准
改完必须过这几关,缺一条都可能上线后翻车:
python tests/smoke.py全绿(含插件一致性断言)。- 前端能选到这个插件,表单字段齐全、必填项有校验。
- 授权类型不匹配时给出中文结论,而不是让用户对着数字 ID 猜。
- 错误路径有中文文案:业务异常只打一行,不甩堆栈,云厂商错误压成
[Code] Message。 - 新异常类登记到
engine._EXPECTED_NAMES,否则日志里会出现堆栈。 - 涉及凭据的字段,保存前 trim,留空不覆盖旧值。
相关约定
项目根目录的 AGENTS.md 是硬性约定(凭据明文查看、元数据驱动、插件覆盖率、错误文案规范等),改代码前先读一遍。与代码冲突时以它为准,并回头把代码改对。
