59 lines
2.2 KiB
Python
59 lines
2.2 KiB
Python
# =============================================================================
|
||
# 企微IT智能服务台 — 阶段5 自动化 回滚补偿
|
||
# =============================================================================
|
||
# 说明:动作执行失败时,对「已执行的前置动作」做补偿(逆向操作)。
|
||
# 本期支持:病毒隔离(virus_quarantine) → 解除隔离(unisolate)。
|
||
# 其余动作(只读/推送类)无需补偿,仅记录日志。
|
||
# 补偿失败不阻断主流程(仅告警),由转人工接管兜底。
|
||
# =============================================================================
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from typing import Any
|
||
|
||
from app.integrations.base import BaseClientError
|
||
from app.integrations.factory import build_huorong_client
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class RollbackService:
|
||
"""回滚补偿服务。"""
|
||
|
||
def __init__(self, db: Any):
|
||
self.db = db
|
||
|
||
async def compensate(self, session: Any, failed_action: Any) -> None:
|
||
"""对失败动作做补偿(如有可逆操作)。
|
||
|
||
Args:
|
||
session: 自动化会话(含 meta.mapping)
|
||
failed_action: 失败的动作
|
||
"""
|
||
action_type = failed_action.action_type
|
||
if action_type != "virus_quarantine":
|
||
# 只读/推送类动作无需补偿
|
||
logger.info(f"动作 {action_type} 无需回滚补偿")
|
||
return
|
||
|
||
try:
|
||
client = await build_huorong_client(self.db)
|
||
except Exception as e: # noqa: BLE001
|
||
logger.warning(f"构建火绒客户端失败,跳过回滚: {e}")
|
||
return
|
||
if client is None:
|
||
return
|
||
|
||
mapping = (session.meta or {}).get("mapping") or {}
|
||
client_ids = (failed_action.payload or {}).get("client_ids") or mapping.get(
|
||
"client_ids"
|
||
) or []
|
||
if not client_ids:
|
||
return
|
||
try:
|
||
await client.unisolate_terminal(client_ids=client_ids)
|
||
logger.info(f"已对终端 {client_ids} 执行解除隔离补偿")
|
||
except BaseClientError as e:
|
||
logger.warning(f"回滚补偿(解除隔离)失败: {e}")
|