Esempio n. 1
0
        public async Task <Deployment> BeginDeploymentAsync(IDeployable deployment)
        {
            using (var client = await _managementClientProvider.CreateResourceManagementClient(deployment.SubscriptionId))
            {
                await client.ResourceGroups.CreateOrUpdateAsync(
                    deployment.ResourceGroupName,
                    new ResourceGroup {
                    Location = deployment.Location
                });

                var templateParams = deployment.DeploymentParameters;

                var properties = new Microsoft.Azure.Management.ResourceManager.Models.Deployment
                {
                    Properties = new DeploymentProperties
                    {
                        Template   = await _templateProvider.GetTemplate(deployment.TemplateName),
                        Parameters = _templateProvider.GetParameters(templateParams),
                        Mode       = DeploymentMode.Incremental
                    }
                };

                // Start the ARM deployment
                var deploymentResult = await client.Deployments.BeginCreateOrUpdateAsync(
                    deployment.ResourceGroupName,
                    deployment.DeploymentName,
                    properties);

                return(ToDeploymentStatus(deploymentResult));
            }
        }
        //
        // Deployment operations
        //
        public async Task BeginRepositoryDeploymentAsync(AssetRepository repository)
        {
            using (var client = await _clientProvider.CreateResourceManagementClient(repository.SubscriptionId))
            {
                await client.ResourceGroups.CreateOrUpdateAsync(
                    repository.ResourceGroupName,
                    new ResourceGroup(
                        repository.Subnet.Location, // The subnet location pins us to a region
                        tags : AzureResourceProvider.GetEnvironmentTags(repository.EnvironmentName)));

                await _azureResourceProvider.AssignRoleToIdentityAsync(
                    repository.SubscriptionId,
                    repository.ResourceGroupResourceId,
                    AzureResourceProvider.ContributorRole,
                    _identityProvider.GetPortalManagedServiceIdentity());

                repository.Deployment = new AzureRenderHub.WebApp.Arm.Deploying.Deployment
                {
                    DeploymentName    = $"{repository.Name}-{Guid.NewGuid()}",
                    SubscriptionId    = repository.SubscriptionId,
                    ResourceGroupName = repository.ResourceGroupName,
                };

                await UpdateRepository(repository);

                await DeployRepository(repository);
            }
        }
