async Task <string> CreateVmSettingsString(string region, int vmId, int studyId, int sandboxId, VirtualMachineCreateDto userInput) { var vmSettings = _mapper.Map <VmSettingsDto>(userInput); var availableOs = await _virtualMachineOperatingSystemService.AvailableOperatingSystems(region); vmSettings.OperatingSystemCategory = AzureVmUtil.GetOsCategory(availableOs, vmSettings.OperatingSystem); vmSettings.Password = await StoreNewVmPasswordAsKeyVaultSecretAndReturnReference(studyId, sandboxId, vmSettings.Password); var diagStorageResource = await CloudResourceQueries.GetDiagStorageAccountEntry(_db, sandboxId); vmSettings.DiagnosticStorageAccountName = diagStorageResource.ResourceName; var networkResource = await CloudResourceQueries.GetNetworkEntry(_db, sandboxId); vmSettings.NetworkName = networkResource.ResourceName; var networkSetting = CloudResourceConfigStringSerializer.NetworkSettings(networkResource.ConfigString); vmSettings.SubnetName = networkSetting.SandboxSubnetName; vmSettings.Rules = VmRuleUtils.CreateInitialVmRules(vmId); return(CloudResourceConfigStringSerializer.Serialize(vmSettings)); }
public async Task <ResourceProvisioningResult> EnsureCreated(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default) { _logger.LogInformation($"Creating virtual network {parameters.Name} in resource Group: {parameters.ResourceGroupName}"); var networkSettings = CloudResourceConfigStringSerializer.NetworkSettings(parameters.ConfigurationString); var virtualNetwork = await GetResourceInternalAsync(parameters.ResourceGroupName, parameters.Name, false); if (virtualNetwork == null) { virtualNetwork = await CreateInternalAsync(GetRegionFromString(parameters.Region), parameters.ResourceGroupName, parameters.Name, networkSettings.SandboxSubnetName, parameters.Tags, cancellationToken); } if (!parameters.TryGetSharedVariable(AzureCrudSharedVariable.NETWORK_SECURITY_GROUP_NAME, out string networkSecurityGroupName)) { throw new ArgumentException("AzureVirtualNetworkService: Missing network security group name from input"); } await EnsureNetworkSecurityGroupIsAddedToSubnet(virtualNetwork, networkSecurityGroupName, networkSettings.SandboxSubnetName); _logger.LogInformation($"Done creating virtual network {parameters.Name}"); var crudResult = CreateResult(virtualNetwork); return(crudResult); }
public async Task Handle( CloudResourceOperationDto operation, IHasCorsRules corsRuleService) { try { var cancellation = new CancellationTokenSource(); if (string.IsNullOrWhiteSpace(operation.DesiredState)) { throw new NullReferenceException($"Desired state empty on operation {operation.Id}: {operation.Description}"); } var rulesFromOperationState = CloudResourceConfigStringSerializer.DesiredCorsRules(operation.DesiredState); var setRulesTask = corsRuleService.SetCorsRules(operation.Resource.ResourceGroupName, operation.Resource.ResourceName, rulesFromOperationState, cancellation.Token); while (!setRulesTask.IsCompleted) { operation = await _cloudResourceOperationUpdateService.TouchAsync(operation.Id); if (await _cloudResourceReadService.ResourceIsDeleted(operation.Resource.Id) || operation.Status == CloudResourceOperationState.ABORTED || operation.Status == CloudResourceOperationState.ABANDONED) { _provisioningLogService.OperationWarning(operation, $"Operation aborted, cors rule assignment will be aborted"); cancellation.Cancel(); break; } Thread.Sleep((int)TimeSpan.FromSeconds(3).TotalMilliseconds); } if (setRulesTask.IsCompletedSuccessfully) { } else { if (setRulesTask.Exception == null) { throw new Exception("cors rule assignment task failed"); } else { throw setRulesTask.Exception; } } } catch (Exception ex) { if (ex.InnerException != null && ex.InnerException.Message.Contains("A task was canceled")) { throw new ProvisioningException($"Resource provisioning (Ensure cors rules) aborted.", logAsWarning: true, innerException: ex.InnerException); } else { throw new ProvisioningException($"Resource provisioning (Ensure cors rules) failed.", CloudResourceOperationState.FAILED, postponeQueueItemFor: 10, innerException: ex); } } }
public async Task <List <VmRuleDto> > GetRules(int vmId, CancellationToken cancellationToken = default) { var vm = await GetVirtualMachineResourceEntry(vmId, UserOperation.Study_Read); //Get config string var vmSettings = CloudResourceConfigStringSerializer.VmSettings(vm.ConfigString); return(vmSettings.Rules != null ? vmSettings.Rules : new List <VmRuleDto>()); }
public async Task Handle(CloudResourceOperationDto operation) { try { var cancellation = new CancellationTokenSource(); if (string.IsNullOrWhiteSpace(operation.DesiredState)) { throw new NullReferenceException($"Desired state empty on operation {operation.Id}: {operation.Description}"); } var operationStateDeserialized = CloudResourceConfigStringSerializer.DesiredRoleAssignment(operation.DesiredState); var study = await _studyModelService.GetWithParticipantsAndUsersNoAccessCheck(operationStateDeserialized.StudyId); var currentRoleAssignmentTask = SetRoleAssignments(operation, study, cancellation.Token); while (!currentRoleAssignmentTask.IsCompleted) { operation = await _cloudResourceOperationUpdateService.TouchAsync(operation.Id); if (await _cloudResourceReadService.ResourceIsDeleted(operation.Resource.Id) || operation.Status == CloudResourceOperationState.ABORTED || operation.Status == CloudResourceOperationState.ABANDONED) { _provisioningLogService.OperationWarning(operation, $"Operation aborted, role assignment will be aborted", eventId: _roleAssignmentEventId); cancellation.Cancel(); break; } Thread.Sleep((int)TimeSpan.FromSeconds(3).TotalMilliseconds); } if (!currentRoleAssignmentTask.IsCompletedSuccessfully) { if (currentRoleAssignmentTask.Exception == null) { throw new Exception("Role assignment task failed"); } else { throw currentRoleAssignmentTask.Exception; } } } catch (Exception ex) { if (ex.InnerException != null && ex.InnerException.Message.Contains("A task was canceled")) { throw new ProvisioningException($"Resource provisioning (Ensure role assignments) aborted.", logAsWarning: true, innerException: ex.InnerException); } else { throw new ProvisioningException($"Resource provisioning (Ensure role assignments) failed.", CloudResourceOperationState.FAILED, postponeQueueItemFor: 10, innerException: ex); } } }
public static string GetOsName(CloudResource resource) { var vmSettings = CloudResourceConfigStringSerializer.VmSettings(resource.ConfigString); if (vmSettings != null) { return(vmSettings.OperatingSystem); } return(null); }
public static string TranslateAllowedIpsToOperationDesiredState(List <DatasetFirewallRule> datasetFirewallRules) { if (datasetFirewallRules.Count == 0) { return(null); } var translated = TranslateAllowedIpsToGenericFirewallRule(datasetFirewallRules); return(CloudResourceConfigStringSerializer.Serialize(translated)); }
async Task ScheduleCreationOfSandboxResourceGroupRoleAssignments(SandboxResourceCreationAndSchedulingDto dto, ProvisioningQueueParentDto queueParentItem) { var desiredState = CloudResourceConfigStringSerializer.Serialize(new CloudResourceOperationStateForRoleUpdate(dto.StudyId)); var resourceGroupCreateOperation = dto.ResourceGroup.Operations.FirstOrDefault().Id; var updateOpId = await _cloudResourceOperationCreateService.CreateUpdateOperationAsync(dto.ResourceGroup.Id, CloudResourceOperationType.ENSURE_ROLES, dependsOn : resourceGroupCreateOperation, desiredState : desiredState); queueParentItem.Children.Add(new ProvisioningQueueChildDto() { ResourceOperationId = updateOpId.Id }); }
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); }
protected async Task CreateRoleUpdateOperationsAsync(int studyId) { var resourcesToUpdate = await _cloudResourceReadService.GetDatasetResourceGroupIdsForStudy(studyId); resourcesToUpdate.AddRange(await _cloudResourceReadService.GetSandboxResourceGroupIdsForStudy(studyId)); foreach (var currentResourceId in resourcesToUpdate) { var desiredState = CloudResourceConfigStringSerializer.Serialize(new CloudResourceOperationStateForRoleUpdate(studyId)); var updateOperation = await _cloudResourceOperationCreateService.CreateUpdateOperationAsync(currentResourceId, CloudResourceOperationType.ENSURE_ROLES, desiredState : desiredState); await _provisioningQueueService.CreateItemAndEnqueue(updateOperation); } }
public async Task <ResourceProvisioningResult> Update(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default) { _logger.LogInformation($"Updating VM {parameters.Name}"); var vm = await GetInternalAsync(parameters.ResourceGroupName, parameters.Name); var primaryNic = await _azure.NetworkInterfaces.GetByIdAsync(vm.PrimaryNetworkInterfaceId, cancellationToken); var vmSettings = CloudResourceConfigStringSerializer.VmSettings(parameters.ConfigurationString); await UpdateVmRules(parameters, vmSettings, primaryNic.PrimaryPrivateIP, cancellationToken); var result = CreateCRUDResult(vm); return(result); }
static string CreateVmSettingsString(string size = VirtualMachineConstants.SIZE, string osCategory = "windows", string os = "win2019datacenter") { var vmSettings = new VmSettingsDto() { DiagnosticStorageAccountName = "diagstorageaccountname", NetworkName = "networkName", SubnetName = "subnetname", Size = size, Rules = VmRuleUtils.CreateInitialVmRules(1), OperatingSystemCategory = osCategory, OperatingSystem = os, Username = VirtualMachineConstants.USERNAME, Password = "******", }; return(CloudResourceConfigStringSerializer.Serialize(vmSettings)); }
async Task ScheduleCreationOfVirtualNetwork(SandboxResourceCreationAndSchedulingDto dto, ProvisioningQueueParentDto queueParentItem) { var networkName = AzureResourceNameUtil.VNet(dto.StudyName, dto.SandboxName); var sandboxSubnetName = AzureResourceNameUtil.SubNet(dto.StudyName, dto.SandboxName); var networkSettings = new NetworkSettingsDto() { SandboxSubnetName = sandboxSubnetName }; var networkSettingsString = CloudResourceConfigStringSerializer.Serialize(networkSettings); var nsgCreateOperation = dto.NetworkSecurityGroup.Operations.FirstOrDefault().Id; var resourceEntry = await CreateResourceEntryAndAddToQueue(dto, queueParentItem, AzureResourceType.VirtualNetwork, resourceName : networkName, configString : networkSettingsString, dependsOn : nsgCreateOperation); dto.Network = resourceEntry; }
async Task DeleteInternalAsync(string resourceGroupName, string virtualMachineName, string networkSecurityGroupName, string configString) { var vm = await GetInternalAsync(resourceGroupName, virtualMachineName, false); if (vm == null) { _logger.LogWarning($"Virtual Machine {virtualMachineName} appears to be deleted allready"); return; } //Ensure resource is is managed by this instance EnsureResourceIsManagedByThisIEnvironmentThrowIfNot(resourceGroupName, vm.Tags); await _azure.VirtualMachines.DeleteByResourceGroupAsync(resourceGroupName, virtualMachineName); //Delete all the disks await DeleteDiskById(vm.OSDiskId); foreach (var curNic in vm.NetworkInterfaceIds) { await DeleteNic(curNic); } foreach (var curDiskKvp in vm.DataDisks) { await DeleteDiskById(curDiskKvp.Value.Id); } //Delete VM rules var vmSettings = CloudResourceConfigStringSerializer.VmSettings(configString); foreach (var curRule in vmSettings.Rules) { try { await _azureNetworkSecurityGroupRuleService.DeleteRule(resourceGroupName, networkSecurityGroupName, curRule.Name); } catch (Exception) { _logger.LogWarning($"Delete VM: Failed to delete NSG rule {curRule.Name} for vm {virtualMachineName}. Assuming it has allready been deleted"); } } }
public async Task <VmRuleDto> GetRuleById(int vmId, string ruleId, CancellationToken cancellationToken = default) { var vm = await GetVirtualMachineResourceEntry(vmId, UserOperation.Study_Read); //Get config string var vmSettings = CloudResourceConfigStringSerializer.VmSettings(vm.ConfigString); if (vmSettings.Rules != null) { foreach (var curExistingRule in vmSettings.Rules) { if (curExistingRule.Name == ruleId) { return(curExistingRule); } } } throw new NotFoundException($"Rule with id {ruleId} does not exist"); }
public async Task <VmRuleDto> GetInternetRule(int vmId) { var vm = await GetVirtualMachineResourceEntry(vmId, UserOperation.Study_Crud_Sandbox); //Get config string var vmSettings = CloudResourceConfigStringSerializer.VmSettings(vm.ConfigString); if (vmSettings.Rules != null) { foreach (var curRule in vmSettings.Rules) { if (curRule.Direction == RuleDirection.Outbound) { if (curRule.Name.Contains(AzureVmConstants.RulePresets.OPEN_CLOSE_INTERNET)) { return(curRule); } } } } return(null); }
public static VmRuleDto GetInternetRule(CloudResource vmResource) { if (!String.IsNullOrWhiteSpace(vmResource.ConfigString)) { var vmSettings = CloudResourceConfigStringSerializer.VmSettings(vmResource.ConfigString); if (vmSettings != null && vmSettings.Rules != null) { foreach (var curRule in vmSettings.Rules) { if (curRule.Direction == RuleDirection.Outbound) { if (curRule.Name.Contains(AzureVmConstants.RulePresets.OPEN_CLOSE_INTERNET)) { return(curRule); } } } } } return(null); }
public async Task <ResourceProvisioningResult> EnsureCreated(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default) { _logger.LogInformation($"Ensuring VM exists: {parameters.Name} in resource Group: {parameters.ResourceGroupName}"); var vmSettings = CloudResourceConfigStringSerializer.VmSettings(parameters.ConfigurationString); var virtualMachine = await GetInternalAsync(parameters.ResourceGroupName, parameters.Name, false); if (virtualMachine == null) { _logger.LogInformation($"VM {parameters.Name} did not exist in resource Group: {parameters.ResourceGroupName}, creating!"); var passwordReference = vmSettings.Password; string password = await GetPasswordFromKeyVault(passwordReference); string vmSize = vmSettings.Size; virtualMachine = await CreateInternalAsync(GetRegionFromString(parameters.Region), parameters.ResourceGroupName, parameters.Name, vmSettings.NetworkName, vmSettings.SubnetName, vmSettings.Username, password, vmSize, vmSettings.OperatingSystem, vmSettings.OperatingSystemCategory, parameters.Tags, vmSettings.DiagnosticStorageAccountName, cancellationToken); await DeletePasswordFromKeyVault(passwordReference); if (vmSettings.DataDisks != null && vmSettings.DataDisks.Count > 0) { foreach (var curDisk in vmSettings.DataDisks) { var sizeAsInt = Convert.ToInt32(curDisk); if (sizeAsInt == 0) { throw new Exception($"Illegal data disk size: {curDisk}"); } await ApplyVmDataDisksInternalAsync(parameters.ResourceGroupName, parameters.Name, sizeAsInt, parameters.Tags); } } _logger.LogInformation($"Done creating Virtual Machine for sandbox with Id: {parameters.SandboxId}! Id: {virtualMachine.Id}"); } else { //Validate data disks if (vmSettings.DataDisks != null && vmSettings.DataDisks.Count > 0) { if (virtualMachine.DataDisks.Count != vmSettings.DataDisks.Count) { throw new Exception($"Data disk(s) not created properly. Expected count of {vmSettings.DataDisks}, saw {vmSettings.DataDisks.Count} on VM"); } } } var primaryNic = await _azure.NetworkInterfaces.GetByIdAsync(virtualMachine.PrimaryNetworkInterfaceId, cancellationToken); //Add tags to NIC await primaryNic.UpdateTags().WithTags(parameters.Tags).ApplyTagsAsync(); await UpdateVmRules(parameters, vmSettings, primaryNic.PrimaryPrivateIP, cancellationToken); var result = CreateCRUDResult(virtualMachine); return(result); }
public async Task <List <VmRuleDto> > SetRules(int vmId, List <VmRuleDto> updatedRuleSet, CancellationToken cancellationToken = default) { var vm = await GetVirtualMachineResourceEntry(vmId, UserOperation.Study_Crud_Sandbox); //Get config string var vmSettings = CloudResourceConfigStringSerializer.VmSettings(vm.ConfigString); await ValidateRuleUpdateInputThrowIfNot(vm, vmSettings.Rules, updatedRuleSet); bool saveAfterwards = false; if (updatedRuleSet == null || updatedRuleSet != null && updatedRuleSet.Count == 0) //Easy, all rules should be deleted { vmSettings.Rules = null; saveAfterwards = true; } else { var newRules = updatedRuleSet.Where(r => String.IsNullOrWhiteSpace(r.Name)).ToList(); var rulesThatShouldExistAllready = updatedRuleSet.Where(r => !String.IsNullOrWhiteSpace(r.Name)).ToList(); //Check that the new rules does not have a duplicate in existing rules foreach (var curNew in newRules) { ThrowIfRuleExists(rulesThatShouldExistAllready, curNew); } foreach (var curRule in updatedRuleSet) { if (curRule.Direction == RuleDirection.Inbound) { if (curRule.Action == RuleAction.Deny) { throw new ArgumentException("Inbound rules can only have Action: Allow"); } if (String.IsNullOrWhiteSpace(curRule.Name)) { curRule.Name = AzureResourceNameUtil.NsgRuleNameForVm(vmId); //curRule.Priority = AzureVmUtil.GetNextVmRulePriority(updatedRuleSet, curRule.Direction); } } else { if (String.IsNullOrWhiteSpace(curRule.Name) || !curRule.Name.Contains(AzureVmConstants.RulePresets.OPEN_CLOSE_INTERNET)) { throw new ArgumentException("Custom outbound rules are not allowed"); } } } vmSettings.Rules = updatedRuleSet; saveAfterwards = true; } if (saveAfterwards) { vm.ConfigString = CloudResourceConfigStringSerializer.Serialize(vmSettings); await _db.SaveChangesAsync(); await CreateUpdateOperationAndAddQueueItem(vm, "Updated rules"); } return(updatedRuleSet != null ? updatedRuleSet : new List <VmRuleDto>()); }