Пример #1
0
        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);
        }
Пример #2
0
        public async Task <ResourceProvisioningResult> EnsureCreated(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default)
        {
            _logger.LogInformation($"Creating Bastion for sandbox with Name: {parameters.SandboxName}! Resource Group: {parameters.ResourceGroupName}");

            if (!parameters.TryGetSharedVariable(AzureCrudSharedVariable.BASTION_SUBNET_ID, out string subnetId))
            {
                throw new ArgumentException("AzureBastionService: Missing Bastion subnet ID from input");
            }

            var bastionHost = await GetResourceInternalAsync(parameters.ResourceGroupName, parameters.Name, false);

            if (bastionHost == null)
            {
                bastionHost = await CreateInternal(GetRegionFromString(parameters.Region), parameters.ResourceGroupName, parameters.Name, subnetId, parameters.Tags, cancellationToken);

                _logger.LogInformation($"Done creating Bastion for sandbox with Id: {parameters.SandboxName}! Bastion Id: {bastionHost.Id}");
            }
            else
            {
                _logger.LogInformation($"Ensure bastion exist for Sandbox: {parameters.SandboxName}! Bastion allready existed. Bastion Id: {bastionHost.Id}");
            }

            var result = CreateResult(bastionHost);

            return(result);
        }
Пример #3
0
        public async Task <ResourceProvisioningResult> Handle(
            CloudResourceOperationDto operation,
            ResourceProvisioningParameters currentCrudInput,
            IPerformResourceProvisioning provisioningService
            )
        {
            try
            {
                _provisioningLogService.OperationInformation(operation, $"Deleting {operation.Resource.ResourceType}");

                var deleteTask = provisioningService.EnsureDeleted(currentCrudInput);

                while (!deleteTask.IsCompleted)
                {
                    operation = await _cloudResourceOperationUpdateService.TouchAsync(operation.Id);

                    Thread.Sleep((int)TimeSpan.FromSeconds(3).TotalMilliseconds);
                }

                _provisioningLogService.OperationInformation(operation, $"Delete Operation finished");

                return(deleteTask.Result);
            }
            catch (Exception ex)
            {
                throw new ProvisioningException($"Provisioning (Delete) failed", innerException: ex);
            }
        }
Пример #4
0
        public async Task <ResourceProvisioningResult> GetSharedVariables(ResourceProvisioningParameters parameters)
        {
            var network = await GetResourceInternalAsync(parameters.ResourceGroupName, parameters.Name);

            var crudResult = CreateResult(network);

            return(crudResult);
        }
        public async Task <ResourceProvisioningResult> EnsureDeleted(ResourceProvisioningParameters parameters)
        {
            await DeleteInternalAsync(parameters.ResourceGroupName, parameters.Name, parameters.NetworkSecurityGroupName, parameters.ConfigurationString);

            var provisioningState = await GetProvisioningState(parameters.ResourceGroupName, parameters.Name);

            return(ResourceProvisioningResultUtil.CreateFromProvisioningState(provisioningState));
        }
        public async Task <ResourceProvisioningResult> GetSharedVariables(ResourceProvisioningParameters parameters)
        {
            var vm = await GetInternalAsync(parameters.ResourceGroupName, parameters.Name);

            var result = CreateCRUDResult(vm);

            return(result);
        }
        public async Task <ResourceProvisioningResult> GetSharedVariables(ResourceProvisioningParameters parameters)
        {
            var diagnosticStorageAccount = await GetResourceAsync(parameters.ResourceGroupName, parameters.Name);

            var result = CreateResult(diagnosticStorageAccount);

            return(result);
        }
Пример #8
0
        public async Task <ResourceProvisioningResult> GetSharedVariables(ResourceProvisioningParameters parameters)
        {
            var resourceGroup = await GetResourceGroupAsync(parameters.Name);

            var crudResult = ResourceProvisioningResultUtil.CreateFromIResource(resourceGroup);

            crudResult.CurrentProvisioningState = resourceGroup.ProvisioningState.ToString();
            return(crudResult);
        }
