feat: add ops center and node onboarding flow
This commit is contained in:
563
docs/schemas/ops_playbook_contract.md
Normal file
563
docs/schemas/ops_playbook_contract.md
Normal file
@@ -0,0 +1,563 @@
|
||||
# domainCheck Ops Playbook Contract
|
||||
|
||||
## 1. 目标
|
||||
|
||||
这份文档用于冻结 `playbook catalog / preview / run / events` 的正式 contract。
|
||||
|
||||
这层的定位不是“页面里的一个弹窗”,而是:
|
||||
|
||||
- 控制面的正式编排对象
|
||||
- 海外 Codex 驾驶员可消费的标准作业对象
|
||||
- Driver / Runbook / Release / Inspection 之间的统一中间层
|
||||
|
||||
核心原则:
|
||||
|
||||
- 一次标准编排 = 一次 `playbook run`
|
||||
- 页面、CLI、Codex 必须共用同一份 `playbook` / `playbook run` 结构
|
||||
- `playbook run` 只负责创建与聚合正式 `ops job`
|
||||
- 不允许前端再把“标准巡检 / 接管验收 / 现场日志”退回成零散按钮逻辑
|
||||
|
||||
建议与 [ops_job_contract.md](/www/wwwroot/getDomain/docs/schemas/ops_job_contract.md:1) 配套阅读。
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前接口面
|
||||
|
||||
当前已落地的主入口:
|
||||
|
||||
- `GET /api/v1/ops/playbooks`
|
||||
- `POST /api/v1/ops/playbooks/preview`
|
||||
- `POST /api/v1/ops/playbooks/execute`
|
||||
- `GET /api/v1/ops/playbook-runs`
|
||||
- `GET /api/v1/ops/playbook-runs/{run_code}`
|
||||
- `GET /api/v1/ops/playbook-runs/{run_code}/events`
|
||||
- `POST /api/v1/ops/playbook-runs/{run_code}/rerun`
|
||||
- `POST /api/v1/ops/playbook-runs/{run_code}/cancel`
|
||||
|
||||
并且这层已经被以下入口复用:
|
||||
|
||||
- `driver action -> open_playbook_dialog`
|
||||
- `runbook sequence -> secondary_resolution`
|
||||
- `inspection`
|
||||
- `activity-stream`
|
||||
|
||||
所以后续不应再新造第四套“标准作业对象”。
|
||||
|
||||
---
|
||||
|
||||
## 3. Playbook Catalog Object
|
||||
|
||||
来源:
|
||||
|
||||
- `GET /api/v1/ops/playbooks`
|
||||
- `preview / execute` 返回体中的 `playbook`
|
||||
|
||||
最小字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"key": "inspection.standard",
|
||||
"group_key": "diagnostics",
|
||||
"group_title": "标准巡检",
|
||||
"title": "标准巡检",
|
||||
"description": "按 健康快照 -> Worker 日志 -> 诊断包 的顺序,对目标节点做一次标准联调巡检。",
|
||||
"target_scope": "node-set",
|
||||
"default_execution_mode": "remote-agent",
|
||||
"default_execution_mode_label": "Node Agent",
|
||||
"execution_modes": [
|
||||
"remote-agent",
|
||||
"ssh"
|
||||
],
|
||||
"execution_mode_options": [
|
||||
{
|
||||
"value": "remote-agent",
|
||||
"label": "Node Agent",
|
||||
"is_default": true
|
||||
},
|
||||
{
|
||||
"value": "ssh",
|
||||
"label": "SSH",
|
||||
"is_default": false
|
||||
}
|
||||
],
|
||||
"default_auto_approve": true,
|
||||
"stop_on_failure": true,
|
||||
"steps": [
|
||||
{
|
||||
"step_key": "health",
|
||||
"title": "采集健康快照",
|
||||
"template_key": "health.snapshot",
|
||||
"payload": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
正式约束:
|
||||
|
||||
- `key`
|
||||
- 是 Playbook 的稳定主键
|
||||
- `group_key`
|
||||
- 用于页面、CLI、Codex 做标准分组,不应用 `title` 猜
|
||||
- `execution_modes`
|
||||
- 是能力白名单,不是建议文案
|
||||
- `stop_on_failure`
|
||||
- 是编排级行为,不是某一步骤的临时说明
|
||||
|
||||
---
|
||||
|
||||
## 4. Playbook Preview Contract
|
||||
|
||||
来源:
|
||||
|
||||
- `POST /api/v1/ops/playbooks/preview`
|
||||
|
||||
最小请求体:
|
||||
|
||||
```json
|
||||
{
|
||||
"playbook_key": "inspection.standard",
|
||||
"node_codes": [
|
||||
"mainland-worker-01"
|
||||
],
|
||||
"execution_mode": "remote-agent",
|
||||
"auto_approve": true,
|
||||
"requested_by": "web-ui"
|
||||
}
|
||||
```
|
||||
|
||||
最小返回体:
|
||||
|
||||
```json
|
||||
{
|
||||
"playbook": {},
|
||||
"requested_by": "web-ui",
|
||||
"execution_mode": "remote-agent",
|
||||
"execution_mode_label": "Node Agent",
|
||||
"auto_approve": true,
|
||||
"target_nodes_total": 1,
|
||||
"target_node_codes": [
|
||||
"mainland-worker-01"
|
||||
],
|
||||
"step_count": 3,
|
||||
"expected_jobs_total": 3,
|
||||
"template_keys": [
|
||||
"health.snapshot",
|
||||
"logs.collect",
|
||||
"diagnostics.collect"
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"order": 1,
|
||||
"step_key": "health",
|
||||
"title": "采集健康快照",
|
||||
"template_key": "health.snapshot",
|
||||
"action": "health.snapshot",
|
||||
"payload": {},
|
||||
"execution_mode": "remote-agent",
|
||||
"execution_mode_label": "Node Agent",
|
||||
"auto_approve": true,
|
||||
"target_nodes_total": 1,
|
||||
"expected_jobs": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
预览阶段必须回答:
|
||||
|
||||
- 最终执行方式是什么
|
||||
- 总共会展开多少步
|
||||
- 每步会展开成什么模板
|
||||
- 总共会生成多少个 `ops job`
|
||||
|
||||
这样页面、CLI、Codex 才能在执行前看见“这次会做什么”。
|
||||
|
||||
---
|
||||
|
||||
## 5. Playbook Run Object
|
||||
|
||||
来源:
|
||||
|
||||
- `GET /api/v1/ops/playbook-runs`
|
||||
- `GET /api/v1/ops/playbook-runs/{run_code}`
|
||||
- `POST /api/v1/ops/playbooks/execute`
|
||||
|
||||
最小字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"run_code": "playbook-20260418-001",
|
||||
"playbook_key": "inspection.standard",
|
||||
"playbook_title": "标准巡检",
|
||||
"group_key": "diagnostics",
|
||||
"group_title": "标准巡检",
|
||||
"requested_by": "web-ui",
|
||||
"execution_mode": "remote-agent",
|
||||
"execution_mode_label": "Node Agent",
|
||||
"stop_on_failure": true,
|
||||
"step_count": 3,
|
||||
"expected_jobs_total": 3,
|
||||
"target_nodes_total": 1,
|
||||
"target_node_codes": [
|
||||
"mainland-worker-01"
|
||||
],
|
||||
"created_at": "2026-04-18 06:30:00",
|
||||
"updated_at": "2026-04-18 06:31:10",
|
||||
"status": "running",
|
||||
"status_label": "收口中",
|
||||
"status_counts": {
|
||||
"queued": 1,
|
||||
"running": 1,
|
||||
"success": 1
|
||||
},
|
||||
"jobs_total": 3,
|
||||
"success_jobs_total": 1,
|
||||
"terminal_jobs_total": 1,
|
||||
"completion_percent": 33.3,
|
||||
"steps_total": 3,
|
||||
"steps_success": 1,
|
||||
"steps_running": 1,
|
||||
"steps_problem": 0,
|
||||
"steps_terminal": 1,
|
||||
"focus_level": "warning",
|
||||
"focus_step_key": "worker_logs",
|
||||
"focus_step_title": "收集 Worker 日志",
|
||||
"focus_summary": "收集 Worker 日志 当前仍在执行,先等待回执或检查对应节点事件流。",
|
||||
"summary": "收集 Worker 日志 当前仍在执行,先等待回执或检查对应节点事件流。",
|
||||
"summary_text": "收集 Worker 日志 当前仍在执行,先等待回执或检查对应节点事件流。",
|
||||
"focus_ref": {
|
||||
"kind": "playbook_run",
|
||||
"run_code": "playbook-20260418-001",
|
||||
"playbook_key": "inspection.standard",
|
||||
"group_key": "diagnostics",
|
||||
"focus_step_key": "worker_logs",
|
||||
"focus_step_title": "收集 Worker 日志",
|
||||
"event_key": "",
|
||||
"node_code": ""
|
||||
},
|
||||
"problem_steps": [],
|
||||
"active_steps": [],
|
||||
"latest_job": {},
|
||||
"steps": []
|
||||
}
|
||||
```
|
||||
|
||||
正式定义:
|
||||
|
||||
> `playbook run` 是一轮标准编排在控制面的聚合对象,不是某一条单独任务。
|
||||
|
||||
也就是说:
|
||||
|
||||
- `ops job` 是执行颗粒度
|
||||
- `playbook run` 是观察、重跑、取消、钻取的编排颗粒度
|
||||
|
||||
---
|
||||
|
||||
## 6. Playbook Step Object
|
||||
|
||||
`playbook run.steps[]` 的最小结构:
|
||||
|
||||
```json
|
||||
{
|
||||
"step_key": "worker_logs",
|
||||
"title": "收集 Worker 日志",
|
||||
"template_key": "logs.collect",
|
||||
"order": 2,
|
||||
"jobs_total": 1,
|
||||
"nodes_total": 1,
|
||||
"target_node_codes": [
|
||||
"mainland-worker-01"
|
||||
],
|
||||
"status_counts": {
|
||||
"running": 1
|
||||
},
|
||||
"terminal_jobs_total": 0,
|
||||
"success_jobs_total": 0,
|
||||
"status": "running",
|
||||
"status_label": "收口中",
|
||||
"completion_percent": 0.0,
|
||||
"summary": "收集 Worker 日志 当前处于执行中,可继续观察该步骤事件。",
|
||||
"summary_text": "收集 Worker 日志 当前处于执行中,可继续观察该步骤事件。",
|
||||
"focus_ref": {
|
||||
"kind": "playbook_run",
|
||||
"run_code": "playbook-20260418-001",
|
||||
"playbook_key": "inspection.standard",
|
||||
"group_key": "diagnostics",
|
||||
"focus_step_key": "worker_logs",
|
||||
"focus_step_title": "收集 Worker 日志",
|
||||
"event_key": "",
|
||||
"node_code": ""
|
||||
},
|
||||
"latest_job": {}
|
||||
}
|
||||
```
|
||||
|
||||
推荐 step 状态:
|
||||
|
||||
- `queued`
|
||||
- `running`
|
||||
- `success`
|
||||
- `attention`
|
||||
|
||||
规则:
|
||||
|
||||
- 只要该步骤出现失败、阻断、取消等终态问题,应收口为 `attention`
|
||||
- 页面与 Codex 都应优先盯 `problem_steps / active_steps`,而不是自己遍历所有子任务推断
|
||||
|
||||
---
|
||||
|
||||
## 7. Playbook Event Stream
|
||||
|
||||
来源:
|
||||
|
||||
- `GET /api/v1/ops/playbook-runs/{run_code}/events`
|
||||
|
||||
最小返回体:
|
||||
|
||||
```json
|
||||
{
|
||||
"run_code": "playbook-20260418-001",
|
||||
"playbook_run": {},
|
||||
"events": [
|
||||
{
|
||||
"job_id": 123,
|
||||
"job_code": "ops-20260418-123",
|
||||
"run_code": "playbook-20260418-001",
|
||||
"job_status": "running",
|
||||
"job_status_label": "收口中",
|
||||
"action": "logs.collect",
|
||||
"target_node_code": "mainland-worker-01",
|
||||
"step_key": "worker_logs",
|
||||
"step_title": "收集 Worker 日志",
|
||||
"event_type": "job_running",
|
||||
"level": "info",
|
||||
"level_label": "信息",
|
||||
"message": "开始收集 Worker 日志",
|
||||
"summary": "开始收集 Worker 日志",
|
||||
"summary_text": "开始收集 Worker 日志",
|
||||
"payload": {},
|
||||
"event_key": "job-event:1001",
|
||||
"occurred_at": "2026-04-18 06:31:00",
|
||||
"focus_ref": {
|
||||
"kind": "playbook_run",
|
||||
"run_code": "playbook-20260418-001",
|
||||
"playbook_key": "inspection.standard",
|
||||
"group_key": "diagnostics",
|
||||
"focus_step_key": "worker_logs",
|
||||
"focus_step_title": "收集 Worker 日志",
|
||||
"event_key": "job-event:1001",
|
||||
"node_code": "mainland-worker-01"
|
||||
},
|
||||
"created_at": "2026-04-18 06:31:00"
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"total": 1,
|
||||
"returned_total": 1,
|
||||
"available_step_counts": {
|
||||
"worker_logs": 1
|
||||
},
|
||||
"available_node_counts": {
|
||||
"mainland-worker-01": 1
|
||||
},
|
||||
"level_counts": {
|
||||
"info": 1
|
||||
},
|
||||
"event_type_counts": {
|
||||
"job_running": 1
|
||||
},
|
||||
"job_status_counts": {
|
||||
"running": 1
|
||||
},
|
||||
"latest_at": "2026-04-18 06:31:00",
|
||||
"filters": {
|
||||
"step_key": "",
|
||||
"node_code": "",
|
||||
"limit": 80
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这层必须支持:
|
||||
|
||||
- 按 `step_key` 过滤
|
||||
- 按 `node_code` 过滤
|
||||
- 快速看到最近活动时间
|
||||
|
||||
否则 `playbook run` 只能看总览,不能真正钻取。
|
||||
|
||||
---
|
||||
|
||||
## 8. 正式 Playbook Key 语义
|
||||
|
||||
当前最值得冻结成正式对象的 key:
|
||||
|
||||
### 8.1 `onboarding.bootstrap`
|
||||
|
||||
定位:
|
||||
|
||||
- 生成节点接入工单
|
||||
|
||||
执行方式:
|
||||
|
||||
- 仅 `control-plane`
|
||||
|
||||
正式语义:
|
||||
|
||||
- 不直接接管节点
|
||||
- 只创建标准接入方案对象
|
||||
|
||||
### 8.2 `onboarding.acceptance`
|
||||
|
||||
定位:
|
||||
|
||||
- 新节点接管后标准验收
|
||||
|
||||
当前标准步骤:
|
||||
|
||||
1. `health.snapshot`
|
||||
2. `service.status(node-agent)`
|
||||
3. `logs.collect(node-agent)`
|
||||
4. `service.status(worker)`
|
||||
5. `logs.collect(worker)`
|
||||
|
||||
### 8.3 `inspection.standard`
|
||||
|
||||
定位:
|
||||
|
||||
- 标准巡检
|
||||
|
||||
当前标准步骤:
|
||||
|
||||
1. `health.snapshot`
|
||||
2. `logs.collect(worker)`
|
||||
3. `diagnostics.collect`
|
||||
|
||||
正式要求:
|
||||
|
||||
- 这是 release / rollout 之前最核心的健康观察面
|
||||
|
||||
### 8.4 `scene.logs.key`
|
||||
|
||||
定位:
|
||||
|
||||
- 关键现场日志样本
|
||||
|
||||
正式要求:
|
||||
|
||||
- 默认比 `scene.logs.full` 更轻
|
||||
- 适合先看现场,再决定是否升级取证
|
||||
|
||||
### 8.5 `scene.logs.full`
|
||||
|
||||
定位:
|
||||
|
||||
- 全量现场取证
|
||||
|
||||
正式要求:
|
||||
|
||||
- 应明确比 `scene.logs.key` 更重
|
||||
- 默认应同时补诊断包
|
||||
|
||||
### 8.6 `scene.diagnostics`
|
||||
|
||||
定位:
|
||||
|
||||
- 轻量诊断包
|
||||
|
||||
正式要求:
|
||||
|
||||
- 适合作为参与节点的常规取证动作
|
||||
|
||||
---
|
||||
|
||||
## 9. 执行模式 Contract
|
||||
|
||||
推荐模式:
|
||||
|
||||
- `remote-agent`
|
||||
- `ssh`
|
||||
- `control-plane`
|
||||
|
||||
正式约束:
|
||||
|
||||
- `remote-agent`
|
||||
- 正式日常运维默认模式
|
||||
- `ssh`
|
||||
- 仅用于首发接管与应急救援
|
||||
- `control-plane`
|
||||
- 只适合控制面本地对象生成或极少量控制面动作
|
||||
|
||||
页面、CLI、Codex 不能自己发明第四种临时模式。
|
||||
|
||||
---
|
||||
|
||||
## 10. Playbook Run 状态机
|
||||
|
||||
推荐状态:
|
||||
|
||||
- `queued`
|
||||
- `running`
|
||||
- `success`
|
||||
- `attention`
|
||||
|
||||
含义:
|
||||
|
||||
- `queued`
|
||||
- 子任务刚创建,尚未出现有效执行推进
|
||||
- `running`
|
||||
- 已有子任务进入 `dispatching / running / awaiting_approval`
|
||||
- `success`
|
||||
- 全部子任务收口成功
|
||||
- `attention`
|
||||
- 任一步骤出现失败、阻断、取消或部分成功,需要人工关注
|
||||
|
||||
正式规则:
|
||||
|
||||
- 页面上的“标准巡检状态”
|
||||
- `activity-stream` 中的 playbook run 摘要
|
||||
- Driver / Codex 的推荐动作
|
||||
|
||||
都必须共用这一套状态语义。
|
||||
|
||||
---
|
||||
|
||||
## 11. 与 Driver / Runbook / Release 的关系
|
||||
|
||||
正式收口规则:
|
||||
|
||||
- Driver 不直接“模拟巡检”
|
||||
- 应优先跳转或创建 `playbook run`
|
||||
- Runbook Sequence 不直接展开 shell
|
||||
- 应优先收口到 `driver action` 或 `playbook`
|
||||
- Release / Rollout 不自己维护另一套巡检摘要
|
||||
- 应优先消费 `inspection.standard` 的最近结果
|
||||
|
||||
也就是说:
|
||||
|
||||
- `scene` 是现场观察对象
|
||||
- `inspection` 是标准健康对象
|
||||
- `release / rollout` 是发布对象
|
||||
|
||||
三者不能再各自维护不同的“日志 / 诊断 / 巡检”定义。
|
||||
|
||||
---
|
||||
|
||||
## 12. 正式要求
|
||||
|
||||
后续继续演进时,必须保持:
|
||||
|
||||
1. `playbook catalog`
|
||||
- 是稳定 contract,而不是页面枚举
|
||||
2. `playbook preview`
|
||||
- 是执行前的唯一结构化预览面
|
||||
3. `playbook run`
|
||||
- 是页面、CLI、Codex 共同观察的一轮编排对象
|
||||
4. `playbook events`
|
||||
- 是整轮编排的钻取视角
|
||||
5. 接管验收、标准巡检、现场观察
|
||||
- 优先都收进 `playbook`
|
||||
|
||||
这样这套编排才能成为真正的正式平台能力,而不是一组“看起来像流程”的按钮。
|
||||
Reference in New Issue
Block a user