windows Azure 虚拟机接口调用示例

最近在windows Azure上做一个项目,需要动态管理虚拟机。在实际开发的时候发现网上的资料还是很少的,下面把自己用到的一些共享出来

AzureHelpter.cs :
  public class AzureHelpter
    {
        private string subscriptionID;
        private string cloudServiceName;
        private string storageAccountName;
        private string certThumb;
        private string depName;//vm depname
        private string role;//vm name
        private string disk;//vm disk 
        private string medialink;//vm medialink
        private string accont;
        private string computerName;
        private string acccont;
        private string requestId;

        public AzureHelpter(string accont)
        {
            this.acccont = accont;
            var userInfo = new EntityControl().Session.QueryOver<Cloud_UserInfo>()
                                .Where(m => m.Cloud_UserAccont == accont)
                                .SingleOrDefault<Cloud_UserInfo>();
            if (userInfo == null)
                throw new Exception(string.Format("未能获取{0}的用户信息", accont));

            var serviceInfo = new EntityControl().Session.QueryOver<Cloud_ServiceInfo>()
                               .Where(m => m.Cloud_ServiceAccont == accont)
                               .SingleOrDefault<Cloud_ServiceInfo>();
            if (serviceInfo == null)
                throw new Exception(string.Format("未能获取{0}的用户服务信息", accont));

            this.accont = accont;
            subscriptionID = Config.GetConifgValue("subscriptionID", "");
            storageAccountName = Config.GetConifgValue("storageAccountName", "");
            certThumb = Config.GetConifgValue("certThumb", "");
            cloudServiceName = "EDoc2Service" + userInfo.Cloud_UserCompanyShortName;
            depName = "EDoc2Dep" + userInfo.Cloud_UserCompanyShortName;
            role = "EDoc2Role" + userInfo.Cloud_UserCompanyShortName;
            disk = "EDoc2Disk" + userInfo.Cloud_UserCompanyShortName;
            medialink = "EDoc2Medialink" + userInfo.Cloud_UserCompanyShortName;
            computerName = "Edoc2" + userInfo.Cloud_UserCompanyShortName;
            requestId = serviceInfo.Cloud_VmRequestId;
        }

        /// <summary>
        /// 创建云服务 约束:云服务名=EDoc2Service+accont 只能是英文和数字.长度也不要太长
        /// </summary>
        /// <returns></returns>
        public bool CreateSevice()
        {
            var requestId = "";
            var result = new MgmtHelper().Request(out requestId, string.Format("https://management.core.windows.net/{0}/services/hostedservices",
                                                  subscriptionID),
                                              "application/xml",
                                              "2010-10-28",
                                              ReadConfig("CreateCS.xml"),
                                              certThumb);
            LogHelper.Instance.WriteFileLog(ErrorLevel.Little, string.Format("尝试创建云服务{0}:返回{1}", role, result));
            var createResult = result.IndexOf("Created") >= 0;
            return createResult;
        }

        /// <summary>
        /// 创建虚拟机
        /// </summary>out string requestId
        /// <returns></returns>
        public bool CreateVmFromImg(out string requestId)
        {
            var xml = ReadConfig("CreateFromImage.xml");
            var pswd = MakeRandomPassword("NUMCHAR", 9);
            xml = xml.Replace("{EdocPswd}", "Edoc21234");
            var result = new MgmtHelper().Request(out requestId, string.Format("https://management.core.windows.net/{0}/services/hostedservices/{1}/deployments",
                                                subscriptionID,
                                                cloudServiceName),
                                            "application/xml",
                                            "2012-03-01",
                                            xml,
                                            certThumb);
            LogHelper.Instance.WriteFileLog(ErrorLevel.Little, string.Format("尝试创建虚拟机{0}:返回{1}", role, result));
            var createResult = result.IndexOf("Accepted") >= 0;
            if (createResult == true)
            {
                var serviceInfo = new EntityControl().Session.QueryOver<Cloud_ServiceInfo>()
                                               .Where(m => m.Cloud_ServiceAccont == accont)
                                               .SingleOrDefault<Cloud_ServiceInfo>();
                if (serviceInfo == null)
                {
                    LogHelper.Instance.WriteFileLog(ErrorLevel.Little, string.Format("未能获取到账号{0}的服务信息", role));
                    return false;
                }
                serviceInfo.Cloud_ServiceAzurePassword = pswd;
                new EntityControl().UpdateEntity(serviceInfo);
            }
            return createResult;
        }
        /// <summary>
        /// 关闭虚拟机
        /// </summary>
        /// <returns></returns>
        public bool ShutDownVM()
        {
            var requestId = "";
            string url = string.Format(
             "https://management.core.windows.net/{0}/services/hostedservices/{1}/deployments/{2}/roleinstances/{3}/Operations"
             , subscriptionID
             , cloudServiceName
             , depName
             , role);
            var result = new MgmtHelper().Request(out requestId, url,
                                               "application/xml",
                                               " 2012-03-01",
                                               ReadConfig("Shutdown.xml"),
                                               certThumb);
            LogHelper.Instance.WriteFileLog(ErrorLevel.Little, string.Format("尝试关闭虚拟机{0}:返回{1}", role, result));
            return result.IndexOf("Accepted") >= 0;
        }

        /// <summary>
        /// 获去虚拟机运行状态 (约定原则)  Started/Stopped/Starting  目前已知的状态
        /// </summary>
        /// <returns></returns>
        public string GetVmPowerState()
        {
            var requestId = "";
            string url = string.Format("https://management.core.windows.net/{0}/services/hostedservices/{1}/deployments/{2}",
                                       subscriptionID,
                                       cloudServiceName,
                                       depName);
            var result = new MgmtHelper().Request(out requestId, url,
                                    null,
                                    "2012-03-01",
                                    null,
                                    certThumb,
                                    "GET");
            if (result.IndexOf("RoleInstance") >= 0)//存在vm实例
            {
                try
                {
                    var regGlass = new Regex("<PowerState>(?<data>.*?)</PowerState>", RegexOptions.Singleline);
                    var returnValue = regGlass.Match(result).Result("${data}"); //虚拟机的运行状态 Started Stopped
                   // LogHelper.Instance.WriteFileLog(ErrorLevel.Little, string.Format("尝试获取Deployment信息{0}:返回{1}", cloudServiceName, returnValue));
                    return returnValue;
                }
                catch (Exception ex)
                {
                    LogHelper.Instance.WriteFileLog(ErrorLevel.Little, string.Format("尝试获取Deployment信息{0}:异常了:{1}", cloudServiceName, ex.ToString()));
                    return "-";
                }
            }
            return "-";//状态不明
        }


        /// <summary>
        /// 修改虚拟机
        /// </summary>
        /// <returns></returns>
        public bool StartVm()
        {
            var requestId = "";
            string url = string.Format(
                          "https://management.core.windows.net/{0}/services/hostedservices/{1}/deployments/{2}/roleinstances/{3}/Operations"
                          , subscriptionID
                          , cloudServiceName
                          , depName
                          , role);
            var result = new MgmtHelper().Request(out requestId,
                                                 url,
                                               "application/xml",
                                               "2012-03-01",
                                               ReadConfig("StartRole.xml"),
                                               certThumb);
            LogHelper.Instance.WriteFileLog(ErrorLevel.Little, string.Format("尝试启动虚拟机{0}:返回{1}", role, result));
            return result.IndexOf("Accepted") >= 0;
        }

        private string ReadConfig(string filename)
        {
            var tempPath = AppDomain.CurrentDomain.BaseDirectory;
            if (tempPath.Contains("ConsoleServer"))
            {
                tempPath = Path.Combine(tempPath.Substring(0, tempPath.LastIndexOf("EDoc2.ConsoleServer")), "cfg\\" + filename);
            }
            else
            {
                tempPath = Path.Combine(tempPath.Substring(0, tempPath.LastIndexOf("Edoc.Cloud")), "cfg\\" + filename);
            }
            using (var sr = new StreamReader(tempPath))
            {
                return sr.ReadToEnd().Replace("{STORAGE}", storageAccountName)
                    .Replace("{CSName}", cloudServiceName)
                    .Replace("{EDoc2Dep}", depName)
                    .Replace("{EDoc2Role}", role)
                    .Replace("{EDoc2Disk}", disk)
                    .Replace("{EDoc2Medialink}", medialink)
                    .Replace("{EDoc2ComputerName}", computerName)
                    .Replace("{LABEL}",
                            Convert.ToBase64String(
                                Encoding.ASCII.GetBytes(
                                    String.Format("label{0}", DateTime.Now.ToString("yyyyMMddHHmmss")))));
            }
        }

        /// <summary>
        /// 生成各类随机密码,包括纯字母,纯数字,带特殊字符等,除非字母大写密码类型,其余方式都将采用小写密码 ,至少符合Edoc21234
        /// </summary>
        /// <param name="pwdType">密码类型 大写为"UPPER",小写为"LOWER",数字为"NUMBER",字母与数字为"NUMCHAR",数字字母字符都包括为"ALL" </param>
        /// <param name="length">密码长度,最小为6位</param>
        /// <returns></returns>
        private static string MakeRandomPassword(string pwdType, int length)
        {
            //定义密码字符的范围,小写,大写字母,数字以及特殊字符
            var lowerChars = "abcdefghijklmnopqrstuvwxyz";
            var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            var numnberChars = "0123456789";
            var specialCahrs = "~!@#$%^&*()_+|-=,./[]{}:;':";   //"\" 转义字符不添加 "号不添加

            var tmpStr = "";

            int iRandNum;
            var rnd = new Random();

            length = (length < 6) ? 6 : length; //密码长度必须大于6,否则自动取6

            // LOWER为小写 UPPER为大写 NUMBER为数字 NUMCHAR为数字和字母 ALL全部包含 五种方式
            //只有当选择UPPER才会有大写字母产生,其余方式中的字母都为小写,避免有些时候字母不区分大小写
            if (pwdType == "LOWER")
            {
                for (int i = 0; i < length; i++)
                {
                    iRandNum = rnd.Next(lowerChars.Length);
                    tmpStr += lowerChars[iRandNum];
                }
            }
            else if (pwdType == "UPPER")
            {
                for (int i = 0; i < length; i++)
                {
                    iRandNum = rnd.Next(upperChars.Length);
                    tmpStr += upperChars[iRandNum];
                }
            }
            else if (pwdType == "NUMBER")
            {
                for (int i = 0; i < length; i++)
                {
                    iRandNum = rnd.Next(numnberChars.Length);
                    tmpStr += numnberChars[iRandNum];
                }
            }
            else if (pwdType == "NUMCHAR")
            {
                int numLength = rnd.Next(length);
                //去掉随机数为0的情况
                if (numLength == 0)
                {
                    numLength = 1;
                }
                int charLength = length - numLength;
                string rndStr = "";
                for (int i = 0; i < numLength; i++)
                {
                    iRandNum = rnd.Next(numnberChars.Length);
                    tmpStr += numnberChars[iRandNum];
                }
                for (int i = 0; i < charLength; i++)
                {
                    iRandNum = rnd.Next(lowerChars.Length);
                    tmpStr += lowerChars[iRandNum];
                }
                //将取得的字符串随机打乱
                for (int i = 0; i < length; i++)
                {
                    int n = rnd.Next(tmpStr.Length);
                    //去除n随机为0的情况
                    //n = (n == 0) ? 1 : n;
                    rndStr += tmpStr[n];
                    tmpStr = tmpStr.Remove(n, 1);
                }
                tmpStr = rndStr;
            }
            else if (pwdType == "ALL")
            {
                int numLength = rnd.Next(length - 1);
                //去掉随机数为0的情况
                if (numLength == 0)
                {
                    numLength = 1;
                }
                int charLength = rnd.Next(length - numLength);
                if (charLength == 0)
                {
                    charLength = 1;
                }
                int specCharLength = length - numLength - charLength;
                string rndStr = "";
                for (int i = 0; i < numLength; i++)
                {
                    iRandNum = rnd.Next(numnberChars.Length);
                    tmpStr += numnberChars[iRandNum];
                }
                for (int i = 0; i < charLength; i++)
                {
                    iRandNum = rnd.Next(lowerChars.Length);
                    tmpStr += lowerChars[iRandNum];
                }
                for (int i = 0; i < specCharLength; i++)
                {
                    iRandNum = rnd.Next(specialCahrs.Length);
                    tmpStr += specialCahrs[iRandNum];
                }
                //将取得的字符串随机打乱
                for (int i = 0; i < length; i++)
                {
                    int n = rnd.Next(tmpStr.Length);
                    //去除n随机为0的情况
                    //n = (n == 0) ? 1 : n;
                    rndStr += tmpStr[n];
                    tmpStr = tmpStr.Remove(n, 1);
                }
                tmpStr = rndStr;
            }
            //默认将返回数字类型的密码
            else
            {
                for (int i = 0; i < length; i++)
                {
                    iRandNum = rnd.Next(numnberChars.Length);
                    tmpStr += numnberChars[iRandNum];
                }
            }
            return tmpStr;
        }

        /// <summary>
        /// 获取vm的当前状态(非电源状态)
        /// </summary>
        public string GetOperationStatus()
        {
            string url = string.Format("https://management.core.windows.net/{0}/operations/{1}",
                                      subscriptionID,
                                      requestId);
            var result = new MgmtHelper().Request(
                                    out requestId,
                                    url,
                                    null,
                                    "2012-03-01",
                                    null,
                                    "",
                                    "GET");
            return result;
        }

    }
