天天看點

利用Azure Rest API 建立虛拟機

在此之前,我曾經看過一篇文章講叙了如何利用Azure power shell team 提供的class library。

而就在這篇文章釋出之後不久,我又發現微軟釋出了一個preview 版本的Windows Azure Management Libraries For .NET Nuget package來幫助.NET 開發人員來更好的控制Auzre Platform。

相比power shell team使用的library, Windows Azure Management Libraries For .NET 将業務邏輯更好的劃分了開來,同時也使用了最新的Async programing來替代.net 4.5之前非常流行的異步委托程式設計方式。很明顯,這個class library今後将融入Azure SDK 之中,成為替代.NET 程式員直接調用Azure Management REST API的最佳選擇。

那麼就讓我們來了解一下如何使用這個libararies吧。

第一步:

    添加NuGet Package到項目中。如下圖

利用Azure Rest API 建立虛拟機

然後輸入如下指令安裝包:

Install-Package Microsoft.WindowsAzure.Management.Libraries -Pre

如果上面的安裝包的過程好了,包中的類庫便會被引入到項目中。

第二步:

    在完成第一步後,我們需要去官方檢視開發文檔(http://msdn.microsoft.com/en-us/library/ee460799.aspx),在Operation On Virtual Machine中點看

Create Virtual Machine Deployment項,進入該篇幅進行技術開發檢視,了解如何去調用類庫建立一個虛機的過程。

    下面圖檔是官方線上文檔截圖:

利用Azure Rest API 建立虛拟機

從這裡我們必須要有一個訂閱ID号,有了這個訂閱ID号之後,在建立虛拟機之前先要建立一個雲服務,用于部署這個虛機時使用。

如何建立雲服務跟上面的一樣簡單,查閱官方文檔,如下圖:

利用Azure Rest API 建立虛拟機

在這裡我就不再重複講解了,你們可以檢視官方文檔和技術案例。我接下來就直接上代碼好了。

第三步:

    App.config代碼

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <appSettings>
    <add key="ServiceManageBaseUrl" value="https://management.core.chinacloudapi.cn/" />
    <add key="SubscriptionID" value="your-Subscription-ID" />
   <add key="Thrumbprint" value="your-Thrumbprint-for-your-certification"/>
  </appSettings>
</configuration>      

這裡面有一點需要說明一下:根據你使用Windows Azure地區版本的不同上面的訂閱資訊會有所不同。比如說如果你使用的是國際版,那麼你的ServiceManageBaseUrl就是官方所提供的

https://management.core.windows.net/,因為我是用的是中國大陸世紀互聯營運代理商的賬号,是以我這裡就是https://management.core.chinacloudapi.cn/。對于為什麼要使用指紋,我們在接下來管理認證的時候講解。

Package.config代碼(在第一步安裝好,便會自動添加這些代碼)

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
  <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
  <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
  <package id="Microsoft.Net.Http" version="2.2.22" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Common" version="1.3.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Common.Dependencies" version="1.1.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.Compute" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.Libraries" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.MediaServices" version="2.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.Monitoring" version="1.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.Network" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.Scheduler" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.Sql" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.Storage" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.WebSites" version="3.0.0" targetFramework="net45" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
</packages>      

邏輯代碼實作:

using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Management.Compute;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Management.Compute.Models;
using System.Net;
namespace AzureTest
{
    class Program
    {
        private static String subscriptionID = ConfigurationManager.AppSettings["SubscriptionID"];
        private static String serviceManageBaseUrl = ConfigurationManager.AppSettings["ServiceManageBaseUrl"];
        private static String thrumbprint = ConfigurationManager.AppSettings["Thrumbprint"];
        //private static String managementCertificate = ConfigurationManager.AppSettings["ManagementCertificate"];
        private static ComputeManagementClient client = new ComputeManagementClient(getCredentials(), new Uri(serviceManageBaseUrl));
        
        static void Main(string[] args)
        {

            //從ComputeManagementDiscoveryExtensions中用CreateComputeManagementClient獲得一個
            //ComputeManagementClient computeManageClient = ComputeManagementDiscoveryExtensions.CreateComputeManagementClient();
            //getAllCloudServicesName();
            try
            {
                string serviceName = CreateCloudService("MikeService");
                createVM(serviceName);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            
            Console.ReadLine();
        }

        /// <summary>
        /// 獲得該訂閱下的所有雲服務名
        /// </summary>
        public static void getAllCloudServicesName()
        {
            var cloudServiceList = client.HostedServices.List();
            foreach (var cloudService in cloudServiceList)
            {
                Console.WriteLine(cloudService.ServiceName);
            }
        }

        /// <summary>
        /// 建立雲服務
        /// </summary>
        /// <param name="serviceName">雲服務名</param>
        /// <returns>雲服務名/Null</returns>
        private static string CreateCloudService(string serviceName)
        {
            try
            {


                HostedServiceCreateParameters parameters = new HostedServiceCreateParameters();
                parameters.ServiceName = serviceName;
                parameters.Location = "West China";
                parameters.Description = "這是一個用于部署虛拟機的雲服務";
                OperationResponse operationResponse = client.HostedServices.Create(parameters);
                if (operationResponse.StatusCode == HttpStatusCode.OK)
                {
                    return serviceName;
                }
                else
                    return null;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// 建立一個虛拟機
        /// </summary>
        /// <param name="serviceName">部署服務名</param>
        private static void createVM(string serviceName)
        {
            //虛機參數模型
            VirtualMachineCreateParameters  parameters = new VirtualMachineCreateParameters();

            parameters.RoleName = "MikeVirtualMachine";
            parameters.RoleSize = "Small";
            //計算機配置
            ConfigurationSet provisionItem = new ConfigurationSet(){
                ConfigurationSetType = ConfigurationSetTypes.WindowsProvisioningConfiguration,
                ComputerName = "Mike-PC",
                AdminUserName = "Mike",
                AdminPassword = "Password01!",
                EnableAutomaticUpdates = true,
                ResetPasswordOnFirstLogon = true
            };
            //網絡配置
            List<InputEndpoint> inputList = new List<InputEndpoint>();
            InputEndpoint endpoint = new InputEndpoint()
            {
                LocalPort = 3389,
                Name = "RemoteDesktop",
                Protocol = "tcp"
            };
            inputList.Add(endpoint);
            ConfigurationSet networkItem = new ConfigurationSet(){
                ConfigurationSetType = ConfigurationSetTypes.NetworkConfiguration,
                InputEndpoints = inputList
            };
            
            parameters.ConfigurationSets.Add(provisionItem);
            parameters.ConfigurationSets.Add(networkItem);

            //虛拟磁盤配置
            parameters.OSVirtualHardDisk.Name = "MikeVirtualMachine-0-20121007173943";
            parameters.OSVirtualHardDisk.MediaLink = new Uri("https://portalvhdsmz7vww0gb0p5k.blob.core.chinacloudapi.cn/vhds/MikeVirtualMachine.vhd");
            parameters.OSVirtualHardDisk.SourceImageName = "55bc2b193643443bb879a78bda516fc8__Windows-Server-2012-R2-201408.01-zh.cn-127GB.vhd";
            Task<OperationStatusResponse> responseTask = client.VirtualMachines.CreateAsync(serviceName,"MikeVirtalMachine",parameters,new System.Threading.CancellationToken());
            Console.WriteLine("響應資訊:/n" + responseTask.IsCompleted.ToString()
                );
        }
        //獲得證書
        private static SubscriptionCloudCredentials getCredentials()
        {
            return new CertificateCloudCredentials(subscriptionID, GetStoreCertificate(thrumbprint));
        }

        /// <summary>
        /// 從指紋獲驗證書
        /// </summary>
        /// <param name="thumbprint">指紋</param>
        /// <returns>用戶端證書</returns>
        private static X509Certificate2 GetStoreCertificate(string thumbprint)
        {
            List<StoreLocation> locations = new List<StoreLocation>
            { 
                StoreLocation.CurrentUser, 
                StoreLocation.LocalMachine
            };

            foreach (var location in locations)
            {
                X509Store store = new X509Store("My", location);
                try
                {
                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                    X509Certificate2Collection certificates = store.Certificates.Find(
                      X509FindType.FindByThumbprint, thumbprint, false);
                    if (certificates.Count == 1)
                    {
                        return certificates[0];
                    }
                }
                finally
                {
                    store.Close();
                }
            }
            throw new ArgumentException(string.Format(
              "A Certificate with Thumbprint '{0}' could not be located.",
              thumbprint));
        }
    }
}      

那麼這個簡單的類庫調用建立虛拟機和雲服務就做好了,是不是感覺很簡單了呢?不用再像Send Http Request那樣麻煩了,都是采用屬性和成員變量的方式對Http Request進行了封裝。習慣了面向對象程式設計的人來說,這給予了極大的友善,更多操作将會在以後的部落格中記錄下我日常Azure REST API工作和學習的遇到的問題和解決方案與大家分享。

總結:

    如果你沒有使用過Http Request的程式員,那麼使用這個也很容易上手,隻要下載下傳這個類庫,那麼你就可以根據代碼的提示查閱相關的資料就可以很快的入門和使用。我總結一下一個Http Request的過程。

    1.訂閱資訊進行認證管理:

private static ComputeManagementClient client = new ComputeManagementClient(getCredentials(), new Uri(serviceManageBaseUrl));      

    通過指紋查找到用戶端管理證書:

/// <summary>
        /// 從指紋獲驗證書
        /// </summary>
        /// <param name="thumbprint">指紋</param>
        /// <returns>用戶端證書</returns>
        private static X509Certificate2 GetStoreCertificate(string thumbprint)
        {
            List<StoreLocation> locations = new List<StoreLocation>
            { 
                StoreLocation.CurrentUser, 
                StoreLocation.LocalMachine
            };

            foreach (var location in locations)
            {
                X509Store store = new X509Store("My", location);
                try
                {
                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                    X509Certificate2Collection certificates = store.Certificates.Find(
                      X509FindType.FindByThumbprint, thumbprint, false);
                    if (certificates.Count == 1)
                    {
                        return certificates[0];
                    }
                }
                finally
                {
                    store.Close();
                }
            }
            throw new ArgumentException(string.Format(
              "A Certificate with Thumbprint '{0}' could not be located.",
              thumbprint));
        }      

類庫中封裝的方法:将訂閱号和管理證書關聯綁定

//獲得證書
        private static SubscriptionCloudCredentials getCredentials()
        {
            return new CertificateCloudCredentials(subscriptionID, GetStoreCertificate(thrumbprint));
        }      

繼續閱讀