Пример #9
0
        public async Task <ResourceProvisioningResult> EnsureDeleted(ResourceProvisioningParameters parameters)
        {
            await DeleteInternal(parameters.ResourceGroupName, parameters.Name);

            var provisioningState = await GetProvisioningState(parameters.ResourceGroupName, parameters.Name);

            var crudResult = ResourceProvisioningResultUtil.CreateFromProvisioningState(provisioningState);

            return(crudResult);
        }
        async Task <int> FindNextPriority(ResourceProvisioningParameters parameters, Dictionary <string, NsgRuleDto> existingRulesForVm, int startingAt, int increaseBy, int highestAllowed, string direction, CancellationToken cancellationToken = default)
        {
            var existingRuleForSameVmWithHighestPriority = existingRulesForVm.Values.Where(r => r.Direction == direction).OrderByDescending(r => r.Priority).FirstOrDefault();

            if (existingRuleForSameVmWithHighestPriority != null)
            {
                startingAt = existingRuleForSameVmWithHighestPriority.Priority += increaseBy;
            }

            return(await FindNextPriority(parameters, startingAt, increaseBy, highestAllowed, direction, cancellationToken));
        }
        public Task <ResourceProvisioningResult> EnsureCreated(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default)
        {
            if (_resourceType == AzureResourceType.ResourceGroup)
            {
                Log($"Creating resource group: {parameters.ResourceGroupName}");
            }
            else
            {
                Log($"Creating resource {parameters.Name} in resource group {parameters.ResourceGroupName}");
            }

            throw new System.NotImplementedException();
        }
        public Task <ResourceProvisioningResult> Delete(ResourceProvisioningParameters parameters)
        {
            if (_resourceType == AzureResourceType.ResourceGroup)
            {
                Log($"Deleting resource group: {parameters.ResourceGroupName}");
            }
            else
            {
                Log($"Updating resource {parameters.Name} in resource group {parameters.ResourceGroupName}");
            }

            throw new System.NotImplementedException();
        }
        public Task <ResourceProvisioningResult> GetSharedVariables(ResourceProvisioningParameters parameters)
        {
            if (_resourceType == AzureResourceType.ResourceGroup)
            {
                Log($"Returning shared variables for resource group: {parameters.ResourceGroupName}");
            }
            else
            {
                Log($"Returning shared variables for resource {parameters.Name} in resource group {parameters.ResourceGroupName}");
            }

            throw new System.NotImplementedException();
        }
Пример #14
0
        protected string GetSharedVariableThrowIfNotFoundOrEmpty(ResourceProvisioningParameters parameters, string variableName, string descriptionForErrorMessage)
        {
            if (!parameters.TryGetSharedVariable(variableName, out string sharedVariableValue))
            {
                throw new ArgumentException($"{this.GetType().Name}: Missing {descriptionForErrorMessage} from input");
            }
            else if (String.IsNullOrWhiteSpace(sharedVariableValue))
            {
                throw new ArgumentException($"{this.GetType().Name}: Empty {descriptionForErrorMessage} from input");
            }

            return(sharedVariableValue);
        }
        public async Task <ResourceProvisioningResult> EnsureDeleted(ResourceProvisioningParameters parameters)
        {
            try
            {
                await Delete(parameters.ResourceGroupName, parameters.Name);

                var provisioningState = await GetProvisioningState(parameters.ResourceGroupName, parameters.Name);

                return(ResourceProvisioningResultUtil.CreateFromProvisioningState(provisioningState));
            }
            catch (Exception)
            {
                throw;
            }
        }
        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);
        }
