async Task ReScheduleSandboxResourceCreation(int sandboxId)
        {
            var sandbox = await _sandboxModelService.GetByIdForReScheduleCreateAsync(sandboxId);

            EnsureHasAllRequiredResourcesThrowIfNot(sandbox);

            var queueParentItem = QueueItemFactory.CreateParent($"Create basic resources for Sandbox (re-scheduled): {sandbox.Id}");

            foreach (var currentSandboxResource in sandbox.Resources.Where(r => r.SandboxControlled).OrderBy(r => r.Id))
            {
                var resourceCreateOperation = CloudResourceOperationUtil.GetCreateOperation(currentSandboxResource);

                if (resourceCreateOperation == null)
                {
                    throw new Exception(ReScheduleLogPrefix(sandbox.StudyId, sandbox.Id, $"Could not locate create operation for resource {currentSandboxResource.Id} - {currentSandboxResource.ResourceName}"));
                }

                if (resourceCreateOperation.Status == CloudResourceOperationState.ABANDONED)
                {
                    throw new Exception(ReScheduleLogPrefix(sandbox.StudyId, sandbox.Id, $"Create operation for resource {currentSandboxResource.Id} - {currentSandboxResource.ResourceName} was abandoned. Cannot proceed"));
                }

                await EnsureOperationIsReadyForRetryAndAddToQueueItem(currentSandboxResource, resourceCreateOperation, queueParentItem);
            }

            if (queueParentItem.Children.Count == 0)
            {
                throw new Exception(ReScheduleLogPrefix(sandbox.StudyId, sandbox.Id, $"Could not re-shedule creation. No relevant resource items found"));
            }
            else
            {
                await _provisioningQueueService.SendMessageAsync(queueParentItem);
            }
        }
        public async Task CreateResourceGroupForStudySpecificDatasetsAsync(Study study, CancellationToken cancellationToken = default)
        {
            var studyForCreation = await _studyModelService.GetForDatasetCreationNoAccessCheckAsync(study.Id);

            var resourceGroupForDatasets = GetResourceGroupForStudySpecificDataset(studyForCreation);

            var parentQueueItem = QueueItemFactory.CreateParent("Create resource group for Study specific datasets");

            if (resourceGroupForDatasets == null)
            {
                var resourceGroupName = AzureResourceNameUtil.StudySpecificDatasetResourceGroup(studyForCreation.Name);
                var tags = ResourceTagFactory.StudySpecificDatasourceResourceGroupTags(_config, studyForCreation);
                resourceGroupForDatasets = await _cloudResourceCreateService.CreateStudySpecificResourceGroupEntryAsync(studyForCreation.Id, resourceGroupName, "norwayeast", tags);

                ProvisioningQueueUtil.CreateChildAndAdd(parentQueueItem, resourceGroupForDatasets);
            }
            else
            {
                throw new Exception("Resource group allready exists");
            }

            await ScheduleResourceGroupRoleAssignments(studyForCreation, resourceGroupForDatasets, parentQueueItem);

            await _provisioningQueueService.SendMessageAsync(parentQueueItem, cancellationToken : cancellationToken);
        }
Esempio n. 3
0
        public async Task DeleteAsync(int id)
        {
            var deleteResourceOperation = await _cloudResourceDeleteService.MarkAsDeletedWithDeleteOperationAsync(id, UserOperation.Study_Crud_Sandbox);

            _logger.LogInformation($"Delete VM: Enqueing delete operation");

            var queueParentItem = QueueItemFactory.CreateParent(deleteResourceOperation);

            await _provisioningQueueService.SendMessageAsync(queueParentItem);
        }
Esempio n. 4
0
        public async Task HandleSandboxDeleteAsync(int sandboxId, EventId eventId)
        {
            var sandboxFromDb = await _sandboxModelService.GetWithResourcesNoPermissionCheckAsync(sandboxId);

            CloudResource sandboxResourceGroup = null;

            if (sandboxFromDb.Resources.Count > 0)
            {
                //Mark all resources as deleted
                foreach (var curResource in sandboxFromDb.Resources)
                {
                    if (curResource.ResourceType == AzureResourceType.ResourceGroup)
                    {
                        sandboxResourceGroup = curResource;
                    }

                    _logger.LogInformation(eventId, "Study {0}, Sandbox {1}: Marking resource {2} for deletion", sandboxFromDb.StudyId, sandboxId, curResource.Id);

                    await _cloudResourceDeleteService.MarkAsDeletedAsync(curResource.Id);
                }

                if (sandboxResourceGroup == null)
                {
                    throw new Exception($"Unable to find ResourceGroup record in DB for Sandbox {sandboxId}, StudyId: {sandboxFromDb.StudyId}.");
                }

                _logger.LogInformation(eventId, $"Creating delete operation for resource group {sandboxResourceGroup.ResourceGroupName}");

                var deleteOperation = await _cloudResourceOperationCreateService.CreateDeleteOperationAsync(sandboxResourceGroup.Id, ResourceOperationDescriptionUtils.CreateDescriptionForResourceOperation(sandboxResourceGroup.ResourceType,
                                                                                                                                                                                                             CloudResourceOperationType.DELETE,
                                                                                                                                                                                                             sandboxId: sandboxResourceGroup.SandboxId.Value) + ". (Delete of Sandbox resource group and all resources within)");

                _logger.LogInformation(eventId, "Study {0}, Sandbox {1}: Queuing operation", sandboxFromDb.StudyId, sandboxId);

                var queueParentItem = QueueItemFactory.CreateParent(deleteOperation);

                await _provisioningQueueService.SendMessageAsync(queueParentItem, visibilityTimeout : TimeSpan.FromSeconds(10));
            }
            else
            {
                _logger.LogCritical(eventId, "Study {0}, Sandbox {1}: Unable to find any resources for Sandbox", sandboxFromDb.StudyId, sandboxId);
            }
        }
