diff --git a/apps/api/src/api/v1/approvals.py b/apps/api/src/api/v1/approvals.py index 4f3c01a1a..500300448 100644 --- a/apps/api/src/api/v1/approvals.py +++ b/apps/api/src/api/v1/approvals.py @@ -101,11 +101,22 @@ def parse_operation_from_action(action: str) -> tuple[OperationType | None, str "Scale deployment web-frontend to 5 replicas" → (SCALE_DEPLOYMENT, "web-frontend", "default") + "重新啟動 awoooi-worker 服務" + → (RESTART_DEPLOYMENT, "awoooi-worker", "default") + Returns: (operation_type, resource_name, namespace) """ action_lower = action.lower() + # Pattern: kubectl rollout restart deployment/ + kubectl_restart_match = re.search(r'kubectl\s+rollout\s+restart\s+deployment/([a-z0-9][\w.-]*)', action_lower) + if kubectl_restart_match: + deploy_name = kubectl_restart_match.group(1) + ns_match = re.search(r'-n\s+(\S+)', action_lower) + namespace = ns_match.group(1) if ns_match else "default" + return OperationType.RESTART_DEPLOYMENT, deploy_name, namespace + # Pattern: kubectl delete pod delete_pod_match = re.search(r'delete\s+pod[:\s]+([a-z0-9][\w.-]*)', action_lower) if delete_pod_match: @@ -115,7 +126,7 @@ def parse_operation_from_action(action: str) -> tuple[OperationType | None, str namespace = ns_match.group(1) if ns_match else "default" return OperationType.DELETE_POD, pod_name, namespace - # Pattern: restart deployment + # Pattern: restart deployment (English) restart_match = re.search(r'restart\s+(?:deployment[:\s]+)?([a-z0-9][\w.-]*)', action_lower) if restart_match: deploy_name = restart_match.group(1) @@ -123,6 +134,12 @@ def parse_operation_from_action(action: str) -> tuple[OperationType | None, str namespace = ns_match.group(1) if ns_match else "default" return OperationType.RESTART_DEPLOYMENT, deploy_name, namespace + # Pattern: 重新啟動 服務 (Chinese) + chinese_restart_match = re.search(r'重新啟動\s+([a-z0-9][\w.-]*)\s*服務', action) + if chinese_restart_match: + deploy_name = chinese_restart_match.group(1) + return OperationType.RESTART_DEPLOYMENT, deploy_name, "default" + # Pattern: scale deployment scale_match = re.search(r'scale\s+(?:deployment[:\s]+)?([a-z0-9][\w.-]*)', action_lower) if scale_match: @@ -131,6 +148,31 @@ def parse_operation_from_action(action: str) -> tuple[OperationType | None, str namespace = ns_match.group(1) if ns_match else "default" return OperationType.SCALE_DEPLOYMENT, deploy_name, namespace + # Pattern: 擴容 (Chinese scale) + chinese_scale_match = re.search(r'擴容\s+([a-z0-9][\w.-]*)', action) + if chinese_scale_match: + deploy_name = chinese_scale_match.group(1) + return OperationType.SCALE_DEPLOYMENT, deploy_name, "default" + + # Pattern: 擴展 副本數 (Chinese scale variant) + chinese_scale2_match = re.search(r'擴展\s+([a-z0-9][\w.-]*)\s*副本', action) + if chinese_scale2_match: + deploy_name = chinese_scale2_match.group(1) + # 移除常見的後綴如 -deployment + deploy_name = re.sub(r'-deployment$', '', deploy_name) + return OperationType.SCALE_DEPLOYMENT, deploy_name, "default" + + # Pattern: 重新啟動 (Chinese restart without 服務) + chinese_restart2_match = re.search(r'重新啟動\s+([a-z0-9][\w.-]*)', action) + if chinese_restart2_match: + resource_name = chinese_restart2_match.group(1) + # StatefulSet Pod 格式: name-N (如 postgres-primary-0) + if re.match(r'.*-\d+$', resource_name): + return OperationType.DELETE_POD, resource_name, "default" + # 移除常見的後綴 + deploy_name = re.sub(r'-deployment$', '', resource_name) + return OperationType.RESTART_DEPLOYMENT, deploy_name, "default" + return None, None, "default"