auto_agent/backend/app/services/software_a_service.py

62 lines
2.4 KiB
Python

from __future__ import annotations
from uuid import uuid4
from app.core.constants import (
SOFTWARE_A_TASK_STATUS_FAILED,
SOFTWARE_A_TASK_STATUS_RUNNING,
SOFTWARE_A_TASK_STATUS_SUCCEEDED,
)
from app.core.time import format_now
from app.schemas.software_a import CreateDeployTaskRequest
class SoftwareAService:
_deploy_tasks: dict[str, dict] = {}
def __init__(self, timezone_name: str) -> None:
self.timezone_name = timezone_name
def create_deploy_task(self, payload: CreateDeployTaskRequest) -> dict:
task_id = f"sa-task-{uuid4().hex[:12]}"
should_fail = self._should_fail_deploy(payload)
task_status = SOFTWARE_A_TASK_STATUS_FAILED if should_fail else SOFTWARE_A_TASK_STATUS_RUNNING
error_detail = self._build_error_detail(payload) if should_fail else None
task = {
"software_a_task_id": task_id,
"task_status": task_status,
"progress_percent": 100,
"app_code": payload.app_code,
"env": payload.env,
"version": payload.version,
"target_nodes": payload.target_nodes,
"started_at": format_now(self.timezone_name),
"finished_at": format_now(self.timezone_name),
"error_detail": error_detail,
}
self._deploy_tasks[task_id] = task
return task
def get_deploy_task(self, software_a_task_id: str) -> dict | None:
task = self._deploy_tasks.get(software_a_task_id)
if not task:
return None
if task["task_status"] == SOFTWARE_A_TASK_STATUS_FAILED:
return task
task["task_status"] = SOFTWARE_A_TASK_STATUS_SUCCEEDED
task["progress_percent"] = 100
return task
def check_permission(self, action_type: str, env: str, approval_status: str | None = None) -> tuple[bool, str]:
if env == "prod" and action_type in {"STOP_SERVICE", "RESTART_SERVICE", "DEPLOY"} and approval_status != "APPROVED":
return False, "生产环境动作默认需要额外审批"
return True, ""
def _should_fail_deploy(self, payload: CreateDeployTaskRequest) -> bool:
app_code = payload.app_code.lower()
version = payload.version.lower()
return "fail" in app_code or "fail" in version
def _build_error_detail(self, payload: CreateDeployTaskRequest) -> str:
return f"demo deploy failed for app={payload.app_code}, env={payload.env}, version={payload.version}"