""" Единый executor операции Nubes. Делает всё до /run включительно. НЕ поллит. Используется api_test.py (ручной) и scenario.py (сценарный). """ from api.utils import find_uid, uid_from_location from operations.terraform import send_params_terraform def execute_operation(client, service_id, operation, instance_uid, params, svc_op_id=None, display_name=None): """Запустить операцию и вернуть результат. Args: client: HttpClient service_id: int — ID сервиса operation: str — create/delete/modify/suspend/resume/redeploy instance_uid: str|None — UUID существующего инстанса (None для create) params: dict — {numeric_param_id: value} svc_op_id: int|None — svcOperationId (игнорируется для create) display_name: str|None — displayName (только для create) Returns: dict {ok, error, failed_step, instance_uid, op_uid, display_name} ok=True при успехе, ok=False при ошибке с failed_step. """ is_create = (operation == "create") # --- Шаг 1: POST /instances (только create) --- if is_create: if not display_name: display_name = f"autotest-{service_id}" descr = f"created by autotest" payload = {"serviceId": service_id, "displayName": display_name, "descr": descr} try: resp = client.post("/instances", payload) except Exception as e: return {"ok": False, "error": str(e), "failed_step": "instances", "instance_uid": None, "op_uid": None, "display_name": display_name} instance_uid = resp.get("instanceUid") or find_uid(resp) or uid_from_location(resp.get("_location", "")) if not instance_uid: return {"ok": False, "error": "No instanceUid in response", "failed_step": "instances", "instance_uid": None, "op_uid": None, "display_name": display_name} # --- Шаг 2: POST /instanceOperations --- if is_create: op_payload = {"instanceUid": instance_uid, "operation": operation} else: op_payload = {"instanceUid": instance_uid, "svcOperationId": svc_op_id, "operation": operation} try: op_resp = client.post("/instanceOperations", op_payload) except Exception as e: return {"ok": False, "error": str(e), "failed_step": "instanceOperations", "instance_uid": instance_uid, "op_uid": None, "display_name": display_name} op_uid = op_resp.get("instanceOperationUid") or find_uid(op_resp) or uid_from_location(op_resp.get("_location", "")) if not op_uid: return {"ok": False, "error": "No opUid in response", "failed_step": "instanceOperations", "instance_uid": instance_uid, "op_uid": None, "display_name": display_name} # --- Шаг 3-6: Параметры + run --- try: send_params_terraform(client, op_uid, params) except Exception as e: return {"ok": False, "error": str(e), "failed_step": "params", "instance_uid": instance_uid, "op_uid": op_uid, "display_name": display_name} try: client.post(f"/instanceOperations/{op_uid}/run") except Exception as e: return {"ok": False, "error": str(e), "failed_step": "run", "instance_uid": instance_uid, "op_uid": op_uid, "display_name": display_name} return {"ok": True, "error": None, "failed_step": None, "instance_uid": instance_uid, "op_uid": op_uid, "display_name": display_name}