|
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import functools |
8 | | -import json |
9 | 8 | import logging |
10 | 9 |
|
11 | 10 | from aiohttp import web |
12 | | -from jsonschema import ValidationError as JsonSchemaValidationError |
13 | 11 | from models_library.api_schemas_webserver.projects import ( |
14 | 12 | EmptyModel, |
15 | 13 | ProjectCopyOverride, |
|
18 | 16 | ProjectPatch, |
19 | 17 | ) |
20 | 18 | from models_library.generics import Envelope |
21 | | -from models_library.projects import Project |
22 | 19 | from models_library.projects_state import ProjectLocked |
23 | 20 | from models_library.rest_ordering import OrderBy |
24 | 21 | from models_library.rest_pagination import Page |
|
44 | 41 |
|
45 | 42 | from .._meta import API_VTAG as VTAG |
46 | 43 | from ..catalog.client import get_services_for_user_in_product |
47 | | -from ..director_v2 import api |
48 | 44 | from ..folders.errors import FolderAccessForbiddenError, FolderNotFoundError |
49 | 45 | from ..login.decorators import login_required |
50 | 46 | from ..resource_manager.user_sessions import PROJECT_ID_KEY, managed_resource |
|
53 | 49 | from ..users.api import get_user_fullname |
54 | 50 | from ..workspaces.errors import WorkspaceAccessForbiddenError, WorkspaceNotFoundError |
55 | 51 | from . import _crud_api_create, _crud_api_read, projects_api |
56 | | -from ._access_rights_api import check_user_project_permission |
57 | 52 | from ._common_models import ProjectPathParams, RequestContext |
58 | 53 | from ._crud_handlers_models import ( |
59 | 54 | ProjectActiveParams, |
|
63 | 58 | ProjectListWithJsonStrParams, |
64 | 59 | ) |
65 | 60 | from ._permalink_api import update_or_pop_permalink_in_project |
66 | | -from .db import ProjectDBAPI |
67 | 61 | from .exceptions import ( |
68 | 62 | ProjectDeleteError, |
69 | 63 | ProjectInvalidRightsError, |
70 | | - ProjectInvalidUsageError, |
71 | 64 | ProjectNotFoundError, |
72 | 65 | ProjectOwnerNotFoundInTheProjectAccessRightsError, |
73 | 66 | WrongTagIdsInQueryError, |
74 | 67 | ) |
75 | 68 | from .lock import get_project_locked_state |
76 | 69 | from .models import ProjectDict |
77 | | -from .nodes_utils import update_frontend_outputs |
78 | | -from .utils import ( |
79 | | - any_node_inputs_changed, |
80 | | - get_project_unavailable_services, |
81 | | - project_uses_available_services, |
82 | | -) |
| 70 | +from .utils import get_project_unavailable_services, project_uses_available_services |
83 | 71 |
|
84 | 72 | # When the user requests a project with a repo, the working copy might differ from |
85 | 73 | # the repo project. A middleware in the meta module (if active) will resolve |
@@ -425,138 +413,9 @@ async def replace_project(request: web.Request): |
425 | 413 | web.HTTPNotFound: This project was not found |
426 | 414 | """ |
427 | 415 |
|
428 | | - db: ProjectDBAPI = ProjectDBAPI.get_from_app_context(request.app) |
429 | | - req_ctx = RequestContext.parse_obj(request) |
430 | | - path_params = parse_request_path_parameters_as(ProjectPathParams, request) |
431 | | - |
432 | | - try: |
433 | | - new_project = await request.json() |
434 | | - # NOTE: this is a temporary fix until proper Model is introduced in ProjectReplace |
435 | | - # Prune state field (just in case) |
436 | | - new_project.pop("state", None) |
437 | | - new_project.pop("permalink", None) |
438 | | - |
439 | | - except json.JSONDecodeError as exc: |
440 | | - raise web.HTTPBadRequest(reason="Invalid request body") from exc |
441 | | - |
442 | | - await check_user_permission( |
443 | | - request, |
444 | | - "project.update | project.workbench.node.inputs.update", |
445 | | - context={ |
446 | | - "dbapi": db, |
447 | | - "app": request.app, |
448 | | - "project_id": f"{path_params.project_id}", |
449 | | - "user_id": req_ctx.user_id, |
450 | | - "new_data": new_project, |
451 | | - }, |
452 | | - ) |
453 | | - |
454 | | - try: |
455 | | - Project.parse_obj(new_project) # validate |
456 | | - |
457 | | - current_project = await projects_api.get_project_for_user( |
458 | | - request.app, |
459 | | - project_uuid=f"{path_params.project_id}", |
460 | | - user_id=req_ctx.user_id, |
461 | | - include_state=True, |
462 | | - ) |
463 | | - |
464 | | - if current_project["accessRights"] != new_project["accessRights"]: |
465 | | - await check_user_permission(request, "project.access_rights.update") |
466 | | - |
467 | | - if await api.is_pipeline_running( |
468 | | - request.app, req_ctx.user_id, path_params.project_id |
469 | | - ) and any_node_inputs_changed(new_project, current_project): |
470 | | - # NOTE: This is a conservative measure that we take |
471 | | - # until nodeports logic is re-designed to tackle with this |
472 | | - # particular state. |
473 | | - # |
474 | | - # This measure avoid having a state with different node *links* in the |
475 | | - # comp-tasks table and the project's workbench column. |
476 | | - # The limitation is that nodeports only "sees" those in the comptask |
477 | | - # and this table does not add the new ones since it remains "blocked" |
478 | | - # for modification from that project while the pipeline runs. Therefore |
479 | | - # any extra link created while the pipeline is running can not |
480 | | - # be managed by nodeports because it basically "cannot see it" |
481 | | - # |
482 | | - # Responds https://httpstatuses.com/409: |
483 | | - # The request could not be completed due to a conflict with the current |
484 | | - # state of the target resource (i.e. pipeline is running). This code is used in |
485 | | - # situations where the user might be able to resolve the conflict |
486 | | - # and resubmit the request (front-end will show a pop-up with message below) |
487 | | - # |
488 | | - raise web.HTTPConflict( |
489 | | - reason=f"Project {path_params.project_id} cannot be modified while pipeline is still running." |
490 | | - ) |
491 | | - |
492 | | - user_project_permission = await check_user_project_permission( |
493 | | - request.app, |
494 | | - project_id=path_params.project_id, |
495 | | - user_id=req_ctx.user_id, |
496 | | - product_name=req_ctx.product_name, |
497 | | - permission="write", |
498 | | - ) |
499 | | - |
500 | | - new_project = await db.replace_project( |
501 | | - new_project, |
502 | | - req_ctx.user_id, |
503 | | - project_uuid=f"{path_params.project_id}", |
504 | | - product_name=req_ctx.product_name, |
505 | | - ) |
506 | | - |
507 | | - await update_frontend_outputs( |
508 | | - app=request.app, |
509 | | - user_id=req_ctx.user_id, |
510 | | - project_uuid=path_params.project_id, |
511 | | - old_project=current_project, |
512 | | - new_project=new_project, |
513 | | - ) |
514 | | - |
515 | | - await api.update_dynamic_service_networks_in_project( |
516 | | - request.app, path_params.project_id |
517 | | - ) |
518 | | - await api.create_or_update_pipeline( |
519 | | - request.app, |
520 | | - req_ctx.user_id, |
521 | | - path_params.project_id, |
522 | | - product_name=req_ctx.product_name, |
523 | | - ) |
524 | | - # Appends state |
525 | | - data = await projects_api.add_project_states_for_user( |
526 | | - user_id=req_ctx.user_id, |
527 | | - project=new_project, |
528 | | - is_template=False, |
529 | | - app=request.app, |
530 | | - ) |
531 | | - # Appends folder ID |
532 | | - user_specific_project_data_db = await db.get_user_specific_project_data_db( |
533 | | - project_uuid=path_params.project_id, |
534 | | - private_workspace_user_id_or_none=( |
535 | | - req_ctx.user_id |
536 | | - if user_project_permission.workspace_id is None |
537 | | - else None |
538 | | - ), |
539 | | - ) |
540 | | - data["folderId"] = user_specific_project_data_db.folder_id |
541 | | - |
542 | | - return web.json_response({"data": data}, dumps=json_dumps) |
543 | | - |
544 | | - except JsonSchemaValidationError as exc: |
545 | | - raise web.HTTPBadRequest( |
546 | | - reason=f"Invalid project update: {exc.message}" |
547 | | - ) from exc |
548 | | - |
549 | | - except ProjectInvalidRightsError as exc: |
550 | | - raise web.HTTPForbidden( |
551 | | - reason="You do not have sufficient rights to replace the project" |
552 | | - ) from exc |
553 | | - except ProjectInvalidUsageError as exc: |
554 | | - raise web.HTTPConflict( |
555 | | - reason="You may not add or remove nodes in the workbench using this entrypoint. TIP: use dedicated add/remove node entrypoints" |
556 | | - ) from exc |
557 | | - |
558 | | - except ProjectNotFoundError as exc: |
559 | | - raise web.HTTPNotFound from exc |
| 416 | + assert request # nosec |
| 417 | + msg = "Not supported anymore" |
| 418 | + raise ValueError(msg) |
560 | 419 |
|
561 | 420 |
|
562 | 421 | @routes.patch(f"/{VTAG}/projects/{{project_id}}", name="patch_project") |
|
0 commit comments