MgmtHelper.cs :
 internal class MgmtHelper
    {
        private static X509Certificate2 GetX509Certificate(string certThumb)
        {
            X509Certificate2 certificate2 = null;
            var store = new X509Store("MY", StoreLocation.CurrentUser);
            store.Open(OpenFlags.OpenExistingOnly);
            var fcollection = store.Certificates.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
            store.Close();
            if (fcollection.Count > 0)
            {
                var enu = fcollection.GetEnumerator();
                while (enu.MoveNext())
                {
                    var variable = enu.Current;
                    if ((variable != null && variable.Thumbprint != null) && variable.Thumbprint.Equals(certThumb, StringComparison.InvariantCultureIgnoreCase))
                    {
                        certificate2 = variable;
                        break;
                    }
                }
            }
            return certificate2;
        }

        /// <summary>
        /// 直接入读取c根目录的证书
        /// </summary>
        /// <returns></returns>
        private static X509Certificate2 GetX509Certificate()
        {
            return new X509Certificate2("C:\\EDoc2AzureTest.cer", "123456");
        }

        internal string Request(out string requestId, string url, string contentType, string xmsversion, string config, string certThumb, string method = "POST")
        {
            var myReq = (HttpWebRequest)WebRequest.Create(
                                      url);
            myReq.Method = method;
            myReq.Headers.Add("x-ms-version", xmsversion);//"2012-03-01"
            myReq.Proxy = null;
            myReq.Timeout = 30 * 1000;//30秒
            if (!string.IsNullOrEmpty(contentType))
            {
                myReq.ContentType = contentType;
            }
            else
            {
                myReq.ContentLength = 0;
            }
            if (!string.IsNullOrEmpty(config))
            {
                string postData = config;
                using (Stream reqStream = myReq.GetRequestStream())
                {
                    using (var sw = new System.IO.StreamWriter(reqStream))
                    {
                        sw.Write(postData);
                        sw.Flush();
                    }
                }
            }
            //myReq.ClientCertificates.Add(GetX509Certificate(certThumb));
            myReq.ClientCertificates.Add(GetX509Certificate());
            try
            {
                var myRes = (HttpWebResponse)myReq.GetResponse();
                var code = myRes.StatusCode;
                requestId = myRes.Headers["x-ms-request-id"];
                using (var sr = new StreamReader(myRes.GetResponseStream()))
                {
                    var result = sr.ReadToEnd();
                    if (string.IsNullOrEmpty(result) == false)
                        return result;
                    else return string.Format("<Result>{0}</Result>", code);
                }

            }
            catch (WebException exWeb)
            {
                Stream responseStream = exWeb.Response.GetResponseStream();
                var reader = new StreamReader(responseStream);
                var xDocResp = new XmlDocument();
                xDocResp.Load(reader);
                var responseStatus = (HttpWebResponse)exWeb.Response;
                if (responseStream != null) responseStream.Close();
                reader.Close();
                var result = NiceFormatXml(xDocResp);
                requestId = "";
                return result;
            }
        }
        private string NiceFormatXml(XmlDocument xDoc)
        {
            var niceString = new StringBuilder();
            var strWriter = new StringWriter(niceString);
            var xmlWriter = new XmlTextWriter(strWriter);
            xmlWriter.Formatting = Formatting.Indented;
            xDoc.WriteTo(xmlWriter);
            xmlWriter.Close();
            strWriter.Close();
            return niceString.ToString();
        }
    }


