public string Resolve(CloudResource source, SandboxResourceLight destination, string destMember, ResolutionContext context) { if (source != null) { var shouldHaveRetryLink = false; var baseStatusOnThisOperation = ResourceStatusUtil.DecideWhatOperationToBaseStatusOn(source); if (baseStatusOnThisOperation == null) { shouldHaveRetryLink = true; } else if (CloudResourceOperationUtil.HasValidStateForRetry(baseStatusOnThisOperation)) { shouldHaveRetryLink = true; } if (shouldHaveRetryLink) { return(AzureResourceUtil.CreateResourceRetryLink(source.Id)); } } return(null); }
public async Task <CloudResource> CreateStudySpecificDatasetEntryAsync(int datasetId, int resourceGroupEntryId, string region, string resourceGroupName, string resourceName, Dictionary <string, string> tags) { var currentUser = await _userService.GetCurrentUserAsync(); var sessionId = _requestIdService.GetRequestId(); var resourceGroupEntry = await GetInternalWithoutAccessCheckAsync(resourceGroupEntryId); if (resourceGroupEntry == null) { throw new Exception("Could not find Resource Group entry"); } var resourceGroupCreateOperation = CloudResourceOperationUtil.GetCreateOperation(resourceGroupEntry); if (resourceGroupCreateOperation == null) { throw new Exception("Could not find Resource Group create operation entry"); } var resourceEntry = CloudResourceFactory.CreateStudySpecificDatasetStorageAccountEntry( currentUser, sessionId, datasetId, region, resourceGroupEntryId, resourceGroupName, resourceName, tags, resourceGroupCreateOperation.Id); await SaveToDb(resourceEntry); return(resourceEntry); }
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); } }
async Task ScheduleResourceGroupRoleAssignments(Study study, CloudResource resourceGroup, ProvisioningQueueParentDto queueParentItem) { var participants = await _db.StudyParticipants.Include(sp => sp.User).Where(p => p.StudyId == study.Id).ToListAsync(); var desiredState = CloudResourceConfigStringSerializer.Serialize(new CloudResourceOperationStateForRoleUpdate(study.Id)); var resourceGroupCreateOperation = CloudResourceOperationUtil.GetCreateOperation(resourceGroup); var roleAssignmentUpdateOperation = await _cloudResourceOperationCreateService.CreateUpdateOperationAsync(resourceGroup.Id, CloudResourceOperationType.ENSURE_ROLES, dependsOn : resourceGroupCreateOperation.Id, desiredState : desiredState); ProvisioningQueueUtil.CreateChildAndAdd(queueParentItem, roleAssignmentUpdateOperation); }
CloudResourceOperation FindOperationToRetry(CloudResource resource) { CloudResourceOperation lastOperation = null; foreach (var currentOperation in resource.Operations.OrderByDescending(o => o.Created)) { if (CloudResourceOperationUtil.HasValidStateForRetry(currentOperation)) { lastOperation = currentOperation; } else if (currentOperation.Status == CloudResourceOperationState.DONE_SUCCESSFUL) { return(lastOperation); } } return(lastOperation); }
bool AllSandboxResourcesOkay(Sandbox sandbox) { if (sandbox.Resources == null) { throw new Exception("Missing include for Sandbox.Resources"); } foreach (var currentSandboxResource in CloudResourceUtil.GetSandboxControlledResources(sandbox.Resources)) { //If create operation failed if (!CloudResourceOperationUtil.HasSuccessfulCreateOperation(currentSandboxResource)) { return(false); } } return(true); }
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); } }
async Task <CloudResource> EnsureResourceGroupExists(Study study, Dataset dataset, ProvisioningQueueParentDto parentQueueItem) { try { var resourceGroupDb = GetResourceGroupForStudySpecificDataset(study); if (resourceGroupDb == null) { resourceGroupDb = await CreateResourceGroupForStudySpecificDatasetsInternalAsync(study, parentQueueItem); } else { if (String.IsNullOrWhiteSpace(resourceGroupDb.LastKnownProvisioningState)) { var resourceGroupCreateOperation = CloudResourceOperationUtil.GetCreateOperation(resourceGroupDb); //Old and failed, give it another try if (resourceGroupCreateOperation != null && resourceGroupCreateOperation.Created.AddMinutes(10) <= DateTime.UtcNow && (resourceGroupCreateOperation.Status == CloudResourceOperationState.FAILED || resourceGroupCreateOperation.Status == CloudResourceOperationState.ABORTED)) { ProvisioningQueueUtil.CreateChildAndAdd(parentQueueItem, resourceGroupDb); } } else { if (resourceGroupDb.LastKnownProvisioningState == CloudResourceProvisioningStates.SUCCEEDED || resourceGroupDb.LastKnownProvisioningState == CloudResourceProvisioningStates.CREATING) { return(resourceGroupDb); } } } return(resourceGroupDb); } catch (Exception ex) { throw new Exception($"Failed to locate or ensure that resource group exist for storage account", ex); } }