Пример #17
0
        public async Task <ResourceProvisioningResult> Handle(
            CloudResourceOperationDto operation,
            ResourceProvisioningParameters currentCrudInput,
            IPerformResourceProvisioning provisioningService
            )
        {
            try
            {
                var cancellation          = new CancellationTokenSource();
                var currentCrudResultTask = CreateProvisioningResultTask(operation, currentCrudInput, provisioningService, cancellation);

                while (!currentCrudResultTask.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, provisioning will be aborted");
                        cancellation.Cancel();
                        break;
                    }

                    Thread.Sleep((int)TimeSpan.FromSeconds(3).TotalMilliseconds);
                }

                var provisioningResult = currentCrudResultTask.Result;

                if (operation.OperationType == CloudResourceOperationType.CREATE)
                {
                    _provisioningLogService.OperationInformation(operation, $"Storing resource Id and Name");
                    await _cloudResourceUpdateService.UpdateResourceIdAndName(operation.Resource.Id, provisioningResult.IdInTargetSystem, provisioningResult.NameInTargetSystem);
                }

                return(provisioningResult);
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null && ex.InnerException.Message.Contains("A task was canceled"))
                {
                    throw new ProvisioningException($"Resource provisioning (Create/update) aborted.", logAsWarning: true, innerException: ex.InnerException);
                }
                else
                {
                    throw new ProvisioningException($"Resource provisioning (Create/update) failed.", CloudResourceOperationState.FAILED, postponeQueueItemFor: 10, innerException: ex);
                }
            }
        }
        async Task <int> FindNextPriority(ResourceProvisioningParameters parameters, int startingAt, int increaseBy, int highestAllowed, string direction, CancellationToken cancellationToken = default)
        {
            var allExistingRulesInNsg = await _azureNetworkSecurityGroupRuleService.GetNsgRulesForDirection(parameters.ResourceGroupName, parameters.NetworkSecurityGroupName, direction, cancellationToken);

            var relevantExistingRulesInNsg = allExistingRulesInNsg.Where(r => r.Value.Priority >= startingAt && r.Value.Priority <= highestAllowed).OrderBy(r => r.Value.Priority);

            if (relevantExistingRulesInNsg.Count() == 0)
            {
                return(startingAt);
            }

            var curPriority = startingAt;

            while (curPriority <= highestAllowed)
            {
                bool collision = false;

                foreach (var curExisting in relevantExistingRulesInNsg)
                {
                    if (curExisting.Value == null)
                    {
                        break;
                    }
                    if (curPriority > curExisting.Value.Priority)
                    {
                        continue;
                    }
                    else if ((curExisting.Value.Priority - curPriority) < 10)
                    {
                        collision = true;
                        break;
                    }
                }

                if (collision)
                {
                    curPriority += increaseBy;
                }
                else
                {
                    return(curPriority);
                }
            }


            throw new Exception($"Unable to determine next priority for vm {parameters.Name}. Stopped at {highestAllowed}");
        }
Пример #19
0
        public static void PrepareForNewOperation(ResourceProvisioningParameters currentCrudInput, CloudResourceOperationDto currentOperation, ResourceProvisioningResult lastResult, string nsgName = null)
        {
            currentCrudInput.ResetButKeepSharedVariables(lastResult?.NewSharedVariables);

            currentCrudInput.Name                     = currentOperation.Resource.ResourceName;
            currentCrudInput.StudyName                = currentOperation.Resource.StudyName;
            currentCrudInput.DatabaseId               = currentOperation.Resource.Id;
            currentCrudInput.StudyId                  = currentOperation.Resource.StudyId;
            currentCrudInput.SandboxId                = currentOperation.Resource.SandboxId;
            currentCrudInput.DatasetId                = currentOperation.Resource.DatasetId;
            currentCrudInput.SandboxName              = currentOperation.Resource.SandboxName;
            currentCrudInput.ResourceGroupName        = currentOperation.Resource.ResourceGroupName;
            currentCrudInput.Region                   = currentOperation.Resource.Region;
            currentCrudInput.Tags                     = currentOperation.Resource.Tags;
            currentCrudInput.ConfigurationString      = currentOperation.Resource.ConfigString;
            currentCrudInput.NetworkSecurityGroupName = nsgName;
        }
