UNPKG

@lxdhub/api

Version:

Display, search and copy LXD-images using a web interface.

128 lines (121 loc) 3.97 kB
import { BadRequestException, Body, Controller, Get, Param, ParseIntPipe, Post, Query, UseInterceptors, ValidationPipe, NotFoundException, InternalServerErrorException, UploadedFile, Logger, Inject, ForbiddenException } from '@nestjs/common'; import { ApiResponse } from '@nestjs/swagger'; import { CloneImageDto, CloneImageResponseDto, ImageDetailDto, ImageListOptions, ImageListItemResponse } from '.'; import { ResponseDto } from '@lxdhub/interfaces'; import { ImageService } from './image.service'; import { ImageListItemInterceptor } from './interceptors/image-list-item.interceptor'; import { FileInterceptor } from '@nestjs/platform-express'; import { LXDHubAPISettings } from '../main'; import { ImportImageDto } from './dtos/import-image.dto'; /** * The Image Controller, which is the API * interface for Image-Operations. */ @Controller('/api/v1/image') export class ImageController { private logger; constructor( private readonly imageService: ImageService, @Inject('LXDHubAPISettings') private settings: LXDHubAPISettings ) { this.logger = new Logger('image.controller'); } /** * Returns images, limited by the given pagination options and * filters it by the given remoteId. * If remoteId is not given, it takes the first remote. * @param options The options to paginate through the requested data */ @Get('/') @UseInterceptors(ImageListItemInterceptor) @ApiResponse({ status: 200, description: 'The images have been successfully requested' }) @ApiResponse({ status: 400, description: 'Bad Request' }) @ApiResponse({ status: 404, description: 'Remote not found' }) async findByRemote( @Query(new ValidationPipe({ transform: true })) options: ImageListOptions ): Promise<ImageListItemResponse> { try { // Fetches the images return await this.imageService .findByRemote(options.remote, options, options.query ? options.query.trim() : null); } catch (err) { if (err instanceof TypeError) { // Is a search query error throw new BadRequestException(err.message); } else if (err instanceof NotFoundException) { // Not found throw err; } else { // Unknwon error. Should not occur throw new InternalServerErrorException('Internal Server Error'); } } } /** * Returns a detail image with the given id * @param {number} fingerprint The fingerprint of the image */ @Get('/:fingerprint') @ApiResponse({ status: 200, description: 'The image have been successfully requested' }) @ApiResponse({ status: 400, description: 'Bad Request' }) async findOne( @Param('fingerprint') fingerprint: string ): Promise<ResponseDto<ImageDetailDto>> { return await this.imageService.findOne(fingerprint); } /** * Clones the image with the given id * @param {number} id The id of the image */ @Post('/:id/clone') @ApiResponse({ status: 200, description: 'The image have been successfully cloned' }) @ApiResponse({ status: 404, description: 'Not Found' }) @ApiResponse({ status: 403, description: 'Not Authorized' }) @ApiResponse({ status: 500, description: 'The destination LXD remote is not reachable' }) async clone( // Convert id to an integer @Param('id', new ParseIntPipe()) id: number, @Body() cloneImageDto: CloneImageDto ) : Promise<ResponseDto<CloneImageResponseDto>> { return await this.imageService.cloneImage(id, cloneImageDto); } @Post('/') @ApiResponse({ status: 200, description: 'The image was imported successfully' }) @UseInterceptors(FileInterceptor('image')) async import( @UploadedFile() image, @Body() body: ImportImageDto ) { if (this.settings.upload) { return await this.imageService.importImage(image, body.remote, body.aliases); } else { throw new ForbiddenException('Image upload is disabled!'); } } }