public async Task <string> CreateAsync(int studyId, IFormFile studyLogo) { var studyFromDb = await _studyModelService.GetByIdAsync(studyId, UserOperation.Study_Update_Metadata); if (!FileIsCorrectImageFormat(studyLogo)) { throw new ArgumentException("Blob has invalid filename or is not of type png, jpg or bmp."); } string uniqueFileName = Guid.NewGuid().ToString("N") + studyLogo.FileName; await _azureBlobStorageService.UploadFileToBlobContainer(_containerName, uniqueFileName, studyLogo); string oldFileName = studyFromDb.LogoUrl; studyFromDb.LogoUrl = uniqueFileName; await _db.SaveChangesAsync(); if (!String.IsNullOrWhiteSpace(oldFileName)) { _ = await _azureBlobStorageService.DeleteFileFromBlobContainer(_containerName, oldFileName); } return(studyFromDb.LogoUrl); }
public async Task Add(string wbsCode) { var queryable = GetItemQueryable(wbsCode); if (queryable.Any()) { var existingItem = await queryable.SingleOrDefaultAsync(); existingItem.Expires = GetNewExpires(); } else { _sepesDbContext.WbsCodeCache.Add(new WbsCodeCache(wbsCode.ToLowerInvariant(), GetNewExpires())); } await _sepesDbContext.SaveChangesAsync(); }
async Task OrderCreationOfStudySpecificDatasetStorageAccount(Study study, Dataset dataset, CloudResource resourceGroup, string clientIp, ProvisioningQueueParentDto queueParent, CancellationToken cancellationToken) { try { if (resourceGroup == null) { throw new ArgumentNullException("resourceGroup", "Resource group entry is null"); } _logger.LogInformation($"CreateResourcesForStudySpecificDataset - Dataset Id: {dataset.Id}"); var currentUser = await _userService.GetCurrentUserAsync(); var tagsForStorageAccount = ResourceTagFactory.StudySpecificDatasourceStorageAccountTags(_config, study, dataset.Name); var storageAccountName = AzureResourceNameUtil.StudySpecificDataSetStorageAccount(dataset.Name); var resourceEntry = await _cloudResourceCreateService.CreateStudySpecificDatasetEntryAsync(dataset.Id, resourceGroup.Id, resourceGroup.Region, resourceGroup.ResourceGroupName, storageAccountName, tagsForStorageAccount); ProvisioningQueueUtil.CreateChildAndAdd(queueParent, resourceEntry); var serverPublicIp = await _publicIpService.GetIp(); DatasetFirewallUtils.EnsureDatasetHasFirewallRules(_logger, currentUser, dataset, clientIp, serverPublicIp); await _db.SaveChangesAsync(); var stateForFirewallOperation = DatasetFirewallUtils.TranslateAllowedIpsToOperationDesiredState(dataset.FirewallRules.ToList()); var createStorageAccountOperation = CloudResourceOperationUtil.GetCreateOperation(resourceEntry); var firewallUpdateOperation = await _cloudResourceOperationCreateService.CreateUpdateOperationAsync(resourceEntry.Id, CloudResourceOperationType.ENSURE_FIREWALL_RULES, dependsOn : createStorageAccountOperation.Id, desiredState : stateForFirewallOperation); ProvisioningQueueUtil.CreateChildAndAdd(queueParent, firewallUpdateOperation); var stateForCorsRules = DatasetCorsUtils.CreateDatasetCorsRules(_config); var corsUpdateOperation = await _cloudResourceOperationCreateService.CreateUpdateOperationAsync(resourceEntry.Id, CloudResourceOperationType.ENSURE_CORS_RULES, dependsOn : firewallUpdateOperation.Id, desiredState : stateForCorsRules); ProvisioningQueueUtil.CreateChildAndAdd(queueParent, corsUpdateOperation); } catch (Exception ex) { throw new Exception($"Failed to schedule creation of Azure Storage Account", ex); } }
public async Task <int> Add(TModel entity) { Validate(entity); var dbSet = _db.Set <TModel>(); dbSet.Add(entity); await _db.SaveChangesAsync(); return(entity.Id); }
public async Task UndoResourceCreationAsync(int sandboxId) { var sandboxFromDb = await _sandboxModelService.GetWithResourcesNoPermissionCheckAsync(sandboxId); foreach (var curRes in sandboxFromDb.Resources) { foreach (var curOp in curRes.Operations) { _db.CloudResourceOperations.Remove(curOp); } _db.CloudResources.Remove(curRes); } await _db.SaveChangesAsync(); }
public async Task Import(CancellationToken cancellationToken = default) { var currentUser = await _userService.GetCurrentUserAsync(); var regionsFromDb = await _db.Regions.Include(r => r.DiskSizeAssociations).ThenInclude(va => va.DiskSize).Where(r => !r.Disabled).ToListAsync(); if (regionsFromDb.Count() == 0) { throw new Exception($"Could not update Vm Disk Cache, No regions found in DB"); } var diskEntriesFromAzure = await _azureDiskPriceService.GetDiskPrices(cancellationToken : cancellationToken); if (diskEntriesFromAzure == null || (diskEntriesFromAzure != null && diskEntriesFromAzure.Count() == 0)) { throw new Exception("No VM Disk Size and Price found in Azure"); } foreach (var curRegionFromDb in regionsFromDb) { _logger.LogInformation($"Updating VM Disk Cache for Region: {curRegionFromDb.Key}"); try { if (diskEntriesFromAzure.TryGetValue(curRegionFromDb.KeyInPriceApi, out AzureDiskPriceForRegion diskSizesForRegion)) { _logger.LogInformation($"Updating VM Size Cache for Region: {curRegionFromDb.Key}. Found {diskSizesForRegion.Types.Count} Disk sizes for region"); var existingDbItemsForRegion = curRegionFromDb.DiskSizeAssociations.ToDictionary(r => r.DiskSize.Key, r => r.DiskSize); var validDiskSizesFromAzure = new HashSet <string>(); DiskSize curDiskSizeInDb; foreach (var curDiskSizeForRegion in diskSizesForRegion.Types) { if (existingDbItemsForRegion.TryGetValue(curDiskSizeForRegion.Key, out curDiskSizeInDb)) { //Get updated price for VM Size var regionAssociation = curDiskSizeInDb.RegionAssociations.Where(ra => ra.RegionKey == curRegionFromDb.Key).SingleOrDefault(); regionAssociation.Price = curDiskSizeForRegion.Value.price; await _db.SaveChangesAsync(); validDiskSizesFromAzure.Add(curDiskSizeInDb.Key); } else { //Size item might exist in db for other region curDiskSizeInDb = await _db.DiskSizes.FirstOrDefaultAsync(r => r.Key == curDiskSizeForRegion.Key); if (curDiskSizeInDb == null) { curDiskSizeInDb = new DiskSize() { Key = curDiskSizeForRegion.Key, Size = curDiskSizeForRegion.Value.size, DisplayText = AzureVmUtil.GetDiskSizeDisplayTextForDropdown(curDiskSizeForRegion.Value.size), CreatedBy = currentUser.UserName }; } ; //Add to lookup existingDbItemsForRegion.Add(curDiskSizeForRegion.Key, curDiskSizeInDb); //Add to DB curRegionFromDb.DiskSizeAssociations.Add(new RegionDiskSize() { Region = curRegionFromDb, DiskSize = curDiskSizeInDb, Price = curDiskSizeForRegion.Value.price }); await _db.SaveChangesAsync(); validDiskSizesFromAzure.Add(curDiskSizeForRegion.Key); } } //Delete those that are no longer present in Azure, or that does not pass the filter foreach (var curDbDiskSize in existingDbItemsForRegion.Values) { if (!validDiskSizesFromAzure.Contains(curDbDiskSize.Key)) { var toRemoveFromDb = curRegionFromDb.DiskSizeAssociations.FirstOrDefault(ra => ra.VmDiskKey == curDbDiskSize.Key); if (toRemoveFromDb != null) { curRegionFromDb.DiskSizeAssociations.Remove(toRemoveFromDb); } } } await _db.SaveChangesAsync(); _logger.LogInformation($"Done updating VM Disk Size and Price Cache for Region: {curRegionFromDb.Name}"); } else { _logger.LogError($"Update VM Size cache: Unable to update Size cache for Region {curRegionFromDb.Key}. No items for region in response"); } } catch (Exception ex) { _logger.LogError($"Update VM Size cache: Unable to update Size cache for Region {curRegionFromDb.Key}. Se inner exception for details", ex); continue; } } _logger.LogInformation($"Deleting Disk size entries not associated with any region"); foreach (var curDiskSize in await _db.DiskSizes.Include(s => s.RegionAssociations).ToListAsync()) { if (curDiskSize.RegionAssociations == null || (curDiskSize.RegionAssociations != null && curDiskSize.RegionAssociations.Count == 0)) { _db.DiskSizes.Remove(curDiskSize); } } await _db.SaveChangesAsync(); _logger.LogInformation($"Done updating VM Disk size cache"); }
public async Task UpdateVmSizeCache(CancellationToken cancellationToken = default) { var currentUser = await _userService.GetCurrentUserAsync(); var regionsFromDb = await _db.Regions.Include(r => r.VmSizeAssociations).ThenInclude(va => va.VmSize).Where(r => !r.Disabled).ToListAsync(); if (regionsFromDb == null || (regionsFromDb != null & regionsFromDb.Count() == 0)) { throw new Exception($"Could not update Vm Size Cache, No regions found in DB"); } foreach (var curRegionFromDb in regionsFromDb) { _logger.LogInformation($"Updating VM Size Cache for Region: {curRegionFromDb.Key}"); try { var resourceSkusFromAzure = await _azureResourceSkuService.GetSKUsForRegion(curRegionFromDb.Key, "virtualMachines", filterBasedOnResponseRestrictions : true, cancellationToken); if (resourceSkusFromAzure == null || (resourceSkusFromAzure != null && resourceSkusFromAzure.Count() == 0)) { throw new Exception($"No VM SKUs found in Azure for region {curRegionFromDb.Key}"); } _logger.LogInformation($"Updating VM Size Cache for Region: {curRegionFromDb.Key}. Found {resourceSkusFromAzure.Count()} SKUs for region"); var existingSizeItemsForRegion = curRegionFromDb.VmSizeAssociations.ToDictionary(r => r.VmSize.Key, r => r.VmSize); var validSkusFromAzure = new HashSet <string>(); VmSize curVmSizeInDb; foreach (var curAzureSku in resourceSkusFromAzure) { if (existingSizeItemsForRegion.TryGetValue(curAzureSku.Name, out curVmSizeInDb)) { curVmSizeInDb.Category = AzureVmUtil.GetSizeCategory(curAzureSku.Name); if (ShouldBeExcluded(curVmSizeInDb)) { var toRemoveFromDb = curRegionFromDb.VmSizeAssociations.FirstOrDefault(ra => ra.VmSizeKey == curVmSizeInDb.Key); curRegionFromDb.VmSizeAssociations.Remove(toRemoveFromDb); await _db.SaveChangesAsync(); continue; } else { PopulateVmSizeProps(curAzureSku, curVmSizeInDb); curVmSizeInDb.DisplayText = VmSizeUtil.GetDisplayTextSizeForDropdown(curVmSizeInDb); //Get updated price for VM Size and set on db entry var regionAssociation = curVmSizeInDb.RegionAssociations.Where(ra => ra.RegionKey == curRegionFromDb.Key).SingleOrDefault(); regionAssociation.Price = await _azureCostManagementService.GetVmPrice(curRegionFromDb.Key, curVmSizeInDb.Key); await _db.SaveChangesAsync(); validSkusFromAzure.Add(curVmSizeInDb.Key); } } else { //Size item might exist in db for other region curVmSizeInDb = await _db.VmSizes.FirstOrDefaultAsync(r => r.Key == curAzureSku.Name); if (curVmSizeInDb == null) { curVmSizeInDb = new VmSize() { Key = curAzureSku.Name, CreatedBy = currentUser.UserName, Category = AzureVmUtil.GetSizeCategory(curAzureSku.Name) }; } else { curVmSizeInDb.Category = AzureVmUtil.GetSizeCategory(curAzureSku.Name); } if (ShouldBeExcluded(curVmSizeInDb)) { //Dont want to include these continue; } PopulateVmSizeProps(curAzureSku, curVmSizeInDb); curVmSizeInDb.DisplayText = VmSizeUtil.GetDisplayTextSizeForDropdown(curVmSizeInDb); //Add to lookup existingSizeItemsForRegion.Add(curAzureSku.Name, curVmSizeInDb); var priceOfVm = await _azureCostManagementService.GetVmPrice(curRegionFromDb.Key, curVmSizeInDb.Key); //Add to DB curRegionFromDb.VmSizeAssociations.Add(new RegionVmSize() { Region = curRegionFromDb, VmSize = curVmSizeInDb, Price = priceOfVm }); await _db.SaveChangesAsync(); validSkusFromAzure.Add(curVmSizeInDb.Key); } } //Delete those that are no longer present in Azure, or that does not pass the filter foreach (var curDbSize in existingSizeItemsForRegion.Values) { if (!validSkusFromAzure.Contains(curDbSize.Key)) { var toRemoveFromDb = curRegionFromDb.VmSizeAssociations.FirstOrDefault(ra => ra.VmSizeKey == curDbSize.Key); if (toRemoveFromDb != null) { curRegionFromDb.VmSizeAssociations.Remove(toRemoveFromDb); } } } await _db.SaveChangesAsync(); _logger.LogInformation($"Done updating VM Size Cache for Region: {curRegionFromDb.Name}"); } catch (Exception ex) { _logger.LogError($"Update VM Size cache: Unable to update Size cache for Region {curRegionFromDb.Key}. Se inner exception for details", ex); continue; } } _logger.LogInformation($"Deleting Vm Size entries not associated with any region"); foreach (var curVmSize in await _db.VmSizes.Include(s => s.RegionAssociations).ToListAsync()) { if (curVmSize.RegionAssociations == null || (curVmSize.RegionAssociations != null && curVmSize.RegionAssociations.Count == 0)) { _db.VmSizes.Remove(curVmSize); } } await _db.SaveChangesAsync(); //TODO: Delete size records with no associated region? _logger.LogInformation($"Done updating VM Size Cache"); }
public async Task <SandboxDetails> MoveToNextPhaseAsync(int sandboxId, CancellationToken cancellation = default) { _logger.LogInformation(_sandboxNextPhaseEventId, "Sandbox {0}: Starting", sandboxId); SandboxPhaseHistory newestHistoryItem = null; bool dataMightHaveBeenChanged = false; try { var user = await _userService.GetCurrentUserAsync(); var sandboxFromDb = await GetSandboxForPhaseShift(sandboxId); var currentPhaseItem = SandboxPhaseUtil.GetCurrentPhaseHistoryItem(sandboxFromDb); if (currentPhaseItem == null) { SandboxPhaseUtil.InitiatePhaseHistory(sandboxFromDb, user); currentPhaseItem = SandboxPhaseUtil.GetCurrentPhaseHistoryItem(sandboxFromDb); } var nextPhase = SandboxPhaseUtil.GetNextPhase(sandboxFromDb); await ValidatePhaseMoveThrowIfNot(sandboxFromDb, currentPhaseItem.Phase, nextPhase, cancellation); _logger.LogInformation(_sandboxNextPhaseEventId, "Sandbox {0}: Moving from {1} to {2}", sandboxId, currentPhaseItem.Phase, nextPhase); newestHistoryItem = new SandboxPhaseHistory() { Counter = currentPhaseItem.Counter + 1, Phase = nextPhase, CreatedBy = user.UserName }; dataMightHaveBeenChanged = true; sandboxFromDb.PhaseHistory.Add(newestHistoryItem); await _db.SaveChangesAsync(); _logger.LogInformation(_sandboxNextPhaseEventId, "Sandbox {0}: Phase added to db. Proceeding to make data available", sandboxId); if (nextPhase == SandboxPhase.DataAvailable) { await MakeDatasetsAvailable(sandboxFromDb, cancellation); } _logger.LogInformation(_sandboxNextPhaseEventId, "Sandbox {0}: Done", sandboxId); return(await GetSandboxDetailsInternalAsync(sandboxId)); } catch (Exception ex) { _logger.LogWarning(_sandboxNextPhaseEventId, ex, "Sandbox {0}: Phase shift failed.", sandboxId); if (dataMightHaveBeenChanged) { _logger.LogWarning(_sandboxNextPhaseEventId, ex, "Data might have been changed. Rolling back"); await MakeDatasetsUnAvailable(sandboxId); await AttemptRollbackPhase(sandboxId, newestHistoryItem); } throw; } }