Azure Virtual Machine 之 如何利用Management Class Libraries 创建VM

之前发的blog简单的介绍了如何使用Management Class Libraries 来控制Azure platform。

但由于官方并没有提供文档,所以我们只能够通过自己研究来摸索使用该类库的方法。

在使用过程中我发现可以再抽象出一层中间层,从而让该类库的使用更趋近于Management REST API。

下面以创建一个Virtual Machine 为例让我们来了解如何使用该类库来操作Virtual Machine

首先我们要知道,在Azure Platform中,任何一个VM Instance都要运行在一个HostedService 里面的Deployment下面的。

所以在使用过程中我们需要首先创建一个Hosted Service。

我们可以通过以下两个方法来进行创建:

  public static void createCloudServiceByLocation(string cloudServiceName, string location)
        {
            ComputeManagementClient client = new ComputeManagementClient(getCredentials());
            HostedServiceCreateParameters hostedServiceCreateParams = new HostedServiceCreateParameters
            {
                ServiceName = cloudServiceName,
                Location = location,
                Label = EncodeToBase64(cloudServiceName),
            };
            try
            {
                client.HostedServices.Create(hostedServiceCreateParams);
            }
            catch (CloudException e)
            {
                throw e;
            }

        }
        public static void createCloudServiceByAffinityGroup(string cloudServiceName, string affinityGroupName)
        {
            ComputeManagementClient client = new ComputeManagementClient(getCredentials());
            HostedServiceCreateParameters hostedServiceCreateParams = new HostedServiceCreateParameters
            {
                ServiceName = cloudServiceName,
                AffinityGroup = affinityGroupName,
                Label = EncodeToBase64(cloudServiceName),
            };
            try
            {
                client.HostedServices.Create(hostedServiceCreateParams);
            }
            catch (CloudException e)
            {
                throw e;
            }

        }
View Code

在有了HostedService之后,我们可以通过两种方式来创建VM。

第一种:首先创建一个Deployment,然后再通过添加角色来向这个Deployment中添加Virtual Machine,这样需要与Azure平台交互两次。

第二种:直接调用创建虚拟机部署,这样将在一个Request中创建一个虚拟机的Deployment并且将添加1或多个Virtual Machine到该Deployment下面。

我们可以通过创建自己的Extension Class Library来使得操作更趋向于REST API,一下是我抽象层的代码:

public static class MyVirtualMachineExtension
    {
        /// <summary>
        /// Instantiation a new VM Role
        /// </summary>
        public static Role CreateVMRole(this IVirtualMachineOperations client, string cloudServiceName, string roleName, VirtualMachineRoleSize roleSize, string userName, string password, OSVirtualHardDisk osVHD)
        {
            Role vmRole = new Role
            {
                RoleType = VirtualMachineRoleType.PersistentVMRole.ToString(),
                RoleName = roleName,
                Label = roleName,
                RoleSize = roleSize,
                ConfigurationSets = new List<ConfigurationSet>(),
                OSVirtualHardDisk = osVHD
            };
            ConfigurationSet configSet = new ConfigurationSet
            {
                ConfigurationSetType = ConfigurationSetTypes.WindowsProvisioningConfiguration,
                EnableAutomaticUpdates = true,
                ResetPasswordOnFirstLogon = false,
                ComputerName = roleName,
                AdminUserName = userName,
                AdminPassword = password,
                InputEndpoints = new BindingList<InputEndpoint>
                {
                    new InputEndpoint { LocalPort = 3389, Name = "RDP", Protocol = "tcp" },
                    new InputEndpoint { LocalPort = 80, Port = 80, Name = "web", Protocol = "tcp" }
                }
            };
            vmRole.ConfigurationSets.Add(configSet);
            return vmRole;
        }

        public static OSVirtualHardDisk CreateOSVHD(this IVirtualMachineImageOperations operation, string cloudserviceName, string vmName, string storageAccount, string imageFamiliyName)
        {
            try
            {
                var osVHD = new OSVirtualHardDisk
                {
                    MediaLink = GetVhdUri(string.Format("{0}.blob.core.windows.net/vhds", storageAccount), cloudserviceName, vmName),
                    SourceImageName = GetSourceImageNameByFamliyName(operation, imageFamiliyName)
                };
                return osVHD;
            }
            catch (CloudException e)
            {

                throw e;
            }

        }

        private static string GetSourceImageNameByFamliyName(this IVirtualMachineImageOperations operation, string imageFamliyName)
        {
            var disk = operation.List().Where(o => o.ImageFamily == imageFamliyName).FirstOrDefault();
            if (disk != null)
            {
                return disk.Name;
            }
            else
            {
                throw new CloudException(string.Format("Can't find {0} OS image in current subscription"));
            }
        }

        private static Uri GetVhdUri(string blobcontainerAddress, string cloudServiceName, string vmName, bool cacheDisk = false, bool https = false)
        {
            var now = DateTime.UtcNow;
            string dateString = now.Year + "-" + now.Month + "-" + now.Day;

            var address = string.Format("http{0}://{1}/{2}-{3}-{4}-{5}-650.vhd", https ? "s" : string.Empty, blobcontainerAddress, cloudServiceName, vmName, cacheDisk ? "-CacheDisk" : string.Empty, dateString);
            return new Uri(address);
        }

        public static void CreateVMDeployment(this IVirtualMachineOperations operations, string cloudServiceName, string deploymentName, List<Role> roleList, DeploymentSlot slot = DeploymentSlot.Production)
        {

            try
            {
                VirtualMachineCreateDeploymentParameters createDeploymentParams = new VirtualMachineCreateDeploymentParameters
                {

                    Name = deploymentName,
                    Label = cloudServiceName,
                    Roles = roleList,
                    DeploymentSlot = slot
                };
                operations.CreateDeployment(cloudServiceName, createDeploymentParams);
            }
            catch (CloudException e)
            {
                throw e;
            }
        }

        public static void AddRole(this IVirtualMachineOperations operations, string cloudServiceName, string deploymentName, Role role, DeploymentSlot slot = DeploymentSlot.Production)
        {
            try
            {
                VirtualMachineCreateParameters createParams = new VirtualMachineCreateParameters
                {
                    RoleName = role.Label,
                    RoleSize = role.RoleSize,
                    OSVirtualHardDisk = role.OSVirtualHardDisk,
                    ConfigurationSets = role.ConfigurationSets,
                    AvailabilitySetName = role.AvailabilitySetName,
                    DataVirtualHardDisks = role.DataVirtualHardDisks
                };

                operations.Create(cloudServiceName, deploymentName, createParams);
            }
            catch (CloudException e)
            {
                throw e;
            }
           
        }
    }
