public async Task <Vm> CreateAsync(VmCreateForm form, CancellationToken ct) { if (_context.Vms.Where(v => v.Id == form.Id).Any()) { throw new ForbiddenException("Vm already exists"); } var vmEntity = _mapper.Map <Domain.Models.Vm>(form); var formTeams = vmEntity.VmTeams.Select(v => v.TeamId).Distinct(); if (!formTeams.Any()) { throw new ForbiddenException("Must include at least 1 team"); } if (!(await _playerService.CanManageTeamsAsync(formTeams, true, ct))) { throw new ForbiddenException(); } if (!(await _permissionsService.CanWrite(formTeams, ct))) { throw new ForbiddenException(); } var teamList = await _context.Teams .Where(t => formTeams.Contains(t.Id)) .Select(t => t.Id) .ToListAsync(ct); foreach (var vmTeam in vmEntity.VmTeams) { if (!teamList.Contains(vmTeam.TeamId)) { _context.Teams.Add(new Domain.Models.Team() { Id = vmTeam.TeamId }); } } _context.Vms.Add(vmEntity); await _context.SaveChangesAsync(ct); return(_mapper.Map <Vm>(vmEntity)); }
public async Task <Response> Handle(Command request, CancellationToken cancellationToken) { var errorsDict = new Dictionary <Guid, string>(); var acceptedList = new List <Guid>(); var vms = await _dbContext.Vms .Include(x => x.VmTeams) .Where(x => request.Ids.Contains(x.Id)) .ToListAsync(cancellationToken); foreach (var id in request.Ids) { var vm = vms.Where(x => x.Id == id).FirstOrDefault(); if (vm == null) { errorsDict.Add(id, "Virtual Machine Not Found"); } else if (vm.PowerState == PowerState.Unknown) { errorsDict.Add(id, "Unsupported Operation"); } else if (!await _playerService.CanAccessTeamsAsync(vm.VmTeams.Select(x => x.TeamId), cancellationToken)) { errorsDict.Add(id, "Unauthorized"); } else if (!await _permissionsService.CanWrite(vm.VmTeams.Select(x => x.TeamId), cancellationToken)) { errorsDict.Add(id, "Insufficient Permissions"); } else { acceptedList.Add(id); } } foreach (var vm in vms.Where(x => acceptedList.Contains(x.Id))) { vm.HasPendingTasks = true; } await _dbContext.SaveChangesAsync(); if (request.Operation == PowerOperation.Shutdown) { var results = await _vsphereService.BulkShutdown(acceptedList.ToArray()); errorsDict = errorsDict .Concat(results) .ToLookup(x => x.Key, x => x.Value) .ToDictionary(x => x.Key, g => g.First()); } else { await _vsphereService.BulkPowerOperation(acceptedList.ToArray(), request.Operation); } return(new Response { Accepted = acceptedList.ToArray(), Errors = errorsDict.Where(x => !string.IsNullOrEmpty(x.Value)).ToDictionary(x => x.Key.ToString(), y => y.Value) }); }