public async Task <CloudResource> CreateVmEntryAsync(int sandboxId, CloudResource resourceGroup, string region, Dictionary <string, string> tags, string vmName, int operationDependsOn, string configString) { try { await ValidateThatNameDoesNotExistThrowIfInvalid(vmName); var currentUser = await _userService.GetCurrentUserAsync(); var sessionId = _requestIdService.GetRequestId(); var resourceEntry = CloudResourceFactory.CreateSandboxResourceEntry( currentUser, sessionId, sandboxId, region, AzureResourceType.VirtualMachine, resourceGroup.Id, resourceName: vmName, tags: tags, configString: configString, dependsOn: operationDependsOn, resourceGroupName: resourceGroup.ResourceGroupName, sandboxControlled: false ); await SaveToDb(resourceEntry); return(resourceEntry); } catch (Exception ex) { throw new Exception($"Unable to create database resource entry for Virtual Machine for Sandbox {sandboxId}. See inner Exception for details", ex); } }
public static CloudResource Create(string region, string resourceType, string resourceGroup, string resourceName, string resourceId = null, string resourceKey = null, string purpose = null, bool sandboxControlled = false, string batchId = null, CloudResource parentResource = null, bool createOperationFinished = true, bool deleted = false, bool deleteSucceeded = false) { var cloudResource = CreateBasic(region, resourceType, resourceGroup, resourceName, resourceId, resourceKey, purpose, sandboxControlled, parentResource); cloudResource.Operations.Add(createOperationFinished ? CloudResourceOperationFactory.SucceededOperation("create" + resourceName, batchId: batchId) : CloudResourceOperationFactory.NewOperation("create" + resourceName, batchId: batchId)); if (deleted) { cloudResource.Operations.Add(deleteSucceeded ? CloudResourceOperationFactory.SucceededOperation("delete" + resourceName, operationType: CloudResourceOperationType.DELETE) : CloudResourceOperationFactory.NewOperation("delete" + resourceName, operationType: CloudResourceOperationType.DELETE)); } return(cloudResource); }
public static CloudResource CreateFailing(string region, string resourceType, string resourceGroup, string resourceName, string resourceId = null, string resourceKey = null, string purpose = null, bool sandboxControlled = false, string batchId = null, CloudResource parentResource = null, string statusOfFailedResource = CloudResourceOperationState.FAILED, int tryCount = CloudResourceConstants.RESOURCE_MAX_TRY_COUNT, int maxTryCount = CloudResourceConstants.RESOURCE_MAX_TRY_COUNT, bool deleted = false, bool deleteSucceeded = false ) { var cloudResource = CreateBasic(region, resourceType, resourceGroup, resourceName, resourceId, resourceKey, purpose, sandboxControlled, parentResource); cloudResource.LastKnownProvisioningState = null; cloudResource.Operations.Add(CloudResourceOperationFactory.FailedOperation("create" + resourceName, batchId: batchId, status: statusOfFailedResource, tryCount: tryCount, maxTryCount: maxTryCount)); if (deleted) { cloudResource.Operations.Add(deleteSucceeded ? CloudResourceOperationFactory.SucceededOperation("delete" + resourceName, operationType: CloudResourceOperationType.DELETE) : CloudResourceOperationFactory.NewOperation("delete" + resourceName, operationType: CloudResourceOperationType.DELETE)); } return(cloudResource); }
string ReScheduleResourceLogPrefix(CloudResource resource, string logText, CloudResourceOperation operation = null) { var logMessage = $"Re-schedule resource operation"; if (resource.StudyId.HasValue) { logMessage += $" | Study {resource.StudyId.Value}"; } if (resource.SandboxId.HasValue) { logMessage += $" | Sandbox {resource.SandboxId.Value}"; } logMessage += $" | Resource: {resource.Id}"; if (operation != null) { logMessage += $" | Operation {operation.Id} | {operation.Description}"; } logMessage += $" | {logText}"; return(logMessage); }
public static CloudResource CreateBasicResource(UserDto currentUser, string sessionId, string region, string resourceType, string resourceName, Dictionary <string, string> tags, string resourceGroupName = null ) { var tagsString = TagUtils.TagDictionaryToString(tags); var newResource = new CloudResource() { ResourceType = resourceType, Region = region, ResourceGroupName = resourceGroupName, ResourceName = resourceName, Tags = tagsString, ResourceKey = AzureResourceNameUtil.AZURE_RESOURCE_INITIAL_ID_OR_NAME, ResourceId = AzureResourceNameUtil.AZURE_RESOURCE_INITIAL_ID_OR_NAME, Operations = new List <CloudResourceOperation> { new CloudResourceOperation() { Status = CloudResourceOperationState.NEW, OperationType = CloudResourceOperationType.CREATE, CreatedBy = currentUser.UserName, CreatedBySessionId = sessionId, MaxTryCount = CloudResourceConstants.RESOURCE_MAX_TRY_COUNT } }, CreatedBy = currentUser.UserName }; return(newResource); }
public static string GetUserFriendlyName(CloudResource resource) { var resourceType = resource.ResourceType; switch (resourceType) { case AzureResourceType.ResourceGroup: return(AzureResourceTypeFriendlyName.ResourceGroup); case AzureResourceType.StorageAccount: return(AzureResourceTypeFriendlyName.StorageAccount); case AzureResourceType.VirtualNetwork: return(AzureResourceTypeFriendlyName.VirtualNetwork); case AzureResourceType.NetworkSecurityGroup: return(AzureResourceTypeFriendlyName.NetworkSecurityGroup); case AzureResourceType.Bastion: return(AzureResourceTypeFriendlyName.Bastion); case AzureResourceType.VirtualMachine: return(AzureResourceTypeFriendlyName.VirtualMachine); default: return("n/a"); } }
public IActionResult CreateMachine(CloudResource machine) { if (machine == null) { return(BadRequest(nameof(machine))); } try { machine.Lessor = _lessorRepository.GetItem(machine.Lessor.Id); var result = _machineService.Create(machine); if (result >= 1) { return(Ok()); } } catch (ArgumentNullException) { return(BadRequest(nameof(machine))); } catch (Exception) { return(StatusCode(500)); } return(StatusCode(500)); }
async Task EnsureOperationIsReadyForRetryAndEnqueue(CloudResource resource, CloudResourceOperation operationToRetry) { var queueParentItem = QueueItemFactory.CreateParent(operationToRetry.Id, $"{operationToRetry.Description} (re-scheduled)"); await EnsureOperationIsReadyForRetryAndAddToQueueItem(resource, operationToRetry, queueParentItem); await _provisioningQueueService.SendMessageAsync(queueParentItem); }
public void DecideWhatOperationToBaseStatusOn_withEmptyParameter_shouldThrow() { var cloudResource = new CloudResource() { }; var ex = Assert.Throws <ArgumentNullException>(() => ResourceStatusUtil.DecideWhatOperationToBaseStatusOn(cloudResource)); }
public static void ResourceAfterCreationAsserts(CloudResource cloudResource) { Assert.NotNull(cloudResource.ResourceId); Assert.NotNull(cloudResource.ResourceGroupName); Assert.NotNull(cloudResource.ResourceName); Assert.NotNull(cloudResource.CreatedBy); Assert.NotNull(cloudResource.LastKnownProvisioningState); }
static void SetOperationProperties(CloudResource resource, string description, string batchId = null, int operationDependsOn = 0) { var operation = resource.Operations.SingleOrDefault(); operation.Description = description; operation.BatchId = batchId; operation.DependsOnOperationId = operationDependsOn > 0 ? operationDependsOn : default(int?); }
// Checks Tags from Resource in Azure with information from db. // Makes sure they are equal. async Task CheckAndUpdateTags(CloudResource resource) { try { var serviceForResource = AzureResourceServiceResolver.GetServiceWithTags(_serviceProvider, resource.ResourceType); if (serviceForResource == null) { LogMonitoringError(resource, SepesEventId.MONITORING_NO_TAG_SERVICE, $"Could not resolve tag service for resource type: {resource.ResourceType}", critical: true); } else { // Read info used to create tags from resourceGroup in DB // These tags should be checked with the ones in Azure. var tagsFromDb = TagUtils.TagStringToDictionary(resource.Tags); var tagsFromAzure = await serviceForResource.GetTagsAsync(resource.ResourceGroupName, resource.ResourceName); if (tagsFromDb != null && tagsFromDb.Count > 0 && tagsFromAzure == null) { _logger.LogWarning(SepesEventId.MONITORING_NO_TAGS, $"No tags found for resource {resource.Id}!"); return; } // Check against tags from resource in Azure. // If different => update Tags and report difference to Study Owner? foreach (var tag in tagsFromAzure) { //Do not check CreatedByMachine-tag, as this will be different from original. if (!tag.Key.Equals("CreatedByMachine")) { if (!tagsFromDb.TryGetValue(tag.Key, out string dbValue)) { // If Tag exists in Azure but not in tags generated from DB-data, report. // Means that user has added tags themselves in Azure. LogMonitoringError(resource, SepesEventId.MONITORING_MANUALLY_ADDED_TAGS, $"Tag {tag.Key} : {tag.Value} has been added after resource creation!"); } else { // If Tag exists in Azure and Db but has different value in Azure if (!tag.Value.Equals(dbValue)) { LogMonitoringError(resource, SepesEventId.MONITORING_INCORRECT_TAGS, $"Tag {tag.Key} : {tag.Value} does not match value from Sepes : {dbValue}"); //Update tag in Azure to match DB-information. await serviceForResource.UpdateTagAsync(resource.ResourceGroupName, resource.ResourceName, new KeyValuePair <string, string>(tag.Key, dbValue)); _logger.LogWarning($"Updated Tag: {tag.Key} from value: {tag.Value} => {dbValue}"); } } } } } } catch (Exception ex) { LogMonitoringError(resource, SepesEventId.MONITORING_CRITICAL, $"Tag check/update failed", ex); } }
public static CloudResourceOperation GetCreateOperation(CloudResource resource) { if (resource.Operations == null) { throw new NullReferenceException($"Operation collection is null, might be missing Include"); } return(resource.Operations.Where(o => o.OperationType == CloudResourceOperationType.CREATE).SingleOrDefault()); }
public void StudySpecificDatasetResourceGroupName_ShouldContainStudyName(string expectedResult, string resourceType) { var resource = new CloudResource { ResourceType = resourceType }; var result = AzureResourceTypeUtil.GetUserFriendlyName(resource); Assert.Equal(expectedResult, result); }
public static bool HasSuccessfulCreateOperation(CloudResource resource) { var createOperation = GetCreateOperation(resource); if (createOperation == null) { return(false); } return(createOperation.Status == CloudResourceOperationState.DONE_SUCCESSFUL); }
public void MarkAsDeleted_ShouldMarkAsDeletedWithCorrectName() { var deletedBy = "John"; var itemToBeDeleted = new CloudResource { }; SoftDeleteUtil.MarkAsDeleted(itemToBeDeleted, deletedBy); Assert.Equal(itemToBeDeleted.DeletedBy, deletedBy); Assert.True(SoftDeleteUtil.IsMarkedAsDeleted(itemToBeDeleted)); }
public void MarkAsDeleted_ShouldMarkAsDeletedWithCorrectName5() { var deletedBy = new UserDto { }; var itemToBeDeleted = new CloudResource { }; var ex = Assert.Throws <ArgumentNullException>(() => SoftDeleteUtil.MarkAsDeleted(null, "")); Assert.Contains("Item to delete was null", ex.Message); Assert.False(SoftDeleteUtil.IsMarkedAsDeleted(itemToBeDeleted)); }
public static bool InternetIsOpen(CloudResource vmResource) { var relevantRule = GetInternetRule(vmResource); if (relevantRule == null) { return(false); } return(relevantRule.Action == RuleAction.Allow); }
public static string GetOsName(CloudResource resource) { var vmSettings = CloudResourceConfigStringSerializer.VmSettings(resource.ConfigString); if (vmSettings != null) { return(vmSettings.OperatingSystem); } return(null); }
async Task ReadAllAndAssertExpectSuccess(CloudResource vm) { await GenericReader.ReadAndAssertExpectSuccess <StudyDetailsDto>(_restHelper, GenericReader.StudyUrl(vm.Sandbox.StudyId)); await GenericReader.ReadAndAssertExpectSuccess <SandboxDetails>(_restHelper, GenericReader.SandboxUrl(vm.Sandbox.Id)); await GenericReader.ReadAndAssertExpectSuccess <List <VmDto> >(_restHelper, GenericReader.SandboxVirtualMachines(vm.Sandbox.Id)); await GenericReader.ReadAndAssertExpectSuccess <List <SandboxResourceLight> >(_restHelper, GenericReader.SandboxResources(vm.Sandbox.Id)); await GenericReader.ReadAndAssertExpectSuccess <VmExtendedDto>(_restHelper, GenericReader.VirtualMachineExtendedInfo(vm.Id)); //Todo: Add this test, but remember to mock out azure vm service }
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); }
async Task ReadAllAndAssertExpectForbidden(CloudResource vm) { await GenericReader.ReadAndAssertExpectForbidden(_restHelper, GenericReader.StudyUrl(vm.Sandbox.StudyId)); await GenericReader.ReadAndAssertExpectForbidden(_restHelper, GenericReader.SandboxUrl(vm.Sandbox.Id)); await GenericReader.ReadAndAssertExpectForbidden(_restHelper, GenericReader.SandboxVirtualMachines(vm.Sandbox.Id)); await GenericReader.ReadAndAssertExpectForbidden(_restHelper, GenericReader.SandboxResources(vm.Sandbox.Id)); await GenericReader.ReadAndAssertExpectForbidden(_restHelper, GenericReader.VirtualMachineExtendedInfo(vm.Id)); //Todo: Add this test, but remember to mock out azure vm service }
public static void StudyDatasetResourceGroupBeforeProvisioningAssert(CloudResource cloudResource) { StudyDatasetResourceGroupBasicAsserts(cloudResource); Assert.Null(cloudResource.LastKnownProvisioningState); foreach (var curOp in cloudResource.Operations) { Assert.Equal(CloudResourceOperationState.NEW, curOp.Status); Assert.NotNull(curOp.CreatedBy); Assert.Null(curOp.CarriedOutBySessionId); } }
async Task EnsureOperationIsReadyForRetryAndAddToQueueItem(CloudResource resource, CloudResourceOperation operationToRetry, ProvisioningQueueParentDto queueParentItem) { await EnsureOperationIsReadyForRetry(resource, operationToRetry); _logger.LogInformation(ReScheduleResourceLogPrefix(resource, $"Re-queing item", operationToRetry)); queueParentItem.Children.Add(new ProvisioningQueueChildDto() { ResourceOperationId = operationToRetry.Id }); _logger.LogInformation(ReScheduleResourceLogPrefix(resource, $"Item re-queued", operationToRetry)); }
public void DecideWhatOperationToBaseStatusOn_withEmptyList_shouldThrow() { var cloudResourceOperation = new List <CloudResourceOperation>() { }; var cloudResource = new CloudResource() { Operations = cloudResourceOperation }; var result = ResourceStatusUtil.DecideWhatOperationToBaseStatusOn(cloudResource); Assert.Null(result); }
//Fetches the provisioning state for the resource and write this on our record of the resource async Task GetAndLogProvisioningState(CloudResource resource) { try { var provisioningState = await GetProvisioningState(resource); await _cloudResourceUpdateService.UpdateProvisioningState(resource.Id, provisioningState); } catch (Exception ex) { _logger.LogCritical(ex, $"Checking provisioning state failed for resource id: {resource.Id}"); } }
async Task CreateUpdateOperationAndAddQueueItem(CloudResource vm, string description) { //If un-started update allready exist, no need to create update op? if (await _sandboxResourceOperationReadService.HasUnstartedCreateOrUpdateOperation(vm.Id)) { _logger.LogWarning($"Updating VM {vm.Id}: There is allready an unstarted VM Create or Update operation. Not creating additional"); } else { var vmUpdateOperation = await _sandboxResourceOperationCreateService.CreateUpdateOperationAsync(vm.Id); await _provisioningQueueService.CreateItemAndEnqueue(vmUpdateOperation); } }
public static CloudResource GetSibilingResource(CloudResource resource, string resourceType) { if (resource.Sandbox == null) { throw new NullReferenceException($"Cannot navigate to Sandbox for resource {resource.Id}"); } if (resource.Sandbox.Resources == null) { throw new NullReferenceException($"Cannot navigate to Sandbox sibling resources for resource {resource.Id}"); } return(resource.Sandbox.Resources.FirstOrDefault(r => r.ResourceType == resourceType)); }
public static void StudyDatasetResourceGroupAfterProvisioningAssert(CloudResource cloudResource) { StudyDatasetResourceGroupBasicAsserts(cloudResource); ResourceAfterCreationAsserts(cloudResource); Assert.Equal(CloudResourceProvisioningStates.SUCCEEDED, cloudResource.LastKnownProvisioningState); foreach (var curOp in cloudResource.Operations) { Assert.Equal(CloudResourceOperationState.DONE_SUCCESSFUL, curOp.Status); Assert.NotNull(curOp.CarriedOutBySessionId); } }
async Task <CloudResourceOperation> CheckAnyIfOperationsToWaitFor(CloudResource resource, UserDto currentUser) { bool mostRecentOperation = true; foreach (var curOperation in resource.Operations.OrderByDescending(o => o.Created)) { if (curOperation.OperationType == CloudResourceOperationType.DELETE) { throw new Exception($"Error when adding operation to resource {resource.Id}, resource allready marked for deletion"); } if (mostRecentOperation && curOperation.Status == CloudResourceOperationState.DONE_SUCCESSFUL) { return(null); } if (curOperation.OperationType == CloudResourceOperationType.UPDATE || curOperation.OperationType == CloudResourceOperationType.ENSURE_ROLES || curOperation.OperationType == CloudResourceOperationType.ENSURE_FIREWALL_RULES || curOperation.OperationType == CloudResourceOperationType.ENSURE_CORS_RULES) { if (curOperation.Status != CloudResourceOperationState.DONE_SUCCESSFUL && curOperation.Status != CloudResourceOperationState.ABORTED && curOperation.Status != CloudResourceOperationState.ABANDONED) { //If very old, set to aborted and continue the search if (curOperation.Updated.AddMinutes(2) < DateTime.UtcNow) { curOperation.Description += " (appeared to be failing)"; curOperation.Status = CloudResourceOperationState.ABANDONED; curOperation.Updated = DateTime.UtcNow; curOperation.UpdatedBy = currentUser.UserName; await _db.SaveChangesAsync(); } else { return(curOperation); } } } if (curOperation.OperationType == CloudResourceOperationType.CREATE) { if (curOperation.Status != CloudResourceOperationState.DONE_SUCCESSFUL && curOperation.Status != CloudResourceOperationState.ABORTED && curOperation.Status != CloudResourceOperationState.ABANDONED) { return(curOperation); } } mostRecentOperation = false; } return(null); }
public static CloudResource CreateCloudResource(string resourceProviderNamespace) { CloudResource cloudResource = new CloudResource(); cloudResource.ResourceProviderNamespace = resourceProviderNamespace; return cloudResource; }