View Code

整体programe代码如下:

 class Program
    {
       
        public const string base64EncodedCertificate = "";
        public const string subscriptionId = "";

        public static string vmName = "Azure111";
        public static string location = "East Asia";
        public static string storageAccountName = "superdino";
        public static string userName = "Dino";
        public static string password = "PassWord1!";

        public static string imageFamiliyName = "Windows Server 2012 Datacenter";

        
        static void Main(string[] args)
        {
            ComputeManagementClient client = new ComputeManagementClient(getCredentials());
            //You need a hosted service host VM.
            try
            {
                client.HostedServices.Get(vmName);
            }
            catch (CloudException e)
            {
                createCloudServiceByLocation(vmName, location);
            }
            

            var OSVHD = client.VirtualMachineImages.CreateOSVHD(vmName, vmName, storageAccountName, imageFamiliyName);
            var VMROle = client.VirtualMachines.CreateVMRole(vmName, vmName, VirtualMachineRoleSize.Small, userName, password, OSVHD);
            List<Role> roleList = new List<Role>{
                VMROle
            };
            client.VirtualMachines.CreateVMDeployment(vmName, vmName, roleList);
            Console.WriteLine("Create VM success");
            client.VirtualMachines.AddRole("CloudServiceName", "ExsitDeploymentName", VMROle);

            Console.ReadLine();
        }

        public static void createCloudServiceByLocation(string cloudServiceName, string location)
        {
            ComputeManagementClient client = new ComputeManagementClient(getCredentials());
            HostedServiceCreateParameters hostedServiceCreateParams = new HostedServiceCreateParameters
            {
                ServiceName = cloudServiceName,
                Location = location,
                Label = EncodeToBase64(cloudServiceName),
            };
            try
            {
                client.HostedServices.Create(hostedServiceCreateParams);
            }
            catch (CloudException e)
            {
                throw e;
            }

        }
        public static void createCloudServiceByAffinityGroup(string cloudServiceName, string affinityGroupName)
        {
            ComputeManagementClient client = new ComputeManagementClient(getCredentials());
            HostedServiceCreateParameters hostedServiceCreateParams = new HostedServiceCreateParameters
            {
                ServiceName = cloudServiceName,
                AffinityGroup = affinityGroupName,
                Label = EncodeToBase64(cloudServiceName),
            };
            try
            {
                client.HostedServices.Create(hostedServiceCreateParams);
            }
            catch (CloudException e)
            {
                throw e;
            }

        }
        public static string EncodeToBase64(string toEncode)
        {
            byte[] toEncodeAsBytes
            = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
            string returnValue
                  = System.Convert.ToBase64String(toEncodeAsBytes);
            return returnValue;
        }

        public static SubscriptionCloudCredentials getCredentials()
        {
            return new CertificateCloudCredentials(subscriptionId, new X509Certificate2(Convert.FromBase64String(base64EncodedCertificate)));
        }

    }
View Code
原文地址:https://www.cnblogs.com/he-yuan/p/3467075.html