feat: add ops center and node onboarding flow

This commit is contained in:
Your Name
2026-04-18 23:52:51 +08:00
parent 246838ae4c
commit b9c29481b5
142 changed files with 89727 additions and 186 deletions

View File

@@ -0,0 +1,255 @@
import unittest
from unittest.mock import patch
from app.services.ops_service import execute_ops_runbook_sequence, resolve_ops_runbook_sequence
class OpsServiceRunbookSequenceTests(unittest.TestCase):
@patch("app.services.ops_service.get_ops_runbook")
def test_resolve_ops_runbook_sequence_uses_primary_action(self, mock_get_ops_runbook) -> None:
mock_get_ops_runbook.return_value = {
"control_sequences": [
{
"key": "release_progression",
"title": "版本发布与放量",
"status": "ready",
"status_label": "可发 Worker 灰度",
"summary": "可以直接发布。",
"reason": "launchpad 已就绪",
"target_scope_label": "Release / Launchpad / 2026.04.18",
"step_titles": ["确认发布包", "发灰度"],
"target_node_codes": ["mainland-worker-01"],
"focus_ref": {
"kind": "release_hub",
"release_id": 12,
"section": "release_launchpad",
},
"primary_label": "直接发 Worker 灰度",
"primary_action_code": "publish_latest_worker",
"primary_action_payload": {
"channel": "stable",
"release_id": 12,
},
"primary_focus_ref": {
"kind": "release_hub",
"release_id": 12,
"section": "release_launchpad",
"mode": "worker",
},
}
]
}
ok, message, data = resolve_ops_runbook_sequence(
"release_progression",
{
"requested_by": "test",
},
)
self.assertTrue(ok, message)
self.assertEqual("标准作业路径解析成功", message)
self.assertEqual("publish_latest_worker", data["driver_action_code"])
self.assertEqual("直接发 Worker 灰度", data["driver_action_label"])
self.assertEqual(["mainland-worker-01"], data["driver_node_codes"])
self.assertEqual("test/runbook/release_progression", data["driver_requested_by"])
self.assertEqual("Release / Launchpad / 2026.04.18", data["sequence"]["target_scope_label"])
self.assertEqual(["确认发布包", "发灰度"], data["sequence"]["step_titles"])
self.assertEqual("release_launchpad", data["sequence"]["focus_ref"]["section"])
self.assertEqual("worker", data["sequence"]["action_focus_ref"]["mode"])
self.assertEqual("worker", data["driver_action_payload"]["focus_ref"]["mode"])
@patch("app.services.ops_service.get_ops_runbook")
def test_resolve_ops_runbook_sequence_uses_secondary_action_and_allows_payload_override(
self,
mock_get_ops_runbook,
) -> None:
mock_get_ops_runbook.return_value = {
"control_sequences": [
{
"key": "node_onboarding",
"title": "纳管新节点",
"status": "warning",
"status_label": "有待接管节点",
"summary": "先补接入。",
"reason": "新增节点需要先纳管。",
"target_node_codes": ["mainland-worker-01"],
"secondary_label": "跑接管验收",
"secondary_action_code": "run_acceptance",
"secondary_action_payload": {
"node_code": "mainland-worker-01",
},
}
]
}
ok, message, data = resolve_ops_runbook_sequence(
"node_onboarding",
{
"secondary": True,
"requested_by": "test",
"node_codes": ["mainland-worker-02"],
"action_payload": {
"auto_approve": True,
},
},
)
self.assertTrue(ok, message)
self.assertEqual("标准作业路径解析成功", message)
self.assertEqual("run_acceptance", data["driver_action_code"])
self.assertEqual("跑接管验收", data["driver_action_label"])
self.assertEqual(["mainland-worker-02"], data["driver_node_codes"])
self.assertTrue(data["sequence"]["secondary"])
self.assertEqual(
{
"node_code": "mainland-worker-01",
"auto_approve": True,
},
data["driver_action_payload"],
)
@patch("app.services.ops_service.execute_driver_action")
@patch("app.services.ops_service.get_ops_runbook")
def test_execute_ops_runbook_sequence_uses_primary_action(
self,
mock_get_ops_runbook,
mock_execute_driver_action,
) -> None:
mock_get_ops_runbook.return_value = {
"control_sequences": [
{
"key": "release_progression",
"title": "版本发布与放量",
"status": "ready",
"status_label": "可发 Worker 灰度",
"summary": "可以直接发布。",
"reason": "launchpad 已就绪",
"target_node_codes": ["mainland-worker-01"],
"primary_action_code": "publish_latest_worker",
"primary_action_payload": {
"channel": "stable",
"release_id": 12,
},
"secondary_action_code": "focus_release_hub",
"secondary_action_payload": {
"release_id": 12,
},
}
]
}
mock_execute_driver_action.return_value = (
True,
"Release rollout 已创建",
{
"handled": True,
"mode": "smart-release-rollout",
},
)
ok, message, data = execute_ops_runbook_sequence(
"release_progression",
{
"requested_by": "test",
},
)
self.assertTrue(ok, message)
self.assertEqual("Release rollout 已创建", message)
self.assertTrue(data["handled"])
self.assertEqual("publish_latest_worker", data["driver_action_code"])
self.assertEqual(["mainland-worker-01"], data["driver_node_codes"])
self.assertEqual("release_progression", data["sequence_key"])
self.assertEqual("版本发布与放量", data["sequence"]["title"])
mock_execute_driver_action.assert_called_once_with(
{
"action_code": "publish_latest_worker",
"node_codes": ["mainland-worker-01"],
"action_payload": {
"channel": "stable",
"release_id": 12,
},
"requested_by": "test/runbook/release_progression",
}
)
@patch("app.services.ops_service.execute_driver_action")
@patch("app.services.ops_service.get_ops_runbook")
def test_execute_ops_runbook_sequence_uses_secondary_action_and_allows_payload_override(
self,
mock_get_ops_runbook,
mock_execute_driver_action,
) -> None:
mock_get_ops_runbook.return_value = {
"control_sequences": [
{
"key": "node_onboarding",
"title": "纳管新节点",
"status": "warning",
"status_label": "有待接管节点",
"summary": "先补接入。",
"reason": "新增节点需要先纳管。",
"target_node_codes": ["mainland-worker-01"],
"primary_action_code": "bootstrap_run",
"primary_action_payload": {
"node_code": "mainland-worker-01",
},
"secondary_action_code": "run_acceptance",
"secondary_action_payload": {
"node_code": "mainland-worker-01",
},
}
]
}
mock_execute_driver_action.return_value = (
True,
"",
{
"handled": True,
"mode": "ui-intent",
},
)
ok, message, data = execute_ops_runbook_sequence(
"node_onboarding",
{
"secondary": True,
"requested_by": "test",
"node_codes": ["mainland-worker-02"],
"action_payload": {
"auto_approve": True,
},
},
)
self.assertTrue(ok, message)
self.assertEqual("", message)
self.assertTrue(data["handled"])
self.assertEqual("run_acceptance", data["driver_action_code"])
self.assertEqual(["mainland-worker-02"], data["driver_node_codes"])
self.assertTrue(data["sequence"]["secondary"])
mock_execute_driver_action.assert_called_once_with(
{
"action_code": "run_acceptance",
"node_codes": ["mainland-worker-02"],
"action_payload": {
"node_code": "mainland-worker-01",
"auto_approve": True,
},
"requested_by": "test/runbook/node_onboarding",
}
)
@patch("app.services.ops_service.get_ops_runbook")
def test_execute_ops_runbook_sequence_returns_error_when_sequence_missing(self, mock_get_ops_runbook) -> None:
mock_get_ops_runbook.return_value = {"control_sequences": []}
ok, message, data = execute_ops_runbook_sequence("missing-sequence", {})
self.assertFalse(ok)
self.assertEqual("标准作业路径不存在", message)
self.assertEqual("missing-sequence", data["sequence_key"])
if __name__ == "__main__":
unittest.main()