|
10 | 10 | from application.exception.application_error import ApplicationError |
11 | 11 | from application.model.provider_build_input import ProviderBuildInput |
12 | 12 | from application.model.machine_input import ControlMachineInput |
| 13 | +from application.model.cert_manager_input import CertManagerInput |
13 | 14 | from application.service.akash_cluster_service import AkashClusterService |
14 | 15 | from application.service.provider_service import ProviderService |
15 | 16 | from application.utils.ssh_utils import get_ssh_client |
@@ -52,7 +53,7 @@ def process_provider_build_input(data: Dict) -> ProviderBuildInput: |
52 | 53 | "message": "The provided configuration is invalid.", |
53 | 54 | "error_code": "VAL_005", |
54 | 55 | "details": [ |
55 | | - {"field": error["loc"][0], "message": error["msg"]} |
| 56 | + {"field": error["loc"][0] if error["loc"] else "__root__", "message": error["msg"]} |
56 | 57 | for error in e.errors() |
57 | 58 | ], |
58 | 59 | }, |
@@ -134,7 +135,7 @@ async def build_provider( |
134 | 135 | "message": "Invalid provider build input", |
135 | 136 | "error_code": "VAL_006", |
136 | 137 | "details": [ |
137 | | - {"field": error["loc"][0], "message": error["msg"]} |
| 138 | + {"field": error["loc"][0] if error["loc"] else "__root__", "message": error["msg"]} |
138 | 139 | for error in ve.errors() |
139 | 140 | ], |
140 | 141 | }, |
@@ -476,6 +477,100 @@ async def upgrade_provider( |
476 | 477 | ) |
477 | 478 |
|
478 | 479 |
|
| 480 | +@router.post("/provider/migrate-gateway-api", include_in_schema=False) |
| 481 | +async def migrate_gateway_api( |
| 482 | + background_tasks: BackgroundTasks, |
| 483 | + machine_input: Dict, |
| 484 | + wallet_address: str = Depends(verify_token), |
| 485 | +) -> Dict: |
| 486 | + try: |
| 487 | + control_machine = machine_input["control_machine"] |
| 488 | + keyfile_value = control_machine.get("keyfile") |
| 489 | + if keyfile_value: |
| 490 | + control_machine["keyfile"] = decode_keyfile_to_uploadfile(keyfile_value) |
| 491 | + control_machine_input = ControlMachineInput(**control_machine) |
| 492 | + |
| 493 | + cert_manager_input = CertManagerInput(**machine_input["cert_manager"]) |
| 494 | + domain = machine_input["domain"] |
| 495 | + if not isinstance(domain, str) or not domain.strip(): |
| 496 | + raise HTTPException( |
| 497 | + status_code=status.HTTP_400_BAD_REQUEST, |
| 498 | + detail={ |
| 499 | + "status": "error", |
| 500 | + "error": { |
| 501 | + "message": "domain is required and must be a non-empty string", |
| 502 | + "error_code": "VAL_010", |
| 503 | + }, |
| 504 | + }, |
| 505 | + ) |
| 506 | + if not cert_manager_input.acme_email: |
| 507 | + raise HTTPException( |
| 508 | + status_code=status.HTTP_400_BAD_REQUEST, |
| 509 | + detail={ |
| 510 | + "status": "error", |
| 511 | + "error": { |
| 512 | + "message": "cert_manager.acme_email is required for migration", |
| 513 | + "error_code": "VAL_007", |
| 514 | + }, |
| 515 | + }, |
| 516 | + ) |
| 517 | + |
| 518 | + action_id = str(uuid4()) |
| 519 | + akash_cluster_service = AkashClusterService() |
| 520 | + background_tasks.add_task( |
| 521 | + akash_cluster_service.migrate_gateway_api, |
| 522 | + action_id, |
| 523 | + control_machine_input, |
| 524 | + cert_manager_input, |
| 525 | + domain, |
| 526 | + wallet_address, |
| 527 | + ) |
| 528 | + return { |
| 529 | + "message": "Gateway API migration started successfully", |
| 530 | + "action_id": action_id, |
| 531 | + } |
| 532 | + except HTTPException: |
| 533 | + raise |
| 534 | + except ValidationError as ve: |
| 535 | + raise HTTPException( |
| 536 | + status_code=status.HTTP_400_BAD_REQUEST, |
| 537 | + detail={ |
| 538 | + "status": "error", |
| 539 | + "error": { |
| 540 | + "message": "Invalid migration input", |
| 541 | + "error_code": "VAL_008", |
| 542 | + "details": [ |
| 543 | + {"field": err["loc"][0] if err["loc"] else "__root__", "message": err["msg"]} |
| 544 | + for err in ve.errors() |
| 545 | + ], |
| 546 | + }, |
| 547 | + }, |
| 548 | + ) from None |
| 549 | + except KeyError as ke: |
| 550 | + raise HTTPException( |
| 551 | + status_code=status.HTTP_400_BAD_REQUEST, |
| 552 | + detail={ |
| 553 | + "status": "error", |
| 554 | + "error": { |
| 555 | + "message": f"Missing required field: {ke}", |
| 556 | + "error_code": "VAL_009", |
| 557 | + }, |
| 558 | + }, |
| 559 | + ) from None |
| 560 | + except Exception as e: |
| 561 | + log.exception("Error starting Gateway API migration") |
| 562 | + raise HTTPException( |
| 563 | + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
| 564 | + detail={ |
| 565 | + "status": "error", |
| 566 | + "error": { |
| 567 | + "message": f"An error occurred while starting migration: {e}", |
| 568 | + "error_code": "PRV_009", |
| 569 | + }, |
| 570 | + }, |
| 571 | + ) from e |
| 572 | + |
| 573 | + |
479 | 574 | @router.post("/restart-provider", include_in_schema=False) |
480 | 575 | async def restart_provider( |
481 | 576 | data: Dict, |
|
0 commit comments