// Copyright Epic Games, Inc. All Rights Reserved. using HordeServer.Api; using HordeServer.Models; using HordeServer.Services; using HordeServer.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using MongoDB.Bson; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; namespace HordeServer.Controllers { using PoolId = StringId; /// /// Controller for the /api/v1/pools endpoint /// [ApiController] [Authorize] [Route("[controller]")] public class PoolsController : ControllerBase { /// /// Singleton instance of the ACL service /// private readonly AclService AclService; /// /// Singleton instance of the pool service /// private readonly PoolService PoolService; /// /// Constructor /// /// The ACL service /// The pool service public PoolsController(AclService AclService, PoolService PoolService) { this.AclService = AclService; this.PoolService = PoolService; } /// /// Creates a new pool /// /// Parameters for the new pool. /// Http result code [HttpPost] [Route("/api/v1/pools")] public async Task> CreatePoolAsync([FromBody] CreatePoolRequest Create) { if(!await AclService.AuthorizeAsync(AclAction.CreatePool, User)) { return Forbid(); } IPool NewPool = await PoolService.CreatePoolAsync(Create.Name, Create.Condition, Create.EnableAutoscaling, Create.MinAgents, Create.NumReserveAgents, Create.Properties); return new CreatePoolResponse(NewPool.Id.ToString()); } /// /// Query all the pools /// /// Filter for the properties to return /// Information about all the pools [HttpGet] [Route("/api/v1/pools")] [ProducesResponseType(typeof(List), 200)] public async Task>> GetPoolsAsync([FromQuery] PropertyFilter? Filter = null) { if (!await AclService.AuthorizeAsync(AclAction.ListPools, User)) { return Forbid(); } List Pools = await PoolService.GetPoolsAsync(); List Responses = new List(); foreach (IPool Pool in Pools) { Responses.Add(new GetPoolResponse(Pool).ApplyFilter(Filter)); } return Responses; } /// /// Retrieve information about a specific pool /// /// Id of the pool to get information about /// Filter to apply to the returned properties /// Information about the requested pool [HttpGet] [Route("/api/v1/pools/{PoolId}")] [ProducesResponseType(typeof(GetPoolResponse), 200)] public async Task> GetPoolAsync(string PoolId, [FromQuery] PropertyFilter? Filter = null) { if (!await AclService.AuthorizeAsync(AclAction.ViewPool, User)) { return Forbid(); } PoolId PoolIdValue = new PoolId(PoolId); IPool? Pool = await PoolService.GetPoolAsync(PoolIdValue); if (Pool == null) { return NotFound(); } return new GetPoolResponse(Pool).ApplyFilter(Filter); } /// /// Update a pool's properties. /// /// Id of the pool to update /// Items on the pool to update /// Http result code [HttpPut] [Route("/api/v1/pools/{PoolId}")] public async Task UpdatePoolAsync(string PoolId, [FromBody] UpdatePoolRequest Update) { if (!await AclService.AuthorizeAsync(AclAction.UpdatePool, User)) { return Forbid(); } PoolId PoolIdValue = new PoolId(PoolId); IPool? Pool = await PoolService.GetPoolAsync(PoolIdValue); if(Pool == null) { return NotFound(); } await PoolService.UpdatePoolAsync(Pool, Update.Name, Update.Condition, Update.EnableAutoscaling, Update.MinAgents, Update.NumReserveAgents, Update.Properties); return new OkResult(); } /// /// Delete a pool /// /// Id of the pool to delete /// Http result code [HttpDelete] [Route("/api/v1/pools/{PoolId}")] public async Task DeletePoolAsync(string PoolId) { if (!await AclService.AuthorizeAsync(AclAction.DeletePool, User)) { return Forbid(); } PoolId PoolIdValue = new PoolId(PoolId); if(!await PoolService.DeletePoolAsync(PoolIdValue)) { return NotFound(); } return new OkResult(); } /// /// Batch update pool properties /// /// List of pools to update /// Http result code [HttpPut] [Route("/api/v1/pools")] public async Task UpdatePoolAsync([FromBody] List BatchUpdates) { if (!await AclService.AuthorizeAsync(AclAction.UpdatePool, User)) { return Forbid(); } foreach (BatchUpdatePoolRequest Update in BatchUpdates) { PoolId PoolIdValue = new PoolId(Update.Id); IPool? Pool = await PoolService.GetPoolAsync(PoolIdValue); if (Pool == null) { return NotFound(); } await PoolService.UpdatePoolAsync(Pool, Update.Name, NewProperties: Update.Properties); } return new OkResult(); } } }