/// <summary> /// Exports service specific deployment details. /// </summary> /// <param name="serviceName">CloudService name</param> /// <param name="deploymentResponse">Deployment response received from Microsoft Azure API</param> /// <returns>Cloud service specific deployment details</returns> private Deployment ExportDeployment(string serviceName, DeploymentGetResponse deploymentResponse) { string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name; Logger.Info(methodName, string.Format(ProgressResources.ExportDeploymentStarted, deploymentResponse.Name, serviceName), ResourceType.Deployment.ToString(), deploymentResponse.Name); try { Deployment deployment = new Deployment { DnsSettings = deploymentResponse.DnsSettings, ExtendedProperties = deploymentResponse.ExtendedProperties, Label = deploymentResponse.Label, LoadBalancers = deploymentResponse.LoadBalancers, Name = deploymentResponse.Name, ReservedIPName = deploymentResponse.ReservedIPName, VirtualIPAddresses = deploymentResponse.VirtualIPAddresses, VirtualNetworkName = deploymentResponse.VirtualNetworkName, //// Export Virtual Machines VirtualMachines = ExportVirtualMachines(serviceName, deploymentResponse), IsImported = false }; Logger.Info(methodName, string.Format(ProgressResources.ExportDeploymentCompleted, deploymentResponse.Name, serviceName), ResourceType.Deployment.ToString(), deploymentResponse.Name); return deployment; } catch (Exception ex) { Logger.Error(methodName, ex, ResourceType.Deployment.ToString(), deploymentResponse.Name); throw; } }
/// <summary> /// Creates deployment and virtual machines in destination subscription. /// </summary> /// <param name="deploymentDetails">Deployment details</param> /// <param name="serviceName">Cloud service name</param> private void CreateDeployment(Deployment deploymentDetails, string serviceName) { string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name; Logger.Info(methodName, ProgressResources.ExecutionStarted, ResourceType.Deployment.ToString(), deploymentDetails.Name); Stopwatch swTotalDeploymentWithVMs = new Stopwatch(); swTotalDeploymentWithVMs.Start(); if (!deploymentDetails.IsImported) { //List<Uri> disks = null; string containerName; using (var client = new ComputeManagementClient(importParameters.SourceSubscriptionSettings.Credentials, importParameters.SourceSubscriptionSettings.ServiceUrl)) { try { using (var computeClient = new ComputeManagementClient(importParameters.DestinationSubscriptionSettings.Credentials)) { for (int virtualMachineNumber = 0; virtualMachineNumber < deploymentDetails.VirtualMachines.Count(); virtualMachineNumber++) { VirtualMachine virtualMachine = deploymentDetails.VirtualMachines[virtualMachineNumber]; // Check if virtual machine is already imported, if not create new virtual machine if (!virtualMachine.IsImported) { string sourceStorageAccountName = virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.MediaLink.Host.Substring( 0, virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.MediaLink.Host.IndexOf('.')); string accountName = GetDestinationResourceName(ResourceType.StorageAccount, sourceStorageAccountName); Stopwatch swDeployment = new Stopwatch(); swDeployment.Start(); containerName = virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.MediaLink.Segments[1].Substring(0, virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.MediaLink.Segments[1].IndexOf('/')); ; // Set up the Virtual Hard Disk with the OS Disk var vhd = new OSVirtualHardDisk { HostCaching = virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.HostCaching, //IOType is implicitly determined from the MediaLink. This should not be explicitly specified in the request. Label = virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.Label, MediaLink = new Uri(string.Format(CultureInfo.InvariantCulture, Constants.StorageAccountMediaLink, accountName, containerName, virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.MediaLink.Segments.Last()), UriKind.Absolute), Name = string.Format("{0}{1}", importParameters.DestinationPrefixName, GetDestinationResourceName(ResourceType.OSDisk, virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.Name, ResourceType.CloudService, serviceName)), OperatingSystem = virtualMachine.VirtualMachineDetails.OSVirtualHardDisk.OperatingSystem, //SourceImageName should be set only when creating the virtual machine from an image. Here we create it from a disk. }; // Set up the Data Disk List<DataVirtualHardDisk> dataDisks = new List<DataVirtualHardDisk>(); foreach (var disk in virtualMachine.VirtualMachineDetails.DataVirtualHardDisks) { dataDisks.Add(new DataVirtualHardDisk { HostCaching = disk.HostCaching, //IOType is implicitly determined from the MediaLink. This should not be explicitly specified in the request. Label = disk.Label, LogicalDiskSizeInGB = disk.LogicalDiskSizeInGB, LogicalUnitNumber = disk.LogicalUnitNumber, MediaLink = new Uri(string.Format(CultureInfo.InvariantCulture, Constants.StorageAccountMediaLink, accountName, containerName, disk.MediaLink.Segments.Last()), UriKind.Absolute), Name = string.Format("{0}{1}", importParameters.DestinationPrefixName, GetDestinationResourceName(ResourceType.HardDisk, disk.Name, ResourceType.CloudService, serviceName)), SourceMediaLink = new Uri(string.Format(CultureInfo.InvariantCulture, Constants.StorageAccountMediaLink, accountName, containerName, disk.MediaLink.Segments.Last()), UriKind.Absolute) }); }; // Deploy the Virtual Machine Logger.Info(methodName, string.Format(ProgressResources.ImportVirtualMachineStarted, virtualMachine.VirtualMachineDetails.RoleName, deploymentDetails.Name), ResourceType.VirtualMachine.ToString(), virtualMachine.VirtualMachineDetails.RoleName); // For first virtual machine create new deployment if (virtualMachineNumber == 0) { List<Role> roles = new List<Role>(); roles.Add(new Role { AvailabilitySetName = virtualMachine.VirtualMachineDetails.AvailabilitySetName, ConfigurationSets = virtualMachine.VirtualMachineDetails.ConfigurationSets, DataVirtualHardDisks = dataDisks, DefaultWinRmCertificateThumbprint = virtualMachine.VirtualMachineDetails.DefaultWinRmCertificateThumbprint, Label = null, // Label is set automatically. MediaLocation = virtualMachine.VirtualMachineDetails.MediaLocation, OSVersion = virtualMachine.VirtualMachineDetails.OSVersion, OSVirtualHardDisk = vhd, ProvisionGuestAgent = true, ResourceExtensionReferences = virtualMachine.VirtualMachineDetails.ResourceExtensionReferences, RoleName = virtualMachine.VirtualMachineDetails.RoleName, RoleSize = virtualMachine.VirtualMachineDetails.RoleSize, RoleType = virtualMachine.VirtualMachineDetails.RoleType, VMImageName = virtualMachine.VirtualMachineDetails.VMImageName }); // Create the deployment parameters var createDeploymentParameters = new VirtualMachineCreateDeploymentParameters { DeploymentSlot = DeploymentSlot.Production, DnsSettings = deploymentDetails.DnsSettings, Label = deploymentDetails.Name, // Set it to new name instead of old deployment label. LoadBalancers = deploymentDetails.LoadBalancers, Name = deploymentDetails.Name, ReservedIPName = deploymentDetails.ReservedIPName, Roles = roles, VirtualNetworkName = deploymentDetails.VirtualNetworkName }; var deploymentResult = Retry.RetryOperation(() => computeClient.VirtualMachines.CreateDeployment( serviceName, createDeploymentParameters), (BaseParameters)importParameters, ResourceType.VirtualMachine, virtualMachine.VirtualMachineDetails.RoleName); UpdateMedatadaFile(ResourceType.VirtualMachine, virtualMachine.VirtualMachineDetails.RoleName, parentResourceName: serviceName); } // Add virtual machine in existing deployment else { VirtualMachineCreateParameters parameters = new VirtualMachineCreateParameters { AvailabilitySetName = virtualMachine.VirtualMachineDetails.AvailabilitySetName, ConfigurationSets = virtualMachine.VirtualMachineDetails.ConfigurationSets, DataVirtualHardDisks = dataDisks, MediaLocation = virtualMachine.VirtualMachineDetails.MediaLocation, OSVirtualHardDisk = vhd, ProvisionGuestAgent = true, ResourceExtensionReferences = virtualMachine.VirtualMachineDetails.ResourceExtensionReferences, RoleName = virtualMachine.VirtualMachineDetails.RoleName, RoleSize = virtualMachine.VirtualMachineDetails.RoleSize, VMImageName = virtualMachine.VirtualMachineDetails.VMImageName }; Retry.RetryOperation(() => computeClient.VirtualMachines.Create(serviceName, deploymentDetails.Name, parameters), (BaseParameters)importParameters, ResourceType.VirtualMachine, virtualMachine.VirtualMachineDetails.RoleName, () => DeleteVirtualMachineIfTaskCancelled(ResourceType.VirtualMachine, serviceName, deploymentDetails.Name, virtualMachine.VirtualMachineDetails.RoleName)); UpdateMedatadaFile(ResourceType.VirtualMachine, virtualMachine.VirtualMachineDetails.RoleName, parentResourceName: serviceName); } swDeployment.Stop(); Logger.Info(methodName, string.Format(ProgressResources.ImportVirtualMachineCompleted, virtualMachine.VirtualMachineDetails.RoleName, deploymentDetails.Name, swDeployment.Elapsed.Days, swDeployment.Elapsed.Hours, swDeployment.Elapsed.Minutes, swDeployment.Elapsed.Seconds), ResourceType.VirtualMachine.ToString(), virtualMachine.VirtualMachineDetails.RoleName); // ShutDown created virtual machine. computeClient.VirtualMachines.Shutdown(serviceName, deploymentDetails.Name, virtualMachine.VirtualMachineDetails.RoleName, new VirtualMachineShutdownParameters { PostShutdownAction = PostShutdownAction.StoppedDeallocated }); } } UpdateMedatadaFile(ResourceType.Deployment, deploymentDetails.Name, parentResourceName: serviceName); } } catch (Exception ex) { Logger.Error(methodName, ex, ResourceType.Deployment.ToString(), deploymentDetails.Name); throw; } } } swTotalDeploymentWithVMs.Stop(); Logger.Info(methodName, string.Format(ProgressResources.ExecutionCompletedWithTime, swTotalDeploymentWithVMs.Elapsed.Days, swTotalDeploymentWithVMs.Elapsed.Hours, swTotalDeploymentWithVMs.Elapsed.Minutes, swTotalDeploymentWithVMs.Elapsed.Seconds), ResourceType.Deployment.ToString(), deploymentDetails.Name); }