Пример #20
0
        public static ResourceProvisioningResult Create(ResourceProvisioningParameters provisionParameters, string resourceType)
        {
            var result = new ResourceProvisioningResult();

            result.CurrentProvisioningState = CloudResourceProvisioningStates.SUCCEEDED;
            result.IdInTargetSystem         = resourceType == AzureResourceType.ResourceGroup ? $"resourceGroups/{provisionParameters.ResourceGroupName}" : $"resources/{provisionParameters.Name}";
            result.NameInTargetSystem       = resourceType == AzureResourceType.ResourceGroup ? provisionParameters.ResourceGroupName : provisionParameters.Name;

            if (resourceType == AzureResourceType.NetworkSecurityGroup)
            {
                result.NewSharedVariables.Add(AzureCrudSharedVariable.NETWORK_SECURITY_GROUP_NAME, provisionParameters.Name);
            }
            else if (resourceType == AzureResourceType.VirtualNetwork)
            {
                result.NewSharedVariables.Add(AzureCrudSharedVariable.BASTION_SUBNET_ID, "bastionSubnetId");
            }

            return(result);
        }
        public async Task <ResourceProvisioningResult> EnsureCreated(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default)
        {
            _logger.LogInformation($"Ensuring Network Security Group exists for sandbox with Name: {parameters.SandboxName}! Resource Group: {parameters.ResourceGroupName}");

            var nsg = await GetResourceInternalAsync(parameters.ResourceGroupName, parameters.Name, false);

            if (nsg == null)
            {
                _logger.LogInformation($"Network Security Group not found for sandbox with Name: {parameters.SandboxName}! Resource Group: {parameters.ResourceGroupName}. Creating!");

                nsg = await CreateInternal(GetRegionFromString(parameters.Region), parameters.ResourceGroupName, parameters.Name, parameters.Tags, cancellationToken);
            }

            var result = CreateResult(nsg);

            _logger.LogInformation($"Done ensuring Network Security Group exists for sandbox with Id: {parameters.SandboxName}! Id: {nsg.Id}");

            return(result);
        }
Пример #22
0
        public async Task <ResourceProvisioningResult> EnsureCreated(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default)
        {
            _logger.LogInformation($"Creating Resource Group for sandbox with Name: {parameters.SandboxName}! Resource Group: {parameters.ResourceGroupName}");

            var resourceGroup = await GetResourceGroupAsync(parameters.ResourceGroupName, false);

            if (resourceGroup == null)
            {
                _logger.LogInformation($"Resource group not found, creating");
                resourceGroup = await CreateInternal(parameters.ResourceGroupName, GetRegionFromString(parameters.Region), parameters.Tags);
            }
            else
            {
                _logger.LogInformation($"Resource group allready exists");
            }

            var crudResult = ResourceProvisioningResultUtil.CreateFromIResource(resourceGroup);

            crudResult.CurrentProvisioningState = resourceGroup.ProvisioningState.ToString();

            _logger.LogInformation($"Done ensuring Resource Group for sandbox with Id: {parameters.SandboxName}! Resource Group Id: {resourceGroup.Id}");
            return(crudResult);
        }
        public async Task <ResourceProvisioningResult> EnsureCreated(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default)
        {
            _logger.LogInformation($"Ensuring Storage Account {parameters.Name} exists in Resource Group: {parameters.ResourceGroupName}");

            var storageAccount = await GetResourceAsync(parameters.ResourceGroupName, parameters.Name, false);

            if (storageAccount == null)
            {
                _logger.LogInformation($"Storage account not found, creating");

                var nameIsAvailable = await _azure.StorageAccounts.CheckNameAvailabilityAsync(parameters.Name);

                if (!(bool)nameIsAvailable.IsAvailable)
                {
                    _logger.LogError($"StorageAccountName not available/invalid. Message: {nameIsAvailable.Message}");
                    throw new ArgumentException($"StorageAccountName not available/invalid. Message: {nameIsAvailable.Message}");
                }

                // Create storage account
                storageAccount = await _azure.StorageAccounts.Define(parameters.Name)
                                 .WithRegion(parameters.Region)
                                 .WithExistingResourceGroup(parameters.ResourceGroupName)
                                 .WithAccessFromAllNetworks()
                                 .WithGeneralPurposeAccountKindV2()
                                 .WithOnlyHttpsTraffic()
                                 .WithSku(StorageAccountSkuType.Standard_LRS)
                                 .WithTags(parameters.Tags)
                                 .CreateAsync(cancellationToken);

                _logger.LogInformation($"Done creating storage account");
            }

            var result = CreateResult(storageAccount);

            return(result);
        }
