mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
Use black with -l 120 param.
This commit is contained in:
1 parent
f928738bd5
commit
c021e21309
194 files changed
+6034
-4564
No files matched your search
@@ -25,12 +25,13 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("")
|
||||
async def get_appliances(update: Optional[bool] = None, symbol_theme: Optional[str] = "Classic"):
|
||||
async def get_appliances(update: Optional[bool] = None, symbol_theme: Optional[str] = "Classic"):
|
||||
"""
|
||||
Return all appliances known by the controller.
|
||||
"""
|
||||
|
||||
from gns3server.controller import Controller
|
||||
|
||||
controller = Controller.instance()
|
||||
if update:
|
||||
await controller.appliance_manager.download_appliances()
|
||||
|
||||
@@ -29,22 +29,24 @@ from gns3server import schemas
|
||||
|
||||
from .dependencies.database import get_repository
|
||||
|
||||
responses = {
|
||||
404: {"model": schemas.ErrorMessage, "description": "Compute not found"}
|
||||
}
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Compute not found"}}
|
||||
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Compute,
|
||||
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"}})
|
||||
@router.post(
|
||||
"",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Compute,
|
||||
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_create: schemas.ComputeCreate,
|
||||
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
|
||||
compute_create: schemas.ComputeCreate,
|
||||
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository)),
|
||||
) -> schemas.Compute:
|
||||
"""
|
||||
Create a new compute on the controller.
|
||||
@@ -53,12 +55,9 @@ async def create_compute(
|
||||
return await ComputesService(computes_repo).create_compute(compute_create)
|
||||
|
||||
|
||||
@router.get("/{compute_id}",
|
||||
response_model=schemas.Compute,
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("/{compute_id}", response_model=schemas.Compute, response_model_exclude_unset=True)
|
||||
async def get_compute(
|
||||
compute_id: Union[str, UUID],
|
||||
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
|
||||
compute_id: Union[str, UUID], computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
|
||||
) -> schemas.Compute:
|
||||
"""
|
||||
Return a compute from the controller.
|
||||
@@ -67,11 +66,9 @@ async def get_compute(
|
||||
return await ComputesService(computes_repo).get_compute(compute_id)
|
||||
|
||||
|
||||
@router.get("",
|
||||
response_model=List[schemas.Compute],
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("", response_model=List[schemas.Compute], response_model_exclude_unset=True)
|
||||
async def get_computes(
|
||||
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
|
||||
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository)),
|
||||
) -> List[schemas.Compute]:
|
||||
"""
|
||||
Return all computes known by the controller.
|
||||
@@ -80,13 +77,11 @@ async def get_computes(
|
||||
return await ComputesService(computes_repo).get_computes()
|
||||
|
||||
|
||||
@router.put("/{compute_id}",
|
||||
response_model=schemas.Compute,
|
||||
response_model_exclude_unset=True)
|
||||
@router.put("/{compute_id}", response_model=schemas.Compute, 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))
|
||||
compute_id: Union[str, UUID],
|
||||
compute_update: schemas.ComputeUpdate,
|
||||
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository)),
|
||||
) -> schemas.Compute:
|
||||
"""
|
||||
Update a compute on the controller.
|
||||
@@ -95,11 +90,9 @@ async def update_compute(
|
||||
return await ComputesService(computes_repo).update_compute(compute_id, compute_update)
|
||||
|
||||
|
||||
@router.delete("/{compute_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.delete("/{compute_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_compute(
|
||||
compute_id: Union[str, UUID],
|
||||
computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
|
||||
compute_id: Union[str, UUID], computes_repo: ComputesRepository = Depends(get_repository(ComputesRepository))
|
||||
):
|
||||
"""
|
||||
Delete a compute from the controller.
|
||||
@@ -160,7 +153,4 @@ async def autoidlepc(compute_id: Union[str, UUID], auto_idle_pc: schemas.AutoIdl
|
||||
"""
|
||||
|
||||
controller = Controller.instance()
|
||||
return await controller.autoidlepc(str(compute_id),
|
||||
auto_idle_pc.platform,
|
||||
auto_idle_pc.image,
|
||||
auto_idle_pc.ram)
|
||||
return await controller.autoidlepc(str(compute_id), auto_idle_pc.platform, auto_idle_pc.image, auto_idle_pc.ram)
|
||||
@@ -29,14 +29,17 @@ from gns3server import schemas
|
||||
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/shutdown",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={403: {"model": schemas.ErrorMessage, "description": "Server shutdown not allowed"}})
|
||||
@router.post(
|
||||
"/shutdown",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={403: {"model": schemas.ErrorMessage, "description": "Server shutdown not allowed"}},
|
||||
)
|
||||
async def shutdown():
|
||||
"""
|
||||
Shutdown the local server
|
||||
@@ -67,8 +70,7 @@ async def shutdown():
|
||||
os.kill(os.getpid(), signal.SIGTERM)
|
||||
|
||||
|
||||
@router.get("/version",
|
||||
response_model=schemas.Version)
|
||||
@router.get("/version", response_model=schemas.Version)
|
||||
def get_version():
|
||||
"""
|
||||
Return the server version number.
|
||||
@@ -78,10 +80,12 @@ def get_version():
|
||||
return {"version": __version__, "local": local_server}
|
||||
|
||||
|
||||
@router.post("/version",
|
||||
response_model=schemas.Version,
|
||||
response_model_exclude_defaults=True,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Invalid version"}})
|
||||
@router.post(
|
||||
"/version",
|
||||
response_model=schemas.Version,
|
||||
response_model_exclude_defaults=True,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Invalid version"}},
|
||||
)
|
||||
def check_version(version: schemas.Version):
|
||||
"""
|
||||
Check if version is the same as the server.
|
||||
@@ -97,8 +101,7 @@ def check_version(version: schemas.Version):
|
||||
return {"version": __version__}
|
||||
|
||||
|
||||
@router.get("/iou_license",
|
||||
response_model=schemas.IOULicense)
|
||||
@router.get("/iou_license", response_model=schemas.IOULicense)
|
||||
def get_iou_license():
|
||||
"""
|
||||
Return the IOU license settings
|
||||
@@ -107,9 +110,7 @@ def get_iou_license():
|
||||
return Controller.instance().iou_license
|
||||
|
||||
|
||||
@router.put("/iou_license",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.IOULicense)
|
||||
@router.put("/iou_license", status_code=status.HTTP_201_CREATED, response_model=schemas.IOULicense)
|
||||
async def update_iou_license(iou_license: schemas.IOULicense):
|
||||
"""
|
||||
Update the IOU license settings.
|
||||
@@ -137,6 +138,7 @@ async def statistics():
|
||||
log.error(f"Could not retrieve statistics on compute {compute.name}: {e}")
|
||||
return compute_statistics
|
||||
|
||||
|
||||
# @Route.post(
|
||||
# r"/debug",
|
||||
# description="Dump debug information to disk (debug directory in config directory). Work only for local server",
|
||||
|
||||
@@ -28,8 +28,7 @@ oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/v3/users/login") # FIXME: URL p
|
||||
|
||||
|
||||
async def get_user_from_token(
|
||||
token: str = Depends(oauth2_scheme),
|
||||
user_repo: UsersRepository = Depends(get_repository(UsersRepository))
|
||||
token: str = Depends(oauth2_scheme), user_repo: UsersRepository = Depends(get_repository(UsersRepository))
|
||||
) -> schemas.User:
|
||||
|
||||
username = auth_service.get_username_from_token(token)
|
||||
@@ -38,7 +37,7 @@ async def get_user_from_token(
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Could not validate credentials",
|
||||
headers={"WWW-Authenticate": "Bearer"}
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
return user
|
||||
|
||||
@@ -49,6 +48,6 @@ async def get_current_active_user(current_user: schemas.User = Depends(get_user_
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Not an active user",
|
||||
headers={"WWW-Authenticate": "Bearer"}
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
return current_user
|
||||
@@ -31,7 +31,7 @@ async def get_db_session(request: Request) -> AsyncSession:
|
||||
|
||||
|
||||
def get_repository(repo: Type[BaseRepository]) -> Callable:
|
||||
|
||||
def get_repo(db_session: AsyncSession = Depends(get_db_session)) -> Type[BaseRepository]:
|
||||
return repo(db_session)
|
||||
|
||||
return get_repo
|
||||
@@ -26,16 +26,12 @@ from uuid import UUID
|
||||
from gns3server.controller import Controller
|
||||
from gns3server import schemas
|
||||
|
||||
responses = {
|
||||
404: {"model": schemas.ErrorMessage, "description": "Project or drawing not found"}
|
||||
}
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Project or drawing not found"}}
|
||||
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
@router.get("",
|
||||
response_model=List[schemas.Drawing],
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("", response_model=List[schemas.Drawing], response_model_exclude_unset=True)
|
||||
async def get_drawings(project_id: UUID):
|
||||
"""
|
||||
Return the list of all drawings for a given project.
|
||||
@@ -45,9 +41,7 @@ async def get_drawings(project_id: UUID):
|
||||
return [v.__json__() for v in project.drawings.values()]
|
||||
|
||||
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Drawing)
|
||||
@router.post("", status_code=status.HTTP_201_CREATED, response_model=schemas.Drawing)
|
||||
async def create_drawing(project_id: UUID, drawing_data: schemas.Drawing):
|
||||
"""
|
||||
Create a new drawing.
|
||||
@@ -58,9 +52,7 @@ async def create_drawing(project_id: UUID, drawing_data: schemas.Drawing):
|
||||
return drawing.__json__()
|
||||
|
||||
|
||||
@router.get("/{drawing_id}",
|
||||
response_model=schemas.Drawing,
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("/{drawing_id}", response_model=schemas.Drawing, response_model_exclude_unset=True)
|
||||
async def get_drawing(project_id: UUID, drawing_id: UUID):
|
||||
"""
|
||||
Return a drawing.
|
||||
@@ -71,9 +63,7 @@ async def get_drawing(project_id: UUID, drawing_id: UUID):
|
||||
return drawing.__json__()
|
||||
|
||||
|
||||
@router.put("/{drawing_id}",
|
||||
response_model=schemas.Drawing,
|
||||
response_model_exclude_unset=True)
|
||||
@router.put("/{drawing_id}", response_model=schemas.Drawing, response_model_exclude_unset=True)
|
||||
async def update_drawing(project_id: UUID, drawing_id: UUID, drawing_data: schemas.Drawing):
|
||||
"""
|
||||
Update a drawing.
|
||||
@@ -85,8 +75,7 @@ async def update_drawing(project_id: UUID, drawing_id: UUID, drawing_data: schem
|
||||
return drawing.__json__()
|
||||
|
||||
|
||||
@router.delete("/{drawing_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.delete("/{drawing_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_drawing(project_id: UUID, drawing_id: UUID):
|
||||
"""
|
||||
Delete a drawing.
|
||||
|
||||
@@ -34,11 +34,10 @@ from gns3server.utils.http_client import HTTPClient
|
||||
from gns3server import schemas
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
responses = {
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project or link"}
|
||||
}
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or link"}}
|
||||
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
@@ -53,9 +52,7 @@ async def dep_link(project_id: UUID, link_id: UUID):
|
||||
return link
|
||||
|
||||
|
||||
@router.get("",
|
||||
response_model=List[schemas.Link],
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("", response_model=List[schemas.Link], response_model_exclude_unset=True)
|
||||
async def get_links(project_id: UUID):
|
||||
"""
|
||||
Return all links for a given project.
|
||||
@@ -65,11 +62,15 @@ async def get_links(project_id: UUID):
|
||||
return [v.__json__() for v in project.links.values()]
|
||||
|
||||
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Link,
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project"},
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create link"}})
|
||||
@router.post(
|
||||
"",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Link,
|
||||
responses={
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project"},
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create link"},
|
||||
},
|
||||
)
|
||||
async def create_link(project_id: UUID, link_data: schemas.Link):
|
||||
"""
|
||||
Create a new link.
|
||||
@@ -84,10 +85,12 @@ async def create_link(project_id: UUID, link_data: schemas.Link):
|
||||
await link.update_suspend(link_data["suspend"])
|
||||
try:
|
||||
for node in link_data["nodes"]:
|
||||
await link.add_node(project.get_node(node["node_id"]),
|
||||
node.get("adapter_number", 0),
|
||||
node.get("port_number", 0),
|
||||
label=node.get("label"))
|
||||
await link.add_node(
|
||||
project.get_node(node["node_id"]),
|
||||
node.get("adapter_number", 0),
|
||||
node.get("port_number", 0),
|
||||
label=node.get("label"),
|
||||
)
|
||||
except ControllerError as e:
|
||||
await project.delete_link(link.id)
|
||||
raise e
|
||||
@@ -103,9 +106,7 @@ async def get_filters(link: Link = Depends(dep_link)):
|
||||
return link.available_filters()
|
||||
|
||||
|
||||
@router.get("/{link_id}",
|
||||
response_model=schemas.Link,
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("/{link_id}", response_model=schemas.Link, response_model_exclude_unset=True)
|
||||
async def get_link(link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Return a link.
|
||||
@@ -114,9 +115,7 @@ async def get_link(link: Link = Depends(dep_link)):
|
||||
return link.__json__()
|
||||
|
||||
|
||||
@router.put("/{link_id}",
|
||||
response_model=schemas.Link,
|
||||
response_model_exclude_unset=True)
|
||||
@router.put("/{link_id}", response_model=schemas.Link, response_model_exclude_unset=True)
|
||||
async def update_link(link_data: schemas.Link, link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Update a link.
|
||||
@@ -132,8 +131,7 @@ async def update_link(link_data: schemas.Link, link: Link = Depends(dep_link)):
|
||||
return link.__json__()
|
||||
|
||||
|
||||
@router.delete("/{link_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.delete("/{link_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_link(project_id: UUID, link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Delete a link.
|
||||
@@ -143,8 +141,7 @@ async def delete_link(project_id: UUID, link: Link = Depends(dep_link)):
|
||||
await project.delete_link(link.id)
|
||||
|
||||
|
||||
@router.post("/{link_id}/reset",
|
||||
response_model=schemas.Link)
|
||||
@router.post("/{link_id}/reset", response_model=schemas.Link)
|
||||
async def reset_link(link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Reset a link.
|
||||
@@ -154,21 +151,20 @@ async def reset_link(link: Link = Depends(dep_link)):
|
||||
return link.__json__()
|
||||
|
||||
|
||||
@router.post("/{link_id}/capture/start",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Link)
|
||||
@router.post("/{link_id}/capture/start", status_code=status.HTTP_201_CREATED, response_model=schemas.Link)
|
||||
async def start_capture(capture_data: dict, link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Start packet capture on the link.
|
||||
"""
|
||||
|
||||
await link.start_capture(data_link_type=capture_data.get("data_link_type", "DLT_EN10MB"),
|
||||
capture_file_name=capture_data.get("capture_file_name"))
|
||||
await link.start_capture(
|
||||
data_link_type=capture_data.get("data_link_type", "DLT_EN10MB"),
|
||||
capture_file_name=capture_data.get("capture_file_name"),
|
||||
)
|
||||
return link.__json__()
|
||||
|
||||
|
||||
@router.post("/{link_id}/capture/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/{link_id}/capture/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_capture(link: Link = Depends(dep_link)):
|
||||
"""
|
||||
Stop packet capture on the link.
|
||||
@@ -189,8 +185,8 @@ async def stream_pcap(request: Request, link: Link = Depends(dep_link)):
|
||||
compute = link.compute
|
||||
pcap_streaming_url = link.pcap_streaming_url()
|
||||
headers = multidict.MultiDict(request.headers)
|
||||
headers['Host'] = compute.host
|
||||
headers['Router-Host'] = request.client.host
|
||||
headers["Host"] = compute.host
|
||||
headers["Router-Host"] = request.client.host
|
||||
body = await request.body()
|
||||
|
||||
async def compute_pcap_stream():
|
||||
|
||||
@@ -36,6 +36,7 @@ from gns3server.controller.controller_error import ControllerForbiddenError
|
||||
from gns3server import schemas
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
node_locks = {}
|
||||
@@ -75,9 +76,7 @@ class NodeConcurrency(APIRoute):
|
||||
return custom_route_handler
|
||||
|
||||
|
||||
responses = {
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project or node"}
|
||||
}
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or node"}}
|
||||
|
||||
router = APIRouter(route_class=NodeConcurrency, responses=responses)
|
||||
|
||||
@@ -100,11 +99,15 @@ async def dep_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||
return node
|
||||
|
||||
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Node,
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project"},
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create node"}})
|
||||
@router.post(
|
||||
"",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Node,
|
||||
responses={
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project"},
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not create node"},
|
||||
},
|
||||
)
|
||||
async def create_node(node_data: schemas.Node, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Create a new node.
|
||||
@@ -113,16 +116,11 @@ async def create_node(node_data: schemas.Node, project: Project = Depends(dep_pr
|
||||
controller = Controller.instance()
|
||||
compute = controller.get_compute(str(node_data.compute_id))
|
||||
node_data = jsonable_encoder(node_data, exclude_unset=True)
|
||||
node = await project.add_node(compute,
|
||||
node_data.pop("name"),
|
||||
node_data.pop("node_id", None),
|
||||
**node_data)
|
||||
node = await project.add_node(compute, node_data.pop("name"), node_data.pop("node_id", None), **node_data)
|
||||
return node.__json__()
|
||||
|
||||
|
||||
@router.get("",
|
||||
response_model=List[schemas.Node],
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("", response_model=List[schemas.Node], response_model_exclude_unset=True)
|
||||
async def get_nodes(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Return all nodes belonging to a given project.
|
||||
@@ -131,8 +129,7 @@ async def get_nodes(project: Project = Depends(dep_project)):
|
||||
return [v.__json__() for v in project.nodes.values()]
|
||||
|
||||
|
||||
@router.post("/start",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_all_nodes(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Start all nodes belonging to a given project.
|
||||
@@ -141,8 +138,7 @@ async def start_all_nodes(project: Project = Depends(dep_project)):
|
||||
await project.start_all()
|
||||
|
||||
|
||||
@router.post("/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_all_nodes(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Stop all nodes belonging to a given project.
|
||||
@@ -151,8 +147,7 @@ async def stop_all_nodes(project: Project = Depends(dep_project)):
|
||||
await project.stop_all()
|
||||
|
||||
|
||||
@router.post("/suspend",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_all_nodes(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Suspend all nodes belonging to a given project.
|
||||
@@ -161,8 +156,7 @@ async def suspend_all_nodes(project: Project = Depends(dep_project)):
|
||||
await project.suspend_all()
|
||||
|
||||
|
||||
@router.post("/reload",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_all_nodes(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Reload all nodes belonging to a given project.
|
||||
@@ -172,8 +166,7 @@ async def reload_all_nodes(project: Project = Depends(dep_project)):
|
||||
await project.start_all()
|
||||
|
||||
|
||||
@router.get("/{node_id}",
|
||||
response_model=schemas.Node)
|
||||
@router.get("/{node_id}", response_model=schemas.Node)
|
||||
def get_node(node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Return a node from a given project.
|
||||
@@ -182,9 +175,7 @@ def get_node(node: Node = Depends(dep_node)):
|
||||
return node.__json__()
|
||||
|
||||
|
||||
@router.put("/{node_id}",
|
||||
response_model=schemas.Node,
|
||||
response_model_exclude_unset=True)
|
||||
@router.put("/{node_id}", response_model=schemas.Node, response_model_exclude_unset=True)
|
||||
async def update_node(node_data: schemas.NodeUpdate, node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Update a node.
|
||||
@@ -201,10 +192,11 @@ async def update_node(node_data: schemas.NodeUpdate, node: Node = Depends(dep_no
|
||||
return node.__json__()
|
||||
|
||||
|
||||
@router.delete("/{node_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={**responses,
|
||||
409: {"model": schemas.ErrorMessage, "description": "Cannot delete node"}})
|
||||
@router.delete(
|
||||
"/{node_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Cannot delete node"}},
|
||||
)
|
||||
async def delete_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Delete a node from a project.
|
||||
@@ -213,23 +205,17 @@ async def delete_node(node_id: UUID, project: Project = Depends(dep_project)):
|
||||
await project.delete_node(str(node_id))
|
||||
|
||||
|
||||
@router.post("/{node_id}/duplicate",
|
||||
response_model=schemas.Node,
|
||||
status_code=status.HTTP_201_CREATED)
|
||||
@router.post("/{node_id}/duplicate", response_model=schemas.Node, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_node(duplicate_data: schemas.NodeDuplicate, node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Duplicate a node.
|
||||
"""
|
||||
|
||||
new_node = await node.project.duplicate_node(node,
|
||||
duplicate_data.x,
|
||||
duplicate_data.y,
|
||||
duplicate_data.z)
|
||||
new_node = await node.project.duplicate_node(node, duplicate_data.x, duplicate_data.y, duplicate_data.z)
|
||||
return new_node.__json__()
|
||||
|
||||
|
||||
@router.post("/{node_id}/start",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/{node_id}/start", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def start_node(start_data: dict, node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Start a node.
|
||||
@@ -238,8 +224,7 @@ async def start_node(start_data: dict, node: Node = Depends(dep_node)):
|
||||
await node.start(data=start_data)
|
||||
|
||||
|
||||
@router.post("/{node_id}/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/{node_id}/stop", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def stop_node(node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Stop a node.
|
||||
@@ -248,8 +233,7 @@ async def stop_node(node: Node = Depends(dep_node)):
|
||||
await node.stop()
|
||||
|
||||
|
||||
@router.post("/{node_id}/suspend",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/{node_id}/suspend", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def suspend_node(node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Suspend a node.
|
||||
@@ -258,8 +242,7 @@ async def suspend_node(node: Node = Depends(dep_node)):
|
||||
await node.suspend()
|
||||
|
||||
|
||||
@router.post("/{node_id}/reload",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/{node_id}/reload", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reload_node(node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Reload a node.
|
||||
@@ -268,9 +251,7 @@ async def reload_node(node: Node = Depends(dep_node)):
|
||||
await node.reload()
|
||||
|
||||
|
||||
@router.get("/{node_id}/links",
|
||||
response_model=List[schemas.Link],
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("/{node_id}/links", response_model=List[schemas.Link], response_model_exclude_unset=True)
|
||||
async def get_node_links(node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Return all the links connected to a node.
|
||||
@@ -300,8 +281,7 @@ async def idlepc_proposals(node: Node = Depends(dep_node)):
|
||||
return await node.dynamips_idlepc_proposals()
|
||||
|
||||
|
||||
@router.post("/{node_id}/resize_disk",
|
||||
status_code=status.HTTP_201_CREATED)
|
||||
@router.post("/{node_id}/resize_disk", status_code=status.HTTP_201_CREATED)
|
||||
async def resize_disk(resize_data: dict, node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Resize a disk image.
|
||||
@@ -328,8 +308,7 @@ async def get_file(file_path: str, node: Node = Depends(dep_node)):
|
||||
return Response(res.body, media_type="application/octet-stream")
|
||||
|
||||
|
||||
@router.post("/{node_id}/files/{file_path:path}",
|
||||
status_code=status.HTTP_201_CREATED)
|
||||
@router.post("/{node_id}/files/{file_path:path}", status_code=status.HTTP_201_CREATED)
|
||||
async def post_file(file_path: str, request: Request, node: Node = Depends(dep_node)):
|
||||
"""
|
||||
Write a file in the node directory.
|
||||
@@ -344,7 +323,7 @@ async def post_file(file_path: str, request: Request, node: Node = Depends(dep_n
|
||||
node_type = node.node_type
|
||||
path = f"/project-files/{node_type}/{node.id}/{path}"
|
||||
|
||||
data = await request.body() #FIXME: are we handling timeout or large files correctly?
|
||||
data = await request.body() # FIXME: are we handling timeout or large files correctly?
|
||||
|
||||
await node.compute.http_query("POST", f"/projects/{node.project.id}/files{path}", data=data, timeout=None, raw=True)
|
||||
|
||||
@@ -357,9 +336,13 @@ async def ws_console(websocket: WebSocket, node: Node = Depends(dep_node)):
|
||||
|
||||
compute = node.compute
|
||||
await websocket.accept()
|
||||
log.info(f"New client {websocket.client.host}:{websocket.client.port} has connected to controller console WebSocket")
|
||||
ws_console_compute_url = f"ws://{compute.host}:{compute.port}/v3/compute/projects/" \
|
||||
f"{node.project.id}/{node.node_type}/nodes/{node.id}/console/ws"
|
||||
log.info(
|
||||
f"New client {websocket.client.host}:{websocket.client.port} has connected to controller console WebSocket"
|
||||
)
|
||||
ws_console_compute_url = (
|
||||
f"ws://{compute.host}:{compute.port}/v3/compute/projects/"
|
||||
f"{node.project.id}/{node.node_type}/nodes/{node.id}/console/ws"
|
||||
)
|
||||
|
||||
async def ws_receive(ws_console_compute):
|
||||
"""
|
||||
@@ -373,8 +356,10 @@ async def ws_console(websocket: WebSocket, node: Node = Depends(dep_node)):
|
||||
await ws_console_compute.send_str(data)
|
||||
except WebSocketDisconnect:
|
||||
await ws_console_compute.close()
|
||||
log.info(f"Client {websocket.client.host}:{websocket.client.port} has disconnected from controller"
|
||||
f" console WebSocket")
|
||||
log.info(
|
||||
f"Client {websocket.client.host}:{websocket.client.port} has disconnected from controller"
|
||||
f" console WebSocket"
|
||||
)
|
||||
|
||||
try:
|
||||
# receive WebSocket data from compute console WebSocket and forward to client.
|
||||
@@ -391,8 +376,7 @@ async def ws_console(websocket: WebSocket, node: Node = Depends(dep_node)):
|
||||
log.error(f"Client error received when forwarding to compute console WebSocket: {e}")
|
||||
|
||||
|
||||
@router.post("/console/reset",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/console/reset", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def reset_console_all_nodes(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Reset console for all nodes belonging to the project.
|
||||
@@ -401,8 +385,7 @@ async def reset_console_all_nodes(project: Project = Depends(dep_project)):
|
||||
await project.reset_console_all()
|
||||
|
||||
|
||||
@router.post("/{node_id}/console/reset",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/{node_id}/console/reset", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def console_reset(node: Node = Depends(dep_node)):
|
||||
|
||||
await node.post("/console/reset")#, request.json)
|
||||
await node.post("/console/reset") # , request.json)
|
||||
@@ -25,6 +25,7 @@ from websockets.exceptions import ConnectionClosed, WebSocketException
|
||||
from gns3server.controller import Controller
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -26,6 +26,7 @@ import aiofiles
|
||||
import time
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger()
|
||||
|
||||
from fastapi import APIRouter, Depends, Request, Body, HTTPException, status, WebSocket, WebSocketDisconnect
|
||||
@@ -45,9 +46,7 @@ from gns3server.controller.export_project import export_project as export_contro
|
||||
from gns3server.utils.asyncio import aiozipstream
|
||||
from gns3server.config import Config
|
||||
|
||||
responses = {
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project"}
|
||||
}
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project"}}
|
||||
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
@@ -64,9 +63,7 @@ def dep_project(project_id: UUID):
|
||||
CHUNK_SIZE = 1024 * 8 # 8KB
|
||||
|
||||
|
||||
@router.get("",
|
||||
response_model=List[schemas.Project],
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("", response_model=List[schemas.Project], response_model_exclude_unset=True)
|
||||
def get_projects():
|
||||
"""
|
||||
Return all projects.
|
||||
@@ -76,11 +73,13 @@ def get_projects():
|
||||
return [p.__json__() for p in controller.projects.values()]
|
||||
|
||||
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
response_model_exclude_unset=True,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create project"}})
|
||||
@router.post(
|
||||
"",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
response_model_exclude_unset=True,
|
||||
responses={409: {"model": schemas.ErrorMessage, "description": "Could not create project"}},
|
||||
)
|
||||
async def create_project(project_data: schemas.ProjectCreate):
|
||||
"""
|
||||
Create a new project.
|
||||
@@ -91,8 +90,7 @@ async def create_project(project_data: schemas.ProjectCreate):
|
||||
return project.__json__()
|
||||
|
||||
|
||||
@router.get("/{project_id}",
|
||||
response_model=schemas.Project)
|
||||
@router.get("/{project_id}", response_model=schemas.Project)
|
||||
def get_project(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Return a project.
|
||||
@@ -101,9 +99,7 @@ def get_project(project: Project = Depends(dep_project)):
|
||||
return project.__json__()
|
||||
|
||||
|
||||
@router.put("/{project_id}",
|
||||
response_model=schemas.Project,
|
||||
response_model_exclude_unset=True)
|
||||
@router.put("/{project_id}", response_model=schemas.Project, response_model_exclude_unset=True)
|
||||
async def update_project(project_data: schemas.ProjectUpdate, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Update a project.
|
||||
@@ -113,8 +109,7 @@ async def update_project(project_data: schemas.ProjectUpdate, project: Project =
|
||||
return project.__json__()
|
||||
|
||||
|
||||
@router.delete("/{project_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.delete("/{project_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_project(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Delete a project.
|
||||
@@ -134,12 +129,11 @@ def get_project_stats(project: Project = Depends(dep_project)):
|
||||
return project.stats()
|
||||
|
||||
|
||||
@router.post("/{project_id}/close",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={
|
||||
**responses,
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not close project"}
|
||||
})
|
||||
@router.post(
|
||||
"/{project_id}/close",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Could not close project"}},
|
||||
)
|
||||
async def close_project(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Close a project.
|
||||
@@ -148,13 +142,12 @@ async def close_project(project: Project = Depends(dep_project)):
|
||||
await project.close()
|
||||
|
||||
|
||||
@router.post("/{project_id}/open",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
responses={
|
||||
**responses,
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not open project"}
|
||||
})
|
||||
@router.post(
|
||||
"/{project_id}/open",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Could not open project"}},
|
||||
)
|
||||
async def open_project(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Open a project.
|
||||
@@ -164,13 +157,12 @@ async def open_project(project: Project = Depends(dep_project)):
|
||||
return project.__json__()
|
||||
|
||||
|
||||
@router.post("/load",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
responses={
|
||||
**responses,
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not load project"}
|
||||
})
|
||||
@router.post(
|
||||
"/load",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Could not load project"}},
|
||||
)
|
||||
async def load_project(path: str = Body(..., embed=True)):
|
||||
"""
|
||||
Load a project (local server only).
|
||||
@@ -181,7 +173,9 @@ async def load_project(path: str = Body(..., embed=True)):
|
||||
if Config.instance().settings.Server.local is False:
|
||||
log.error(f"Cannot load '{dot_gns3_file}' because the server has not been started with the '--local' parameter")
|
||||
raise ControllerForbiddenError("Cannot load project when server is not local")
|
||||
project = await controller.load_project(dot_gns3_file,)
|
||||
project = await controller.load_project(
|
||||
dot_gns3_file,
|
||||
)
|
||||
return project.__json__()
|
||||
|
||||
|
||||
@@ -248,11 +242,13 @@ async def notification_ws(project_id: UUID, websocket: WebSocket):
|
||||
|
||||
|
||||
@router.get("/{project_id}/export")
|
||||
async def export_project(project: Project = Depends(dep_project),
|
||||
include_snapshots: bool = False,
|
||||
include_images: bool = False,
|
||||
reset_mac_addresses: bool = False,
|
||||
compression: str = "zip"):
|
||||
async def export_project(
|
||||
project: Project = Depends(dep_project),
|
||||
include_snapshots: bool = False,
|
||||
include_images: bool = False,
|
||||
reset_mac_addresses: bool = False,
|
||||
compression: str = "zip",
|
||||
):
|
||||
"""
|
||||
Export a project as a portable archive.
|
||||
"""
|
||||
@@ -275,12 +271,14 @@ async def export_project(project: Project = Depends(dep_project),
|
||||
async def streamer():
|
||||
with tempfile.TemporaryDirectory(dir=working_dir) as tmpdir:
|
||||
with aiozipstream.ZipFile(compression=compression) as zstream:
|
||||
await export_controller_project(zstream,
|
||||
project,
|
||||
tmpdir,
|
||||
include_snapshots=include_snapshots,
|
||||
include_images=include_images,
|
||||
reset_mac_addresses=reset_mac_addresses)
|
||||
await export_controller_project(
|
||||
zstream,
|
||||
project,
|
||||
tmpdir,
|
||||
include_snapshots=include_snapshots,
|
||||
include_images=include_images,
|
||||
reset_mac_addresses=reset_mac_addresses,
|
||||
)
|
||||
async for chunk in zstream:
|
||||
yield chunk
|
||||
|
||||
@@ -295,9 +293,7 @@ async def export_project(project: Project = Depends(dep_project),
|
||||
return StreamingResponse(streamer(), media_type="application/gns3project", headers=headers)
|
||||
|
||||
|
||||
@router.post("/{project_id}/import",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project)
|
||||
@router.post("/{project_id}/import", status_code=status.HTTP_201_CREATED, response_model=schemas.Project)
|
||||
async def import_project(project_id: UUID, request: Request, path: Optional[Path] = None, name: Optional[str] = None):
|
||||
"""
|
||||
Import a project from a portable archive.
|
||||
@@ -318,7 +314,7 @@ async def import_project(project_id: UUID, request: Request, path: Optional[Path
|
||||
working_dir = controller.projects_directory()
|
||||
with tempfile.TemporaryDirectory(dir=working_dir) as tmpdir:
|
||||
temp_project_path = os.path.join(tmpdir, "project.zip")
|
||||
async with aiofiles.open(temp_project_path, 'wb') as f:
|
||||
async with aiofiles.open(temp_project_path, "wb") as f:
|
||||
async for chunk in request.stream():
|
||||
await f.write(chunk)
|
||||
with open(temp_project_path, "rb") as f:
|
||||
@@ -330,13 +326,12 @@ async def import_project(project_id: UUID, request: Request, path: Optional[Path
|
||||
return project.__json__()
|
||||
|
||||
|
||||
@router.post("/{project_id}/duplicate",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
responses={
|
||||
**responses,
|
||||
409: {"model": schemas.ErrorMessage, "description": "Could not duplicate project"}
|
||||
})
|
||||
@router.post(
|
||||
"/{project_id}/duplicate",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project,
|
||||
responses={**responses, 409: {"model": schemas.ErrorMessage, "description": "Could not duplicate project"}},
|
||||
)
|
||||
async def duplicate_project(project_data: schemas.ProjectDuplicate, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Duplicate a project.
|
||||
@@ -350,7 +345,9 @@ async def duplicate_project(project_data: schemas.ProjectDuplicate, project: Pro
|
||||
location = None
|
||||
|
||||
reset_mac_addresses = project_data.reset_mac_addresses
|
||||
new_project = await project.duplicate(name=project_data.name, location=location, reset_mac_addresses=reset_mac_addresses)
|
||||
new_project = await project.duplicate(
|
||||
name=project_data.name, location=location, reset_mac_addresses=reset_mac_addresses
|
||||
)
|
||||
return new_project.__json__()
|
||||
|
||||
|
||||
@@ -360,7 +357,7 @@ async def get_file(file_path: str, project: Project = Depends(dep_project)):
|
||||
Return a file from a project.
|
||||
"""
|
||||
|
||||
path = os.path.normpath(file_path).strip('/')
|
||||
path = os.path.normpath(file_path).strip("/")
|
||||
|
||||
# Raise error if user try to escape
|
||||
if path[0] == ".":
|
||||
@@ -373,8 +370,7 @@ async def get_file(file_path: str, project: Project = Depends(dep_project)):
|
||||
return FileResponse(path, media_type="application/octet-stream")
|
||||
|
||||
|
||||
@router.post("/{project_id}/files/{file_path:path}",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/{project_id}/files/{file_path:path}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def write_file(file_path: str, request: Request, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Write a file from a project.
|
||||
@@ -389,7 +385,7 @@ async def write_file(file_path: str, request: Request, project: Project = Depend
|
||||
path = os.path.join(project.path, path)
|
||||
|
||||
try:
|
||||
async with aiofiles.open(path, 'wb+') as f:
|
||||
async with aiofiles.open(path, "wb+") as f:
|
||||
async for chunk in request.stream():
|
||||
await f.write(chunk)
|
||||
except FileNotFoundError:
|
||||
|
||||
@@ -20,6 +20,7 @@ API routes for snapshots.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger()
|
||||
|
||||
from fastapi import APIRouter, Depends, status
|
||||
@@ -30,9 +31,7 @@ from gns3server.controller.project import Project
|
||||
from gns3server import schemas
|
||||
from gns3server.controller import Controller
|
||||
|
||||
responses = {
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find project or snapshot"}
|
||||
}
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or snapshot"}}
|
||||
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
@@ -46,9 +45,7 @@ def dep_project(project_id: UUID):
|
||||
return project
|
||||
|
||||
|
||||
@router.post("",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Snapshot)
|
||||
@router.post("", status_code=status.HTTP_201_CREATED, response_model=schemas.Snapshot)
|
||||
async def create_snapshot(snapshot_data: schemas.SnapshotCreate, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Create a new snapshot of a project.
|
||||
@@ -58,9 +55,7 @@ async def create_snapshot(snapshot_data: schemas.SnapshotCreate, project: Projec
|
||||
return snapshot.__json__()
|
||||
|
||||
|
||||
@router.get("",
|
||||
response_model=List[schemas.Snapshot],
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("", response_model=List[schemas.Snapshot], response_model_exclude_unset=True)
|
||||
def get_snapshots(project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Return all snapshots belonging to a given project.
|
||||
@@ -70,8 +65,7 @@ def get_snapshots(project: Project = Depends(dep_project)):
|
||||
return [s.__json__() for s in sorted(snapshots, key=lambda s: (s.created_at, s.name))]
|
||||
|
||||
|
||||
@router.delete("/{snapshot_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.delete("/{snapshot_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_snapshot(snapshot_id: UUID, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Delete a snapshot.
|
||||
@@ -80,9 +74,7 @@ async def delete_snapshot(snapshot_id: UUID, project: Project = Depends(dep_proj
|
||||
await project.delete_snapshot(str(snapshot_id))
|
||||
|
||||
|
||||
@router.post("/{snapshot_id}/restore",
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
response_model=schemas.Project)
|
||||
@router.post("/{snapshot_id}/restore", status_code=status.HTTP_201_CREATED, response_model=schemas.Project)
|
||||
async def restore_snapshot(snapshot_id: UUID, project: Project = Depends(dep_project)):
|
||||
"""
|
||||
Restore a snapshot.
|
||||
|
||||
@@ -29,6 +29,7 @@ from gns3server import schemas
|
||||
from gns3server.controller.controller_error import ControllerError, ControllerNotFoundError
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -42,8 +43,9 @@ def get_symbols():
|
||||
return controller.symbols.list()
|
||||
|
||||
|
||||
@router.get("/{symbol_id:path}/raw",
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find symbol"}})
|
||||
@router.get(
|
||||
"/{symbol_id:path}/raw", responses={404: {"model": schemas.ErrorMessage, "description": "Could not find symbol"}}
|
||||
)
|
||||
async def get_symbol(symbol_id: str):
|
||||
"""
|
||||
Download a symbol file.
|
||||
@@ -57,8 +59,10 @@ async def get_symbol(symbol_id: str):
|
||||
return ControllerNotFoundError(f"Could not get symbol file: {e}")
|
||||
|
||||
|
||||
@router.get("/{symbol_id:path}/dimensions",
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find symbol"}})
|
||||
@router.get(
|
||||
"/{symbol_id:path}/dimensions",
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find symbol"}},
|
||||
)
|
||||
async def get_symbol_dimensions(symbol_id: str):
|
||||
"""
|
||||
Get a symbol dimensions.
|
||||
@@ -67,14 +71,13 @@ async def get_symbol_dimensions(symbol_id: str):
|
||||
controller = Controller.instance()
|
||||
try:
|
||||
width, height, _ = controller.symbols.get_size(symbol_id)
|
||||
symbol_dimensions = {'width': width, 'height': height}
|
||||
symbol_dimensions = {"width": width, "height": height}
|
||||
return symbol_dimensions
|
||||
except (KeyError, OSError, ValueError) as e:
|
||||
return ControllerNotFoundError(f"Could not get symbol file: {e}")
|
||||
|
||||
|
||||
@router.post("/{symbol_id:path}/raw",
|
||||
status_code=status.HTTP_204_NO_CONTENT)
|
||||
@router.post("/{symbol_id:path}/raw", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def upload_symbol(symbol_id: str, request: Request):
|
||||
"""
|
||||
Upload a symbol file.
|
||||
|
||||
@@ -22,6 +22,7 @@ import hashlib
|
||||
import json
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
from fastapi import APIRouter, Request, Response, HTTPException, Depends, status
|
||||
@@ -34,17 +35,15 @@ from gns3server.db.repositories.templates import TemplatesRepository
|
||||
from gns3server.services.templates import TemplatesService
|
||||
from .dependencies.database import get_repository
|
||||
|
||||
responses = {
|
||||
404: {"model": schemas.ErrorMessage, "description": "Could not find template"}
|
||||
}
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find template"}}
|
||||
|
||||
router = APIRouter(responses=responses)
|
||||
|
||||
|
||||
@router.post("/templates", response_model=schemas.Template, status_code=status.HTTP_201_CREATED)
|
||||
async def create_template(
|
||||
template_create: schemas.TemplateCreate,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
template_create: schemas.TemplateCreate,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> dict:
|
||||
"""
|
||||
Create a new template.
|
||||
@@ -53,14 +52,12 @@ async def create_template(
|
||||
return await TemplatesService(templates_repo).create_template(template_create)
|
||||
|
||||
|
||||
@router.get("/templates/{template_id}",
|
||||
response_model=schemas.Template,
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("/templates/{template_id}", response_model=schemas.Template, response_model_exclude_unset=True)
|
||||
async def get_template(
|
||||
template_id: UUID,
|
||||
request: Request,
|
||||
response: Response,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
template_id: UUID,
|
||||
request: Request,
|
||||
response: Response,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> dict:
|
||||
"""
|
||||
Return a template.
|
||||
@@ -77,13 +74,11 @@ async def get_template(
|
||||
return template
|
||||
|
||||
|
||||
@router.put("/templates/{template_id}",
|
||||
response_model=schemas.Template,
|
||||
response_model_exclude_unset=True)
|
||||
@router.put("/templates/{template_id}", response_model=schemas.Template, response_model_exclude_unset=True)
|
||||
async def update_template(
|
||||
template_id: UUID,
|
||||
template_update: schemas.TemplateUpdate,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
template_id: UUID,
|
||||
template_update: schemas.TemplateUpdate,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> dict:
|
||||
"""
|
||||
Update a template.
|
||||
@@ -92,11 +87,12 @@ async def update_template(
|
||||
return await TemplatesService(templates_repo).update_template(template_id, template_update)
|
||||
|
||||
|
||||
@router.delete("/templates/{template_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT,)
|
||||
@router.delete(
|
||||
"/templates/{template_id}",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
)
|
||||
async def delete_template(
|
||||
template_id: UUID,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
template_id: UUID, templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
) -> None:
|
||||
"""
|
||||
Delete a template.
|
||||
@@ -105,11 +101,9 @@ async def delete_template(
|
||||
await TemplatesService(templates_repo).delete_template(template_id)
|
||||
|
||||
|
||||
@router.get("/templates",
|
||||
response_model=List[schemas.Template],
|
||||
response_model_exclude_unset=True)
|
||||
@router.get("/templates", response_model=List[schemas.Template], response_model_exclude_unset=True)
|
||||
async def get_templates(
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> List[dict]:
|
||||
"""
|
||||
Return all templates.
|
||||
@@ -118,12 +112,9 @@ async def get_templates(
|
||||
return await TemplatesService(templates_repo).get_templates()
|
||||
|
||||
|
||||
@router.post("/templates/{template_id}/duplicate",
|
||||
response_model=schemas.Template,
|
||||
status_code=status.HTTP_201_CREATED)
|
||||
@router.post("/templates/{template_id}/duplicate", response_model=schemas.Template, status_code=status.HTTP_201_CREATED)
|
||||
async def duplicate_template(
|
||||
template_id: UUID,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
template_id: UUID, templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
) -> dict:
|
||||
"""
|
||||
Duplicate a template.
|
||||
@@ -132,15 +123,17 @@ async def duplicate_template(
|
||||
return await TemplatesService(templates_repo).duplicate_template(template_id)
|
||||
|
||||
|
||||
@router.post("/projects/{project_id}/templates/{template_id}",
|
||||
response_model=schemas.Node,
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project or template"}})
|
||||
@router.post(
|
||||
"/projects/{project_id}/templates/{template_id}",
|
||||
response_model=schemas.Node,
|
||||
status_code=status.HTTP_201_CREATED,
|
||||
responses={404: {"model": schemas.ErrorMessage, "description": "Could not find project or template"}},
|
||||
)
|
||||
async def create_node_from_template(
|
||||
project_id: UUID,
|
||||
template_id: UUID,
|
||||
template_usage: schemas.TemplateUsage,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository))
|
||||
project_id: UUID,
|
||||
template_id: UUID,
|
||||
template_usage: schemas.TemplateUsage,
|
||||
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
|
||||
) -> schemas.Node:
|
||||
"""
|
||||
Create a new node from a template.
|
||||
@@ -149,8 +142,7 @@ async def create_node_from_template(
|
||||
template = TemplatesService(templates_repo).get_template(template_id)
|
||||
controller = Controller.instance()
|
||||
project = controller.get_project(str(project_id))
|
||||
node = await project.add_node_from_template(template,
|
||||
x=template_usage.x,
|
||||
y=template_usage.y,
|
||||
compute_id=template_usage.compute_id)
|
||||
node = await project.add_node_from_template(
|
||||
template, x=template_usage.x, y=template_usage.y, compute_id=template_usage.compute_id
|
||||
)
|
||||
return node.__json__()
|
||||
@@ -28,7 +28,7 @@ from gns3server import schemas
|
||||
from gns3server.controller.controller_error import (
|
||||
ControllerBadRequestError,
|
||||
ControllerNotFoundError,
|
||||
ControllerUnauthorizedError
|
||||
ControllerUnauthorizedError,
|
||||
)
|
||||
|
||||
from gns3server.db.repositories.users import UsersRepository
|
||||
@@ -38,6 +38,7 @@ from .dependencies.authentication import get_current_active_user
|
||||
from .dependencies.database import get_repository
|
||||
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter()
|
||||
@@ -54,8 +55,7 @@ async def get_users(users_repo: UsersRepository = Depends(get_repository(UsersRe
|
||||
|
||||
@router.post("", response_model=schemas.User, status_code=status.HTTP_201_CREATED)
|
||||
async def create_user(
|
||||
user_create: schemas.UserCreate,
|
||||
users_repo: UsersRepository = Depends(get_repository(UsersRepository))
|
||||
user_create: schemas.UserCreate, users_repo: UsersRepository = Depends(get_repository(UsersRepository))
|
||||
) -> schemas.User:
|
||||
"""
|
||||
Create a new user.
|
||||
@@ -72,8 +72,7 @@ async def create_user(
|
||||
|
||||
@router.get("/{user_id}", response_model=schemas.User)
|
||||
async def get_user(
|
||||
user_id: UUID,
|
||||
users_repo: UsersRepository = Depends(get_repository(UsersRepository))
|
||||
user_id: UUID, users_repo: UsersRepository = Depends(get_repository(UsersRepository))
|
||||
) -> schemas.User:
|
||||
"""
|
||||
Get an user.
|
||||
@@ -87,9 +86,9 @@ async def get_user(
|
||||
|
||||
@router.put("/{user_id}", response_model=schemas.User)
|
||||
async def update_user(
|
||||
user_id: UUID,
|
||||
user_update: schemas.UserUpdate,
|
||||
users_repo: UsersRepository = Depends(get_repository(UsersRepository))
|
||||
user_id: UUID,
|
||||
user_update: schemas.UserUpdate,
|
||||
users_repo: UsersRepository = Depends(get_repository(UsersRepository)),
|
||||
) -> schemas.User:
|
||||
"""
|
||||
Update an user.
|
||||
@@ -103,9 +102,9 @@ async def update_user(
|
||||
|
||||
@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_user(
|
||||
user_id: UUID,
|
||||
users_repo: UsersRepository = Depends(get_repository(UsersRepository)),
|
||||
current_user: schemas.User = Depends(get_current_active_user)
|
||||
user_id: UUID,
|
||||
users_repo: UsersRepository = Depends(get_repository(UsersRepository)),
|
||||
current_user: schemas.User = Depends(get_current_active_user),
|
||||
) -> None:
|
||||
"""
|
||||
Delete an user.
|
||||
@@ -121,8 +120,8 @@ async def delete_user(
|
||||
|
||||
@router.post("/login", response_model=schemas.Token)
|
||||
async def login(
|
||||
users_repo: UsersRepository = Depends(get_repository(UsersRepository)),
|
||||
form_data: OAuth2PasswordRequestForm = Depends()
|
||||
users_repo: UsersRepository = Depends(get_repository(UsersRepository)),
|
||||
form_data: OAuth2PasswordRequestForm = Depends(),
|
||||
) -> schemas.Token:
|
||||
"""
|
||||
User login.
|
||||
@@ -130,9 +129,11 @@ async def login(
|
||||
|
||||
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.",
|
||||
headers={"WWW-Authenticate": "Bearer"})
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Authentication was unsuccessful.",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
|
||||
token = schemas.Token(access_token=auth_service.create_access_token(user.username), token_type="bearer")
|
||||
return token
|
||||
|
||||
Reference in new issue
Block a user