CreateCS.xml:

<?xml version="1.0" encoding="utf-8"?>
<CreateHostedService xmlns="http://schemas.microsoft.com/windowsazure">
  <ServiceName>{CSName}</ServiceName>
  <Label>{LABEL}</Label>
  <Location>East Asia</Location>

</CreateHostedService>

CreateFromImage.xml:

<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Name>{EDoc2Dep}</Name>
  <DeploymentSlot>Production</DeploymentSlot>
  <Label>labelofdepd</Label>
  <RoleList>
    <Role>
      <RoleName>{EDoc2Role}</RoleName>
      <RoleType>PersistentVMRole</RoleType>
      <ConfigurationSets>
        <ConfigurationSet>
          <ConfigurationSetType>WindowsProvisioningConfiguration</ConfigurationSetType>
          <ComputerName>{EDoc2ComputerName}</ComputerName>
          <AdminPassword>{EdocPswd}</AdminPassword>

          <EnableAutomaticUpdates>false</EnableAutomaticUpdates>
        </ConfigurationSet>

        <ConfigurationSet>
          <ConfigurationSetType>NetworkConfiguration</ConfigurationSetType>

          <InputEndpoints>
            <InputEndpoint>
              <LocalPort>3389</LocalPort>
              <Name>RDP</Name>
              <Port>38983</Port>
              <Protocol>tcp</Protocol>
            </InputEndpoint>
            <InputEndpoint>
              <LocalPort>80</LocalPort>
              <Name>WEB</Name>
              <Port>80</Port>
              <Protocol>tcp</Protocol>
            </InputEndpoint>
          </InputEndpoints>

        </ConfigurationSet>
      </ConfigurationSets>
      <AvailabilitySetName></AvailabilitySetName>
      <OSVirtualHardDisk>
        <HostCaching>ReadWrite</HostCaching>
        <DiskName>{EDoc2Disk}</DiskName>
          <MediaLink>http://{STORAGE}.blob.core.windows.net/vhds/bjer5mun.{EDoc2Medialink}.vhd</MediaLink>
          <SourceImageName>img14</SourceImageName>
      </OSVirtualHardDisk>
      <RoleSize>Medium</RoleSize>
    </Role>
  </RoleList>
