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); } }
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); } }