Пример #24
0
 public Task <ResourceProvisioningResult> EnsureDeleted(ResourceProvisioningParameters parameters)
 {
     throw new NotImplementedException();
 }
        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 HandleWork(ProvisioningQueueParentDto queueParentItem)
        {
            _provisioningLogService.HandlingQueueParent(queueParentItem);

            //One per child item in queue item
            CloudResourceOperationDto currentOperation = null;

            //Get's re-used amonong child elements because the operations might share variables
            var currentProvisioningParameters = new ResourceProvisioningParameters();

            ResourceProvisioningResult currentProvisioningResult = null;

            try
            {
                //If more than one child/operation, run basic checks on all operations before starting
                if (queueParentItem.Children.Count > 1)
                {
                    _provisioningLogService.QueueParentProgressInformation(queueParentItem,
                                                                           "Multiple child item, running pre checks");

                    foreach (var queueChildItem in queueParentItem.Children)
                    {
                        currentOperation = await _resourceOperationReadService.GetByIdAsync(queueChildItem.ResourceOperationId);

                        _operationCheckService.ThrowIfPossiblyInProgress(currentOperation);
                    }
                }

                foreach (var queueChildItem in queueParentItem.Children)
                {
                    try
                    {
                        currentOperation = await _resourceOperationReadService.GetByIdAsync(queueChildItem.ResourceOperationId);

                        _provisioningLogService.OperationInformation(currentOperation, "Starting operation");

                        _operationCheckService.ThrowIfTryCountExceededOrAborted(currentOperation);

                        _operationCheckService.ThrowIfResourceIsDeletedAndOperationIsNotADelete(currentOperation);

                        _operationCheckService.ThrowIfPossiblyInProgress(currentOperation);

                        await _operationCheckService.ThrowIfDependentOnUnfinishedOperationAsync(currentOperation, queueParentItem);

                        string networkSecurityGroupName = null;

                        //Only relevant for Sandbox Resource Creation
                        if (currentOperation.Resource.SandboxId.HasValue)
                        {
                            var nsg = CloudResourceUtil.GetSibilingResource(await _resourceReadService.GetByIdNoAccessCheckAsync(currentOperation.Resource.Id), AzureResourceType.NetworkSecurityGroup);
                            networkSecurityGroupName = nsg?.ResourceName;
                        }

                        ProvisioningParamaterUtil.PrepareForNewOperation(currentProvisioningParameters, currentOperation, currentProvisioningResult, networkSecurityGroupName);

                        await _provisioningQueueService.IncreaseInvisibleBasedOnResource(currentOperation, queueParentItem);

                        _provisioningLogService.OperationInformation(currentOperation, "Initial checks passed");

                        if (_createAndUpdateService.CanHandle(currentOperation))
                        {
                            _provisioningLogService.OperationInformation(currentOperation, "Operation is CREATE or UPDATE");

                            var provisioningService = AzureResourceServiceResolver.GetProvisioningServiceOrThrow(_serviceProvider, currentOperation.Resource.ResourceType);

                            if (await _operationCompletedService.HandledAsAllreadyCompletedAsync(currentOperation))
                            {
                                _provisioningLogService.OperationInformation(currentOperation, "Operation is allready completed");
                                currentProvisioningResult = await provisioningService.GetSharedVariables(currentProvisioningParameters);

                                continue;
                            }
                            else
                            {
                                currentOperation = await _resourceOperationUpdateService.SetInProgressAsync(currentOperation.Id, _requestIdService.GetRequestId());

                                currentProvisioningResult = await _createAndUpdateService.Handle(currentOperation, currentProvisioningParameters, provisioningService);
                            }

                            currentOperation = await _resourceOperationUpdateService.TouchAsync(currentOperation.Id);

                            await _resourceOperationUpdateService.UpdateStatusAsync(currentOperation.Id,
                                                                                    CloudResourceOperationState.DONE_SUCCESSFUL,
                                                                                    updatedProvisioningState : currentProvisioningResult.CurrentProvisioningState);
                        }
                        else if (_deleteOperationService.CanHandle(currentOperation))
                        {
                            _provisioningLogService.OperationInformation(currentOperation, "Operation is DELETE");
                            var provisioningService = AzureResourceServiceResolver.GetProvisioningServiceOrThrow(_serviceProvider, currentOperation.Resource.ResourceType);
                            currentOperation = await _resourceOperationUpdateService.SetInProgressAsync(currentOperation.Id, _requestIdService.GetRequestId());

                            currentProvisioningResult = await _deleteOperationService.Handle(currentOperation, currentProvisioningParameters, provisioningService);

                            await _resourceOperationUpdateService.UpdateStatusAsync(currentOperation.Id, CloudResourceOperationState.DONE_SUCCESSFUL, updatedProvisioningState : null);
                        }
                        else if (_roleProvisioningService.CanHandle(currentOperation))
                        {
                            _provisioningLogService.OperationInformation(currentOperation, "Operation is ENSURE ROLES");
                            currentOperation = await _resourceOperationUpdateService.SetInProgressAsync(currentOperation.Id, _requestIdService.GetRequestId());

                            await _roleProvisioningService.Handle(currentOperation);

                            await _resourceOperationUpdateService.UpdateStatusAsync(currentOperation.Id, CloudResourceOperationState.DONE_SUCCESSFUL);
                        }
                        else if (_firewallService.CanHandle(currentOperation))
                        {
                            _provisioningLogService.OperationInformation(currentOperation, "Operation is ENSURE FIREWALL");
                            var firewallRuleService = AzureResourceServiceResolver.GetFirewallRuleService(_serviceProvider, currentOperation.Resource.ResourceType);
                            currentOperation = await _resourceOperationUpdateService.SetInProgressAsync(currentOperation.Id, _requestIdService.GetRequestId());

                            if (firewallRuleService is IHasFirewallRules)
                            {
                                await _firewallService.Handle(currentOperation,
                                                              firewallRuleService
                                                              );

                                await _resourceOperationUpdateService.UpdateStatusAsync(currentOperation.Id, CloudResourceOperationState.DONE_SUCCESSFUL);
                            }
                            else
                            {
                                throw new ProvisioningException($"Service {firewallRuleService.GetType().Name} does not support firewall operations", CloudResourceOperationState.ABORTED, deleteFromQueue: true);
                            }
                        }
                        else if (_corsRuleProvisioningService.CanHandle(currentOperation))
                        {
                            _provisioningLogService.OperationInformation(currentOperation, "Operation is ENSURE CORS RULES");
                            var corsRuleService = AzureResourceServiceResolver.GetCorsRuleServiceOrThrow(_serviceProvider, currentOperation.Resource.ResourceType);
                            currentOperation = await _resourceOperationUpdateService.SetInProgressAsync(currentOperation.Id, _requestIdService.GetRequestId());

                            if (corsRuleService is IHasCorsRules)
                            {
                                await _corsRuleProvisioningService.Handle(currentOperation, corsRuleService);

                                await _resourceOperationUpdateService.UpdateStatusAsync(currentOperation.Id, CloudResourceOperationState.DONE_SUCCESSFUL);
                            }
                            else
                            {
                                throw new ProvisioningException($"Service {corsRuleService.GetType().Name} does not support CORS operations", CloudResourceOperationState.ABORTED, deleteFromQueue: true);
                            }
                        }
                        else
                        {
                            throw new ProvisioningException("Unknown operation type", CloudResourceOperationState.ABORTED);
                        }

                        _provisioningLogService.OperationInformation(currentOperation, "Successfully handeled operation");
                    }
                    catch (ProvisioningException ex) //Inner loop, ordinary exception is not catched
                    {
                        if (ex.LogAsWarning)
                        {
                            if (ex.IncludeExceptionInWarningLog)
                            {
                                _provisioningLogService.OperationWarning(currentOperation, "Operation aborted", ex);
                            }
                            else
                            {
                                _provisioningLogService.OperationWarning(currentOperation, $"Operation aborted: {ex.Message}");
                            }
                        }
                        else
                        {
                            _provisioningLogService.OperationError(ex, currentOperation, "Operation failed");
                        }

                        currentOperation = await _resourceOperationUpdateService.SetErrorMessageAsync(currentOperation.Id, ex);

                        if (!String.IsNullOrWhiteSpace(ex.NewOperationStatus))
                        {
                            currentOperation = await _resourceOperationUpdateService.UpdateStatusAsync(currentOperation.Id, ex.NewOperationStatus);
                        }

                        if (!ex.ProceedWithOtherOperations)
                        {
                            throw;
                        }
                    }
                } //foreach

                _provisioningLogService.QueueParentProgressInformation(queueParentItem, "Done");

                await _provisioningQueueService.DeleteMessageAsync(queueParentItem);
                await MoveUpAnyDependentOperations(queueParentItem);
            }
            catch (ProvisioningException ex) //Outer loop catch 1
            {
                if (ex.DeleteFromQueue)
                {
                    _provisioningLogService.QueueParentProgressWarning(queueParentItem, "Deleting due to exception");
                    await _provisioningQueueService.DeleteMessageAsync(queueParentItem);
                }
                else if (ex.PostponeQueueItemFor.HasValue && ex.PostponeQueueItemFor.Value > 0)
                {
                    if (currentOperation.TryCount < currentOperation.MaxTryCount)
                    {
                        if (queueParentItem.DequeueCount == 5)
                        {
                            _provisioningLogService.QueueParentProgressWarning(queueParentItem, "Re-queuing after exception");

                            await _provisioningQueueService.ReQueueMessageAsync(queueParentItem, ex.PostponeQueueItemFor.Value);
                        }
                        else
                        {
                            _provisioningLogService.QueueParentProgressWarning(queueParentItem, "Increasing invisibility after exception");
                            await _provisioningQueueService.IncreaseInvisibilityAsync(queueParentItem, ex.PostponeQueueItemFor.Value);
                        }
                    }
                }

                if (ex.StoreQueueInfoOnOperation)
                {
                    if (!queueParentItem.NextVisibleOn.HasValue)
                    {
                        _provisioningLogService.QueueParentProgressError(queueParentItem, "Could not store queue info on operation, no next visible time exist");
                    }
                    else
                    {
                        currentOperation = await _resourceOperationUpdateService.SetQueueInformationAsync(currentOperation.Id, queueParentItem.MessageId, queueParentItem.PopReceipt, queueParentItem.NextVisibleOn.Value);
                    }
                }
            }
            catch (Exception ex) //Outer loop catch 2
            {
                _provisioningLogService.QueueParentProgressError(queueParentItem, "Unhandled exception occured");
                await _provisioningQueueService.DeleteMessageAsync(queueParentItem);
            }
        }
 public Task <ResourceProvisioningResult> Update(ResourceProvisioningParameters parameters, CancellationToken cancellationToken = default)
 {
     throw new NotImplementedException();
 }