Esempio n. 3
0
        public async Task <ActionResult> Step3FileServer(string repoId, AddNfsFileServerModel model)
        {
            // Validate that the share isn't a root share
            if (model.FileShareName.StartsWith("/") &&
                model.FileShareName.Split("/", StringSplitOptions.RemoveEmptyEntries).Length == 1)
            {
                ModelState.AddModelError(nameof(AddNfsFileServerModel.FileShareName), "File share cannot be at the root of the file system, e.g. /share.");
            }

            if (!ModelState.IsValid)
            {
                return(View("Create/Step3FileServer", model));
            }

            var repository = await _assetRepoCoordinator.GetRepository(repoId);

            if (repository == null)
            {
                return(RedirectToAction("Overview"));
            }

            // validate the resource group doesn't exist or is empty
            var client = await _managementClientProvider.CreateResourceManagementClient(repository.SubscriptionId);

            if (!await ValidateResourceGroup(client, model.NewResourceGroupName, nameof(model.NewResourceGroupName)))
            {
                if (!ModelState.IsValid)
                {
                    return(View("Create/Step3FileServer", model));
                }
            }

            if (repository.Enabled)
            {
                return(RedirectToAction("Overview"));
            }

            try
            {
                repository.UpdateFromModel(model);
                await _assetRepoCoordinator.BeginRepositoryDeploymentAsync(repository);
            }
            catch (Exception ex)
            {
                model.Error        = "Failed to create repository with error";
                model.ErrorMessage = ex.ToString();
                return(View("Create/Step3FileServer", model));
            }

            return(RedirectToAction("Overview", new { repoId = repository.Name }));
        }
        private async Task DeployFileServer(NfsFileServer repository, IManagementClientProvider managementClientProvider)
        {
            try
            {
                using (var client = await managementClientProvider.CreateResourceManagementClient(repository.SubscriptionId))
                {
                    await client.ResourceGroups.CreateOrUpdateAsync(repository.ResourceGroupName,
                                                                    new ResourceGroup { Location = repository.Subnet.Location });

                    var templateParams = GetTemplateParameters(repository);

                    var properties = new Deployment
                    {
                        Properties = new DeploymentProperties
                        {
                            Template   = await _templateProvider.GetTemplate("linux-file-server.json"),
                            Parameters = _templateProvider.GetParameters(templateParams),
                            Mode       = DeploymentMode.Incremental
                        }
                    };

                    // Start the ARM deployment
                    await client.Deployments.BeginCreateOrUpdateAsync(
                        repository.ResourceGroupName,
                        repository.DeploymentName,
                        properties);

                    // Queue a request for the background host to monitor the deployment
                    // and update the state and IP address when it's done.
                    await _deploymentQueue.Add(new ActiveDeployment
                    {
                        FileServerName = repository.Name,
                        StartTime      = DateTime.UtcNow,
                    });

                    repository.ProvisioningState = ProvisioningState.Running;
                    repository.InProgress        = false;

                    await UpdateRepository(repository);
                }
            }
            catch (CloudException ex)
            {
                _logger.LogError(ex, $"Failed to deploy NFS server: {ex.Message}.");
                throw;
            }
        }
        private async Task <DeploymentExtended> GetDeploymentAsync(AssetRepository assetRepo, IManagementClientProvider managementClientProvider)
        {
            using (var resourceClient = await managementClientProvider.CreateResourceManagementClient(assetRepo.SubscriptionId))
            {
                try
                {
                    return(await resourceClient.Deployments.GetAsync(
                               assetRepo.ResourceGroupName,
                               assetRepo.DeploymentName));
                }
                catch (CloudException e)
                {
                    if (ResourceNotFound(e))
                    {
                        return(null);
                    }

                    throw;
                }
            }
        }
        //
        // Deployment operations
        //
        public async Task BeginRepositoryDeploymentAsync(AssetRepository repository, IManagementClientProvider managementClientProvider, IAzureResourceProvider azureResourceProvider)
        {
            using (var client = await managementClientProvider.CreateResourceManagementClient(repository.SubscriptionId))
            {
                await client.ResourceGroups.CreateOrUpdateAsync(
                    repository.ResourceGroupName,
                    new ResourceGroup(
                        repository.Subnet.Location, // The subnet location pins us to a region
                        tags : AzureResourceProvider.GetEnvironmentTags(repository.EnvironmentName)));

                await azureResourceProvider.AssignManagementIdentityAsync(
                    repository.SubscriptionId,
                    repository.ResourceGroupResourceId,
                    AzureResourceProvider.ContributorRole,
                    _identityProvider.GetPortalManagedServiceIdentity());

                repository.DeploymentName = "FileServerDeployment";
                await UpdateRepository(repository);

                await DeployFileServer(repository as NfsFileServer, managementClientProvider);
            }
        }
        public async Task DeleteRepositoryResourcesAsync(AssetRepository repository, IManagementClientProvider managementClientProvider)
        {
            var fileServer = repository as NfsFileServer;

            if (fileServer == null)
            {
                return;
            }

            using (var resourceClient = await managementClientProvider.CreateResourceManagementClient(repository.SubscriptionId))
                using (var computeClient = await managementClientProvider.CreateComputeManagementClient(repository.SubscriptionId))
                    using (var networkClient = await managementClientProvider.CreateNetworkManagementClient(repository.SubscriptionId))
                    {
                        try
                        {
                            var virtualMachine = await computeClient.VirtualMachines.GetAsync(fileServer.ResourceGroupName, fileServer.VmName);

                            var nicName   = virtualMachine.NetworkProfile.NetworkInterfaces[0].Id.Split("/").Last();;
                            var avSetName = virtualMachine.AvailabilitySet.Id?.Split("/").Last();
                            var osDisk    = virtualMachine.StorageProfile.OsDisk.ManagedDisk.Id.Split("/").Last();
                            var dataDisks = virtualMachine.StorageProfile.DataDisks.Select(dd => dd.ManagedDisk.Id.Split("/").Last()).ToList();

                            string pip = null;
                            string nsg = null;
                            try
                            {
                                var nic = await networkClient.NetworkInterfaces.GetAsync(fileServer.ResourceGroupName, nicName);

                                pip = nic.IpConfigurations[0].PublicIPAddress?.Id.Split("/").Last();
                                nsg = nic.NetworkSecurityGroup?.Id.Split("/").Last();
                            }
                            catch (CloudException ex) when(ResourceNotFound(ex))
                            {
                                // NIC doesn't exist
                            }

                            await IgnoreNotFound(async() =>
                            {
                                await computeClient.VirtualMachines.GetAsync(fileServer.ResourceGroupName, fileServer.VmName);
                                await computeClient.VirtualMachines.DeleteAsync(fileServer.ResourceGroupName, fileServer.VmName);
                            });

                            if (nicName != null)
                            {
                                await IgnoreNotFound(() => networkClient.NetworkInterfaces.DeleteAsync(fileServer.ResourceGroupName, nicName));
                            }

                            var tasks = new List <Task>();

                            if (nsg == "nsg")
                            {
                                tasks.Add(IgnoreNotFound(() => networkClient.NetworkSecurityGroups.DeleteAsync(fileServer.ResourceGroupName, nsg)));
                            }

                            if (pip != null)
                            {
                                tasks.Add(IgnoreNotFound(() => networkClient.PublicIPAddresses.DeleteAsync(fileServer.ResourceGroupName, pip)));
                            }

                            tasks.Add(IgnoreNotFound(() => computeClient.Disks.DeleteAsync(fileServer.ResourceGroupName, osDisk)));

                            tasks.AddRange(dataDisks.Select(
                                               dd => IgnoreNotFound(() => computeClient.Disks.DeleteAsync(fileServer.ResourceGroupName, dd))));

                            await Task.WhenAll(tasks);

                            if (avSetName != null)
                            {
                                await IgnoreNotFound(() => computeClient.AvailabilitySets.DeleteAsync(fileServer.ResourceGroupName, avSetName));
                            }
                        }
                        catch (CloudException ex) when(ResourceNotFound(ex))
                        {
                            // VM doesn't exist
                        }

                        try
                        {
                            await resourceClient.ResourceGroups.GetAsync(fileServer.ResourceGroupName);

                            var resources = await resourceClient.Resources.ListByResourceGroupAsync(fileServer.ResourceGroupName);

                            if (resources.Any())
                            {
                                _logger.LogDebug($"Skipping resource group deletion as it contains the following resources: {string.Join(", ", resources.Select(r => r.Id))}");
                            }
                            else
                            {
                                await resourceClient.ResourceGroups.DeleteAsync(fileServer.ResourceGroupName);
                            }
                        }
                        catch (CloudException ex) when(ResourceNotFound(ex))
                        {
                            // RG doesn't exist
                        }

                        await RemoveRepository(repository);
                    }
        }