Save computes to database

This commit is contained in:
grossmj committed 2021-04-05 14:21:41 +09:30
1 parent e607793e74
commit 566e326b57
13 files changed
+515 -337

No files matched your search

+39 -47
View File
@@ -19,20 +19,23 @@
API routes for computes.
"""
from fastapi import APIRouter, status
from fastapi.encoders import jsonable_encoder
from fastapi import APIRouter, Depends, status
from typing import List, Union
from uuid import UUID
from gns3server.controller import Controller
from gns3server.db.repositories.computes import ComputesRepository
from gns3server.services.computes import ComputesService
from gns3server import schemas
router = APIRouter()
from .dependencies.database import get_repository
responses = {
404: {"model": schemas.ErrorMessage, "description": "Compute not found"}
}
router = APIRouter(responses=responses)
@router.post("",
status_code=status.HTTP_201_CREATED,
@@ -40,69 +43,73 @@ responses = {
responses={404: {"model": schemas.ErrorMessage, "description": "Could not connect to compute"},
409: {"model": schemas.ErrorMessage, "description": "Could not create compute"},
401: {"model": schemas.ErrorMessage, "description": "Invalid authentication for compute"}})
async def create_compute(compute_data: schemas.ComputeCreate):
async def create_compute(
compute_create: schemas.ComputeCreate,
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
) -> schemas.Compute:
"""
Create a new compute on the controller.
"""
compute = await Controller.instance().add_compute(**jsonable_encoder(compute_data, exclude_unset=True),
connect=False)
return compute.__json__()
return await ComputesService(computes_repo).create_compute(compute_create)
@router.get("/{compute_id}",
response_model=schemas.Compute,
response_model_exclude_unset=True,
responses=responses)
def get_compute(compute_id: Union[str, UUID]):
response_model_exclude_unset=True)
async def get_compute(
compute_id: Union[str, UUID],
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
) -> schemas.Compute:
"""
Return a compute from the controller.
"""
compute = Controller.instance().get_compute(str(compute_id))
return compute.__json__()
return await ComputesService(computes_repo).get_compute(compute_id)
@router.get("",
response_model=List[schemas.Compute],
response_model_exclude_unset=True)
async def get_computes():
async def get_computes(
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
) -> List[schemas.Compute]:
"""
Return all computes known by the controller.
"""
controller = Controller.instance()
return [c.__json__() for c in controller.computes.values()]
return await ComputesService(computes_repo).get_computes()
@router.put("/{compute_id}",
response_model=schemas.Compute,
response_model_exclude_unset=True,
responses=responses)
async def update_compute(compute_id: Union[str, UUID], compute_data: schemas.ComputeUpdate):
response_model_exclude_unset=True)
async def update_compute(
compute_id: Union[str, UUID],
compute_update: schemas.ComputeUpdate,
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
) -> schemas.Compute:
"""
Update a compute on the controller.
"""
compute = Controller.instance().get_compute(str(compute_id))
# exclude compute_id because we only use it when creating a new compute
await compute.update(**jsonable_encoder(compute_data, exclude_unset=True, exclude={"compute_id"}))
return compute.__json__()
return await ComputesService(computes_repo).update_compute(compute_id, compute_update)
@router.delete("/{compute_id}",
status_code=status.HTTP_204_NO_CONTENT,
responses=responses)
async def delete_compute(compute_id: Union[str, UUID]):
status_code=status.HTTP_204_NO_CONTENT)
async def delete_compute(
compute_id: Union[str, UUID],
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
):
"""
Delete a compute from the controller.
"""
await Controller.instance().delete_compute(str(compute_id))
await ComputesService(computes_repo).delete_compute(compute_id)
@router.get("/{compute_id}/{emulator}/images",
responses=responses)
@router.get("/{compute_id}/{emulator}/images")
async def get_images(compute_id: Union[str, UUID], emulator: str):
"""
Return the list of images available on a compute for a given emulator type.
@@ -113,8 +120,7 @@ async def get_images(compute_id: Union[str, UUID], emulator: str):
return await compute.images(emulator)
@router.get("/{compute_id}/{emulator}/{endpoint_path:path}",
responses=responses)
@router.get("/{compute_id}/{emulator}/{endpoint_path:path}")
async def forward_get(compute_id: Union[str, UUID], emulator: str, endpoint_path: str):
"""
Forward a GET request to a compute.
@@ -126,8 +132,7 @@ async def forward_get(compute_id: Union[str, UUID], emulator: str, endpoint_path
return result
@router.post("/{compute_id}/{emulator}/{endpoint_path:path}",
responses=responses)
@router.post("/{compute_id}/{emulator}/{endpoint_path:path}")
async def forward_post(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict):
"""
Forward a POST request to a compute.
@@ -138,8 +143,7 @@ async def forward_post(compute_id: Union[str, UUID], emulator: str, endpoint_pat
return await compute.forward("POST", emulator, endpoint_path, data=compute_data)
@router.put("/{compute_id}/{emulator}/{endpoint_path:path}",
responses=responses)
@router.put("/{compute_id}/{emulator}/{endpoint_path:path}")
async def forward_put(compute_id: Union[str, UUID], emulator: str, endpoint_path: str, compute_data: dict):
"""
Forward a PUT request to a compute.
@@ -150,8 +154,7 @@ async def forward_put(compute_id: Union[str, UUID], emulator: str, endpoint_path
return await compute.forward("PUT", emulator, endpoint_path, data=compute_data)
@router.post("/{compute_id}/auto_idlepc",
responses=responses)
@router.post("/{compute_id}/auto_idlepc")
async def autoidlepc(compute_id: Union[str, UUID], auto_idle_pc: schemas.AutoIdlePC):
"""
Find a suitable Idle-PC value for a given IOS image. This may take a few minutes.
@@ -162,14 +165,3 @@ async def autoidlepc(compute_id: Union[str, UUID], auto_idle_pc: schemas.AutoIdl
auto_idle_pc.platform,
auto_idle_pc.image,
auto_idle_pc.ram)
@router.get("/{compute_id}/ports",
deprecated=True,
responses=responses)
async def ports(compute_id: Union[str, UUID]):
"""
Return ports information for a given compute.
"""
return await Controller.instance().compute_ports(str(compute_id))
+18 -19
View File
@@ -44,43 +44,42 @@ router = APIRouter()
@router.get("", response_model=List[schemas.User])
async def get_users(user_repo: UsersRepository = Depends(get_repository(UsersRepository))) -> List[schemas.User]:
async def get_users(users_repo: UsersRepository = Depends(get_repository(UsersRepository))) -> List[schemas.User]:
"""
Get all users.
"""
users = await user_repo.get_users()
return users
return await users_repo.get_users()
@router.post("", response_model=schemas.User, status_code=status.HTTP_201_CREATED)
async def create_user(
new_user: schemas.UserCreate,
user_repo: UsersRepository = Depends(get_repository(UsersRepository))
user_create: schemas.UserCreate,
users_repo: UsersRepository = Depends(get_repository(UsersRepository))
) -> schemas.User:
"""
Create a new user.
"""
if await user_repo.get_user_by_username(new_user.username):
raise ControllerBadRequestError(f"Username '{new_user.username}' is already registered")
if await users_repo.get_user_by_username(user_create.username):
raise ControllerBadRequestError(f"Username '{user_create.username}' is already registered")
if new_user.email and await user_repo.get_user_by_email(new_user.email):
raise ControllerBadRequestError(f"Email '{new_user.email}' is already registered")
if user_create.email and await users_repo.get_user_by_email(user_create.email):
raise ControllerBadRequestError(f"Email '{user_create.email}' is already registered")
return await user_repo.create_user(new_user)
return await users_repo.create_user(user_create)
@router.get("/{user_id}", response_model=schemas.User)
async def get_user(
user_id: UUID,
user_repo: UsersRepository = Depends(get_repository(UsersRepository))
users_repo: UsersRepository = Depends(get_repository(UsersRepository))
) -> schemas.User:
"""
Get an user.
"""
user = await user_repo.get_user(user_id)
user = await users_repo.get_user(user_id)
if not user:
raise ControllerNotFoundError(f"User '{user_id}' not found")
return user
@@ -89,14 +88,14 @@ async def get_user(
@router.put("/{user_id}", response_model=schemas.User)
async def update_user(
user_id: UUID,
update_user: schemas.UserUpdate,
user_repo: UsersRepository = Depends(get_repository(UsersRepository))
user_update: schemas.UserUpdate,
users_repo: UsersRepository = Depends(get_repository(UsersRepository))
) -> schemas.User:
"""
Update an user.
"""
user = await user_repo.update_user(user_id, update_user)
user = await users_repo.update_user(user_id, user_update)
if not user:
raise ControllerNotFoundError(f"User '{user_id}' not found")
return user
@@ -105,7 +104,7 @@ async def update_user(
@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_user(
user_id: UUID,
user_repo: UsersRepository = Depends(get_repository(UsersRepository)),
users_repo: UsersRepository = Depends(get_repository(UsersRepository)),
current_user: schemas.User = Depends(get_current_active_user)
) -> None:
"""
@@ -115,21 +114,21 @@ async def delete_user(
if current_user.is_superuser:
raise ControllerUnauthorizedError("The super user cannot be deleted")
success = await user_repo.delete_user(user_id)
success = await users_repo.delete_user(user_id)
if not success:
raise ControllerNotFoundError(f"User '{user_id}' not found")
@router.post("/login", response_model=schemas.Token)
async def login(
user_repo: UsersRepository = Depends(get_repository(UsersRepository)),
users_repo: UsersRepository = Depends(get_repository(UsersRepository)),
form_data: OAuth2PasswordRequestForm = Depends()
) -> schemas.Token:
"""
User login.
"""
user = await user_repo.authenticate_user(username=form_data.username, password=form_data.password)
user = await users_repo.authenticate_user(username=form_data.username, password=form_data.password)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
detail="Authentication was unsuccessful.",