Пример #28
0
        Task <ResourceProvisioningResult> CreateProvisioningResultTask(CloudResourceOperationDto operation, ResourceProvisioningParameters currentCrudInput, IPerformResourceProvisioning provisioningService, CancellationTokenSource cancellation)
        {
            if (operation.OperationType == CloudResourceOperationType.CREATE)
            {
                return(provisioningService.EnsureCreated(currentCrudInput, cancellation.Token));
            }

            return(provisioningService.Update(currentCrudInput, cancellation.Token));
        }
        async Task UpdateVmRules(ResourceProvisioningParameters parameters, VmSettingsDto vmSettings, string privateIp, CancellationToken cancellationToken = default)
        {
            _logger.LogInformation($"Setting desired VM rules for {parameters.Name}");

            var existingRules = await _azureNetworkSecurityGroupRuleService.GetNsgRulesContainingName(parameters.ResourceGroupName, parameters.NetworkSecurityGroupName, $"{AzureResourceNameUtil.NSG_RULE_FOR_VM_PREFIX}{parameters.DatabaseId}", cancellationToken);

            var existingRulesThatStillExists = new HashSet <string>();

            if (vmSettings.Rules == null)
            {
                throw new Exception($"No rules exists for VM {parameters.Name}");
            }
            else
            {
                foreach (var curRule in vmSettings.Rules)
                {
                    try
                    {
                        var ruleMapped = _mapper.Map <NsgRuleDto>(curRule);

                        if (curRule.Direction == RuleDirection.Inbound)
                        {
                            ruleMapped.SourceAddress      = curRule.Ip;
                            ruleMapped.SourcePort         = curRule.Port;
                            ruleMapped.DestinationAddress = privateIp;
                            ruleMapped.DestinationPort    = curRule.Port;

                            //get existing rule and use that name
                            if (existingRules.TryGetValue(curRule.Name, out NsgRuleDto existingRule))
                            {
                                existingRulesThatStillExists.Add(curRule.Name);
                                ruleMapped.Priority = existingRule.Priority;
                                await _azureNetworkSecurityGroupRuleService.UpdateInboundRule(parameters.ResourceGroupName, parameters.NetworkSecurityGroupName, ruleMapped, cancellationToken);
                            }
                            else
                            {
                                ruleMapped.Priority = await FindNextPriority(parameters, existingRules, AzureVmConstants.MIN_RULE_PRIORITY, 10, AzureVmConstants.MAX_RULE_PRIORITY, curRule.Direction.ToString());

                                await _azureNetworkSecurityGroupRuleService.AddInboundRule(parameters.ResourceGroupName, parameters.NetworkSecurityGroupName, ruleMapped, cancellationToken);
                            }
                        }
                        else
                        {
                            ruleMapped.SourceAddress = privateIp;
                            ruleMapped.SourcePort    = curRule.Port;

                            if (ruleMapped.Name.Contains(AzureVmConstants.RulePresets.OPEN_CLOSE_INTERNET))
                            {
                                ruleMapped.DestinationAddress = "*";
                                ruleMapped.DestinationPort    = 0;
                            }
                            else
                            {
                                ruleMapped.DestinationAddress = curRule.Ip;
                                ruleMapped.DestinationPort    = curRule.Port;
                            }

                            if (existingRules.TryGetValue(curRule.Name, out NsgRuleDto existingRule))
                            {
                                existingRulesThatStillExists.Add(curRule.Name);
                                ruleMapped.Priority = existingRule.Priority; //Ensure same priority is re-used
                                await _azureNetworkSecurityGroupRuleService.UpdateOutboundRule(parameters.ResourceGroupName, parameters.NetworkSecurityGroupName, ruleMapped, cancellationToken);
                            }
                            else
                            {
                                ruleMapped.Priority = await FindNextPriority(parameters, existingRules, AzureVmConstants.MIN_RULE_PRIORITY, 10, AzureVmConstants.MAX_RULE_PRIORITY, curRule.Direction.ToString());

                                await _azureNetworkSecurityGroupRuleService.AddOutboundRule(parameters.ResourceGroupName, parameters.NetworkSecurityGroupName, ruleMapped, cancellationToken);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception($"Unable to create rule {curRule.Name} for VM {parameters.Name}", ex);
                    }
                }
            }

            if (existingRules != null && existingRules.Count > 0)
            {
                foreach (var curExistingKvp in existingRules)
                {
                    if (!existingRulesThatStillExists.Contains(curExistingKvp.Key))
                    {
                        await _azureNetworkSecurityGroupRuleService.DeleteRule(parameters.ResourceGroupName, parameters.NetworkSecurityGroupName, curExistingKvp.Key, cancellationToken);
                    }
                }
            }

            _logger.LogInformation($"Done setting desired VM rules for {parameters.Name}");
        }