Esempio n. 5
0
        public async Task CreateBasicSandboxResourcesAsync(Sandbox sandbox)
        {
            _logger.LogInformation($"Creating basic sandbox resources for sandbox: {sandbox.Name}. First creating Resource Group, other resources are created by worker");

            try
            {
                var tags = ResourceTagFactory.SandboxResourceTags(_configuration, sandbox.Study, sandbox);

                var creationAndSchedulingDto =
                    new SandboxResourceCreationAndSchedulingDto()
                {
                    StudyId     = sandbox.Study.Id,
                    SandboxId   = sandbox.Id,
                    StudyName   = sandbox.Study.Name,
                    SandboxName = sandbox.Name,
                    Region      = sandbox.Region,
                    Tags        = tags,
                    BatchId     = Guid.NewGuid().ToString()
                };

                var queueParentItem = new ProvisioningQueueParentDto
                {
                    Description = $"Create basic resources for Sandbox: {creationAndSchedulingDto.SandboxId}"
                };

                await ScheduleCreationOfSandboxResourceGroup(creationAndSchedulingDto, queueParentItem);
                await ScheduleCreationOfSandboxResourceGroupRoleAssignments(creationAndSchedulingDto, queueParentItem);
                await ScheduleCreationOfDiagStorageAccount(creationAndSchedulingDto, queueParentItem);
                await ScheduleCreationOfNetworkSecurityGroup(creationAndSchedulingDto, queueParentItem);
                await ScheduleCreationOfVirtualNetwork(creationAndSchedulingDto, queueParentItem);
                await ScheduleCreationOfBastion(creationAndSchedulingDto, queueParentItem);

                await _provisioningQueueService.SendMessageAsync(queueParentItem);

                _logger.LogInformation($"Done ordering creation of basic resources for sandbox: {creationAndSchedulingDto.SandboxName}");
            }
            catch (Exception ex)
            {
                throw new Exception($"Unable to create basic sandbox resources.", ex);
            }
        }
        public async Task <VmDto> CreateAsync(int sandboxId, VirtualMachineCreateDto userInput)
        {
            CloudResource vmResourceEntry = null;

            try
            {
                ValidateVmPasswordOrThrow(userInput.Password);

                GenericNameValidation.ValidateName(userInput.Name);

                _logger.LogInformation($"Creating Virtual Machine for sandbox: {sandboxId}");

                var sandbox = await _sandboxModelService.GetByIdForResourceCreationAsync(sandboxId, UserOperation.Study_Crud_Sandbox);

                var virtualMachineName = AzureResourceNameUtil.VirtualMachine(sandbox.Study.Name, sandbox.Name, userInput.Name);

                await _cloudResourceCreateService.ValidateThatNameDoesNotExistThrowIfInvalid(virtualMachineName);

                var tags = ResourceTagFactory.SandboxResourceTags(_config, sandbox.Study, sandbox);

                var region = RegionStringConverter.Convert(sandbox.Region);

                userInput.DataDisks = await TranslateDiskSizes(sandbox.Region, userInput.DataDisks);

                var resourceGroup = await CloudResourceQueries.GetResourceGroupEntry(_db, sandboxId);

                //Make this dependent on bastion create operation to be completed, since bastion finishes last
                var dependsOn = await CloudResourceQueries.GetCreateOperationIdForBastion(_db, sandboxId);

                vmResourceEntry = await _cloudResourceCreateService.CreateVmEntryAsync(sandboxId, resourceGroup, region.Name, tags, virtualMachineName, dependsOn, null);

                //Create vm settings and immeately attach to resource entry
                var vmSettingsString = await CreateVmSettingsString(sandbox.Region, vmResourceEntry.Id, sandbox.Study.Id, sandboxId, userInput);

                vmResourceEntry.ConfigString = vmSettingsString;
                await _cloudResourceUpdateService.Update(vmResourceEntry.Id, vmResourceEntry);

                var queueParentItem = new ProvisioningQueueParentDto
                {
                    Description = $"Create VM for Sandbox: {sandboxId}"
                };

                queueParentItem.Children.Add(new ProvisioningQueueChildDto()
                {
                    ResourceOperationId = vmResourceEntry.Operations.FirstOrDefault().Id
                });

                await _provisioningQueueService.SendMessageAsync(queueParentItem);

                var dtoMappedFromResource = _mapper.Map <VmDto>(vmResourceEntry);

                return(dtoMappedFromResource);
            }
            catch (Exception ex)
            {
                try
                {
                    //Delete resource if created
                    if (vmResourceEntry != null)
                    {
                        await _cloudResourceDeleteService.HardDeleteAsync(vmResourceEntry.Id);
                    }
                }
                catch (Exception rollbackEx)
                {
                    _logger.LogError(rollbackEx, $"Failed to roll back VM creation for sandbox {sandboxId}");
                }

                throw new Exception($"Failed to create VM: {ex.Message}", ex);
            }
        }