Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
            }
        }
Exemplo n.º 4
0
        public async Task <int> Add(TModel entity)
        {
            Validate(entity);

            var dbSet = _db.Set <TModel>();

            dbSet.Add(entity);
            await _db.SaveChangesAsync();

            return(entity.Id);
        }
Exemplo n.º 5
0
        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();
        }
Exemplo n.º 6
0
        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");
        }
Exemplo n.º 8
0
        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;
            }
        }