gns3-server/gns3server/api/routes/controller/appliances.py
grossmj 04934691df Appliance management refactoring:
* Install an appliance based on selected version
* Each template have unique name and version
* Allow to download an appliance file
2021-10-18 18:04:30 +10:30

97 lines
3.3 KiB
Python

#
# Copyright (C) 2020 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
API routes for appliances.
"""
import os
import logging
from fastapi import APIRouter, Depends, Response, status
from fastapi.responses import FileResponse
from typing import Optional, List
from uuid import UUID
from gns3server import schemas
from gns3server.controller import Controller
from gns3server.controller.controller_error import ControllerNotFoundError
from gns3server.db.repositories.images import ImagesRepository
from gns3server.db.repositories.templates import TemplatesRepository
from gns3server.db.repositories.rbac import RbacRepository
from .dependencies.authentication import get_current_active_user
from .dependencies.database import get_repository
log = logging.getLogger(__name__)
router = APIRouter()
@router.get("")
async def get_appliances(update: Optional[bool] = False, symbol_theme: Optional[str] = "Classic") -> List[dict]:
"""
Return all appliances known by the controller.
"""
controller = Controller.instance()
if update:
await controller.appliance_manager.download_appliances()
controller.appliance_manager.load_appliances(symbol_theme=symbol_theme)
return [c.asdict() for c in controller.appliance_manager.appliances.values()]
@router.get("/{appliance_id}/download")
def download_appliance(appliance_id: UUID) -> FileResponse:
"""
Download an appliance file.
"""
controller = Controller.instance()
appliance = controller.appliance_manager.appliances.get(str(appliance_id))
if not appliance:
raise ControllerNotFoundError(message=f"Could not find appliance '{appliance_id}'")
if not os.path.exists(appliance.path):
raise ControllerNotFoundError(message=f"Could not find appliance file '{appliance.path}'")
return FileResponse(appliance.path, media_type="application/json")
@router.post("/{appliance_id}/install", status_code=status.HTTP_204_NO_CONTENT)
async def install_appliance(
appliance_id: UUID,
version: Optional[str] = None,
images_repo: ImagesRepository = Depends(get_repository(ImagesRepository)),
templates_repo: TemplatesRepository = Depends(get_repository(TemplatesRepository)),
current_user: schemas.User = Depends(get_current_active_user),
rbac_repo: RbacRepository = Depends(get_repository(RbacRepository))
) -> Response:
"""
Install an appliance.
"""
controller = Controller.instance()
await controller.appliance_manager.install_appliance(
appliance_id,
version,
images_repo,
templates_repo,
rbac_repo,
current_user
)
return Response(status_code=status.HTTP_204_NO_CONTENT)