Azure Lei Zhang的博客

weibo: LeiZhang的微博/QQ: 185165016/QQ群:319036205/邮箱:leizhang1984@outlook.com/TeL:139-161-22926

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  390 随笔 :: 0 文章 :: 394 评论 :: 0 引用

  《Windows Azure Platform 系列文章目录

  

  笔者之前遇到一个客户,需求是当发生某一个特定条件的时候,对多台Azure ARM VM执行开机或者关机操作,这个时候就需要使用Azure REST API。

  (当然也是可以使用Azure .NET SDK或者Java SDK,有兴趣的读者可以参考相关资料)

  

  在使用Azure REST API操作ARM VM的时候,需要有四个步骤:

  1.创建1个Azure Active Directory Application,设置Service Principal,设置Service Princial Permission,设置credential

  2.查看Azure ARM REST API支持的Virtual Machine API Version

  3.创建C# 代码,并设置Access Token

  4.C#调用REST API  

  

  有关ARM VM REST API,请参考:https://docs.microsoft.com/en-us/rest/api/compute/virtualmachines

 

  我们先开始第一部分:创建1个Azure Active Directory Application,设置Service Principal,设置Service Princial Permission,设置credential

  其实这个步骤可以通过现有的Azure PowerShell来执行,具体的PowerShell链接下载地址:

  https://github.com/leizhang1984/AzureChinaPowerShell/blob/master/ARM/4VSTStoAzureChina/RegisterVsts2AzureChina.txt 

  (1)我们先找到Azure ARM虚拟机所在的资源组名称,比如这里用YourAzureChinaResourceGroup

  (2)然后将上面的Azure PowerShell下载到本地D盘根目录,并且将扩展名重命名为ps1

  (3)安装Azure PowerShell,并执行下面的命令:

D:\RegisterVsts2Mooncake.ps1 -subscriptionName '[YourAzureChinaSubscriptionName]' -password '[YourPassword]' -resourceGroupName '[YourAzureChinaResourceGroup]'

  注意:第一个参数subscriptionName是订阅名称

  password是密码。注意这个密码不一定是AzureChina登录的密码,我们可以设置为其他的密码

  resourceGroupName是虚拟机所在的资源组名称

  (4)执行完毕后,如下图:

  

  把上面的Tenant ID记录下来

 

  (5)因为上面的PowerShell脚本,Key的过期时间是1年。如果我们的代码需要长期使用的话,需要设置过期时间。

  (6)我们登录Azure China Portal: https://portal.azure.cn

  (7)我们点击Azure Active Directory,应用注册,然后点击“查看所有应用程序”。如下图:

  

  (8)点击上图的"应用注册"后,会显示VSO开头的内容,我们选中该行:

  

  (9)选中Settings,然后点击Keys,在Passoword,创建1个新的Key Descriptions,同时Expires设置为Never Expires

  请注意:上面设置Passwords的时候,请先保存在记事本上,否则设置完毕后无法查看

  

  把上面的Client ID和Client Secret记录下来

 

 

  我们先开始第二部分:查看Azure ARM REST API支持的Virtual Machine API Version

  (1)运行Azure PowerShell,执行下面的脚本

Add-AzureRmAccount -Environment AzureChinaCloud

((Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Compute).ResourceTypes | Where-Object ResourceTypeName -eq virtualMachines).ApiVersions

  (2)可以查看支持的API Version

  

 

 

  然后执行第三部分:创建C#代码

  (1)我们先创建1个C# Windows Form Project

  (2)管理 NuGet包,增加Microsoft.IdentityModel.Clients.ActiveDirectory,如下图:

  

  (3)在Form1.cs增加引用:using Microsoft.IdentityModel.Clients.ActiveDirectory;

  (4)在Form1.cs增加如下代码:

        string _tenantId = "这里输入第一部分第4步的Tenant ID";
        string _clientId = "这里输入第一部分第9步的Client ID";
        string _clientSecret = "这里输入第一部分第9步的Client Secret";
        string _subscriptionId = "这里输入订阅ID";
        string _resourceGroupName = "这里输入资源组名称";
        AzureARMVMOperation armVMOperation;

        private void button1_Click(object sender, EventArgs e)
        {
            armVMOperation = new AzureARMVMOperation();

            armVMOperation.Authenticate(_tenantId, _clientId, _clientSecret);

            armVMOperation.StartARMVM(_tenantId, _clientId, _clientSecret, _subscriptionId, _resourceGroupName, "需要开机的ARM VM Name");
            armVMOperation.StartARMVM(_tenantId, _clientId, _clientSecret, _subscriptionId, _resourceGroupName, "需要开机的ARM VM Name");
        }

 

  (5)在Project中,增加AzureARMVMOperation.cs

  请注意下面的API Version参数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using Microsoft.IdentityModel.Clients.ActiveDirectory;

namespace AzureARMVM
{
    class AzureARMVMOperation
    {
        public AzureARMVMOperation()
        {

        }

        public string Authenticate(string TentantID, string ClientID, string ClientSecret)
        {
            try
            {
                string authContextURL = "https://login.chinacloudapi.cn/" + TentantID;
                var authenticationContext = new AuthenticationContext(authContextURL);
                var credential = new ClientCredential(ClientID, ClientSecret);
                var result = authenticationContext.AcquireTokenAsync(resource: "https://management.chinacloudapi.cn/", clientCredential: credential).Result;
                return result.AccessToken.ToString();
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        /// <summary>
        /// 开机操作
        /// </summary>
        /// <param name="TentantID"></param>
        /// <param name="ClientID"></param>
        /// <param name="ClientSecret"></param>
        /// <param name="SubscriptionId"></param>
        /// <param name="ResourceGroupName"></param>
        /// <param name="VMName"></param>
        public void StartARMVM(string TentantID, string ClientID, string ClientSecret, string SubscriptionId, string ResourceGroupName, string VMName)
        {
            string result = Authenticate(TentantID, ClientID, ClientSecret);
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + result);
                client.BaseAddress = new Uri("https://management.chinacloudapi.cn/");

                PostOperation(client, $"/subscriptions/{SubscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Compute/virtualMachines/{VMName}/start?api-version=2017-12-01");
            }
        }
        /// <summary>
        /// 关机操作
        /// </summary>
        /// <param name="TentantID"></param>
        /// <param name="ClientID"></param>
        /// <param name="ClientSecret"></param>
        /// <param name="SubscriptionId"></param>
        /// <param name="ResourceGroupName"></param>
        /// <param name="VMName"></param>
        public void StopARMVM(string TentantID, string ClientID, string ClientSecret, string SubscriptionId, string ResourceGroupName, string VMName)
        {
            string result = Authenticate(TentantID, ClientID, ClientSecret);
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + result);
                client.BaseAddress = new Uri("https://management.chinacloudapi.cn/");

                PostOperation(client, $"/subscriptions/{SubscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.Compute/virtualMachines/{VMName}/deallocate?api-version=2017-12-01");
            }
        }


        private void PostOperation(HttpClient client, string requestUri)
        {
            string data = "<someXml></someXml>";
            StringContent queryString = new StringContent(data);

            using (var response = client.PostAsync(requestUri, queryString).Result)
            {
                response.Content.ReadAsStringAsync();
            }
        }

    }
}

 

  然后我们执行Project,就可以测试和调试了。

 

  

posted on 2018-05-09 18:56 Lei Zhang的博客 阅读(...) 评论(...) 编辑 收藏