</Deployment>

Edoc2Cloud.xml :

<Deployment xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <Name>nameofcode5</Name>
    <DeploymentSlot>Production</DeploymentSlot>
    <Label>labelofdepa</Label>
    <RoleList>
        <Role>
            <RoleName>rolecode5</RoleName>
            <RoleType>PersistentVMRole</RoleType>
            <ConfigurationSets>
                <ConfigurationSet>
                    <ConfigurationSetType>WindowsProvisioningConfiguration</ConfigurationSetType>
                    <ComputerName>Edoc2</ComputerName>
                    <AdminPassword>Edoc21234</AdminPassword>
                    <EnableAutomaticUpdates>false</EnableAutomaticUpdates>
                </ConfigurationSet>

                <ConfigurationSet>
                    <ConfigurationSetType>NetworkConfiguration</ConfigurationSetType>

                    <InputEndpoints>
                        <InputEndpoint>
                            <LocalPort>3389</LocalPort>
                            <Name>RDP</Name>
                            <Port>38983</Port>
                            <Protocol>tcp</Protocol>
                        </InputEndpoint>
                        <InputEndpoint>
                            <LocalPort>80</LocalPort>
                            <Name>web</Name>
                            <Port>80</Port>
                            <Protocol>tcp</Protocol>
                        </InputEndpoint>
                    </InputEndpoints>

                </ConfigurationSet>
            </ConfigurationSets>
            <AvailabilitySetName></AvailabilitySetName>
            <OSVirtualHardDisk>
                <HostCaching>ReadWrite</HostCaching>
                <DiskName>diskcode5</DiskName>
                <MediaLink>https://{STORAGE}.blob.core.windows.net/vhds/testBTSa.vhd</MediaLink>
                <SourceImageName>2cdc6229df6344129ee553dd3499f0d3__BizTalk-Server-2013-Standard</SourceImageName>
            </OSVirtualHardDisk>
            <RoleSize>Medium</RoleSize>
        </Role>
    </RoleList>
</Deployment>

Shutdown.xml :

<ShutdownRoleOperation xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <OperationType>ShutdownRoleOperation</OperationType>
</ShutdownRoleOperation>

StartRole.xml :

<StartRoleOperation xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <OperationType>StartRoleOperation</OperationType>
</StartRoleOperation>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值