Share via


Windows Azure Management Libraries - управление облачной инфраструктурой из .NET-приложений

В этой статье дается описание библиотек Windows Azure Management Libraries, выпущенных недавно и предназначенных для управления из .NET-приложений облачной инфраструктурой, сервисами и элементами хранилища размещенными в Windows Azure. Описание возможностей библиотек дается на примерах кода WPF-приложения.

Что такое Windows Azure Management Libraries?

С выпуском библиотек Windows Azure Management Libraries широкая часть облачной инфраструктуры Windows Azure может быть доступна и автоматизирована из приложений на .NET. Эти библиотеки работают поверх функций открытого REST API платформы и их выпуск предназначен для облегчения работы разработчика с облачной инфраструктурой.
Превью библиотек доступное сегодня, включает в себя поддержку облачных сервисов (Cloud Services), виртуальных машин и сетей, веб-сайтов (Web Sites), учетных записей хранилищ и таких инфраструктурных элементов как группы доступности (Affinity Groups).

Мы потратили много времени на проектирование естественного .NET Framework API, который прозрачно представляет собой лежащий ниже открытый REST API. Для нас было очень важным представить эти сервисы с помощью современных знакомых разработчикам подходов используемых на платформе .NET:

  • поддержка Portable Class Library (PCL) для .NET Framework 4.5, Windows Phone 8, Windows Store и Silverlight;
  • распространение в виде пакетов NuGet с минимумом зависимостей для облегчения версионности;
  • поддержка асинхронности и асинхронных операций на основе элементов платформы async/await (с легкой возможностью реализовать синхронные перегруженные методы);
  • наличие общей инфраструктуры для единой обработки ошибок, трассировки, конфигурации и управления пайплайном HTTP;
  • спроектировано для легкости тестирования и использования мокинга (mocking);
  • построено на базе популярных библиотек, таких как HttpClient и Json.NET.

Эти пакеты открывают перед вами богатые возможности и простоту управления, автоматизации, развертывания и тестирования облачной инфраструктуры WIndows Azure. С помощью них вы сможете управлять виртуальными машинами, облачными сервисами, виртуальными сетями, веб-сайтами и ключевыми инфраструктурными компонентами платформы.

Начало работы

Как и с любым другим SDK, для того, чтобы узнать как нам с ним работать лучше всего изучить немного кода. Ни один код не должен быть написал для решения проблемы, которой на самом деле не существует, так что давайте сначала сформулируем, какую проблему решают библиотеки Windows Azure Management Libraries:

У меня есть процесс, который я запускаю в Windows Azure в виде рабочей роли (Worker Role). Все работает замечательно, однако этот процесс, в действительности, необходимо запускать только несколько раз в неделю. Было бы замечательно иметь возможность завести новый сервис, разместить в него мой код и затем запустить его выполнение. Совсем хорошо было бы, если после выполнения сервиса, код сообщил об этом назад, так что мы могли бы удалить его автоматически. Порой, я забываю выключить этот сервис вручную, так что у меня могут быть лишние траты, когда он остается включенным после выполнения кода. Было бы замечательно иметь возможность автоматизировать создание необходимой мне инфраструктуры, ее запуск и последующее самоуничтожение.

До появления в свет библиотек Windows Azure Management Libraries (сокращенно, хоть и не официально, – WAML) решение описанной проблемы было непростой задачей. Правда, уже существует ряд отличных opensource-библиотек от сообщества, которые предлагают .NET-прослойку для управления сервисами Windows Azure, однако, ни одна из них не имеет полноты реализации функций Windows Azure Management REST API или полноценной реализации возможностей C#. При создании собственного слоя для управления мощностями облака Windows Azure вам обязательно придется написать свой собственный HTTP/XML-код для обмена запросами с REST API. Это не самое интересное, чем можно заняться в жизни. Занудная и скучная работа, особенно после того, как вы реализуете свою вторую дюжину из сотен методов API.

Установка библиотек Management Libraries

Я решил реализовать задачу в виде простого WPF-приложения, которое будет запускаться на моем рабочем столе. Так как у меня будет облачный сервис с рабочей ролью запущенные в облаке, я объединил все три проекта в единое решение, которое вы можете увидеть ниже: 

a123

Вероятно, вы обратили внимание на то, что я приготовился добавить несколько NuGet-пакетов в мое приложение. Это связано с тем, что Windows Azure Management Libraries распространяются в виде отдельных NuGet-пакетов. Я собираюсь выбрать пакет Microsoft.WindowsAzure.Management.Libraries и он один установит все доступные в Management Libraries библиотеки. Если мне захочется управлять только одним из аспектов Windows Azure, то вместо того, чтобы добавлять все библиотеки, я могу установить только один специфический пакет, например, Microsoft.WindowsAzure.Management.WebSites, который предлагает функциональность для управления только инфраструктурой Windows Azure Web Sites.

a124

После добавления ссылки на пакет, у меня есть все необходимое для настройки клиентской аутентификации между моим WPF-приложением и Windows Azure REST API.

Клиентская аутентификация

Первая реализация аутентификации пользователей, которую мы написали для WAML и Windows Azure, была основана на механизме X509-сертификатов. Недавно в пакете Windows Azure for .NET SDK 2.2, Visual Studio и для PowerShell была добавлена встроенная аутентификация на основе учетных записей. В настоящее время мы работаем над ее поддержкой в WAML. Доступный на сегодня выпуск WAML поддерживает аутентификацию только на основе сертификатов, однако, следите за новостями, мы работаем над тем, чтобы добавить в библиотеку поддержку аутентификации на базе учетных записей.
Я не буду заострять наше внимание на обсуждении использования аутентификации на основе сертификатов. Наоборот, я намерен как можно быстрее перейти к обсуждению функциональных вещей в нашей статье. Мне потребуется информация всего о двух элементах для подключения к Windows Azure REST API:

  • Идентификатор подписки (Subscription ID);
  • Сертификат управления (Management Certificate).

Я получил эти значения из одного из моих файлов с настройками публикации (publish settings files). Ниже вы можете увидеть XML- содержимое такого файла:

a125

Используя ключ и идентификатор подписки далее в моем коде, я могу вызваю метод GetCredentials, который возвращает экземпляр абстрактного класса SubscriptionCloudCredentials, который мы используем в коде библиотеки Management Library для представления данных о параметрах пользовательского доступа. С таким подходом, если я захочу в будущем добавить аутентификацию на основе учетных записей, то мне будет гораздо проще заменить механизм аутентификации. Код класса CertificateAuthenticationHelper из моего примера указан ниже:

using Microsoft.WindowsAzure;
using System;
using System.Security.Cryptography.X509Certificates;
 
namespace MyCloudServiceManager
{
     internal class CertificateAuthenticationHelper
     {
         internal static SubscriptionCloudCredentials GetCredentials(
            string subscrtionId,
             string base64EncodedCert)
         {
             return new CertificateCloudCredentials(subscrtionId,
                 new X509Certificate2(Convert.FromBase64String(base64EncodedCert)));
         }
     }
}

Теперь, я напишу класс контроллера, который будет осуществлять работу по взаимодействию между WPF-приложением и библиотеками Management Libraries. 

Слой управления

Для того, чтобы учесть все возможные параметры, которые будут использоваться в моем сервисе, я создал класс ManagementControllerParameters. Это класс содержит все данные, которые мне понадобятся для создания сервисов и размещения в облаке моего кода.

namespace MyCloudServiceManager
{
     internal class ManagementControllerParameters
     {
         internal string Region { get; set; }
         internal string StorageAccountName { get; set; }
         internal string CloudServiceName { get; set; }
         internal string PackageFilePath { get; set; }
         internal string ConfigurationFilePath { get; set; }
         public string SubscriptionId { get; set; }
         public string Base64EncodedCertificate { get; set; }
     }
}

Затем я создал класс, который содержит удобную функциональность по взаимодействию между пользовательским интерфейсом и слоем библиотек Management Library. Этот класс создан для более чистого кода в слое UX в дальнейшем. Обратите внимание на код конструктора. В нем создаются два клиента. Первый, StorageManagementClient предназначен для управления учетными записями хранилища. Второй ComputeManagementClient предлагает возможность работы с вычислительными мощностями Windows Azure – облачными службами и виртуальными машинами, их расположениям и так далее.

В целях разделения кода между файлами на разные функциональные части я создал partial-класс ManagementController, код которого доступен вам в публичном Gist, так что вы можете использовать его в своих собственных проектах.

using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Management.Compute;
using Microsoft.WindowsAzure.Management.Storage;
using System;
 
namespace MyCloudServiceManager
{
     internal partial class ManagementController : IDisposable
     {
         private StorageManagementClient _storageManagementClient;
         private ManagementControllerParameters _parameters;
         private ComputeManagementClient _computeManagementClient;
 
         internal ManagementController(ManagementControllerParameters parameters)
         {
             _parameters = parameters;
 
             var credential = CertificateAuthenticationHelper.GetCredentials(
                 parameters.SubscriptionId,
                 parameters.Base64EncodedCertificate);
 
             _storageManagementClient = CloudContext.Clients.CreateStorageManagementClient(credential);
             _computeManagementClient = CloudContext.Clients.CreateComputeManagementClient(credential);
         }
 
         public void Dispose()
         {
             if (_storageManagementClient != null)
                 _storageManagementClient.Dispose();
             if (_computeManagementClient != null)
                 _computeManagementClient.Dispose();
         }
     }
}

Теперь, давайте создадим несколько клиентов для управления облаком и сделаем кое-какую работу.

Создание новой учетной записи хранилища

Первое, что нам нужно для реализации стратегии нашего сервиса – это учетная запись хранилища. Сервис будет использовать файл пакета .cspkg созданный в Visual Studio на базе проекта облачной службы. Его необходимо разместить в виде блоба в хранилище Windows Azure. Перед тем, как я смогу это сделать, мне необходимо создать учетную запись, в хранилище которой может быть загружен файл пакета. Код ниже предназначен для того, чтобы создать учетную запись хранилища в указанном регионе:

using Microsoft.WindowsAzure.Management.Storage;
using Microsoft.WindowsAzure.Management.Storage.Models;
using System.Threading.Tasks;
 
namespace MyCloudServiceManager
{
     internal partial class ManagementController
     {
         internal async Task CreateStorageAccount()
         {
             await _storageManagementClient.StorageAccounts.CreateAsync(
                 new StorageAccountCreateParameters
                 {
                     Location = _parameters.Region,
                     ServiceName = _parameters.StorageAccountName
                 });
         }
     }
}

После того, как учетная запись хранилища будет создана, я смогу ее использовать. Мне необходима строка подключения для подключения моего приложения (и моего «вскоре-будет-создан» облачного сервиса) к хранилищу. Я написал метод, который отвечает за получение ключей подключения к хранилищу Windows Azure через REST API. Затем, я формирую строку подключения и возвращаю ее в вызывающий код.

using Microsoft.WindowsAzure.Management.Storage;
using System.Globalization;
using System.Threading.Tasks;
 
namespace MyCloudServiceManager
{
     internal partial class ManagementController
     {
         private async Task<string> GetStorageAccountConnectionString()
         {
             var keys = await _storageManagementClient.StorageAccounts.GetKeysAsync(_parameters.StorageAccountName);
 
             string connectionString = string.Format(
                 CultureInfo.InvariantCulture,
                 "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
                 _parameters.StorageAccountName, keys.SecondaryKey);
 
             return connectionString;
         }
     }
}

Теперь, после создания учетной записи хранилища, я могу создать облачный сервис и опубликовать мой пакет в Windows Azure.

Создание и размещение нового облачного сервиса

Код необходимый для облачного сервиса удивительно прост. Все что нам нужно – это указать название сервиса и регион, в котором он должен быть создан.

using Microsoft.WindowsAzure.Management.Compute;
using Microsoft.WindowsAzure.Management.Compute.Models;
using System.Threading.Tasks;
 
namespace MyCloudServiceManager
{
     internal partial class ManagementController
     {
         internal async Task CreateCloudService()
         {
             await _computeManagementClient.HostedServices.CreateAsync(new HostedServiceCreateParameters
             {
                 Location = _parameters.Region,
                 ServiceName = _parameters.CloudServiceName
             });
         }
     }
}

Наконец, все что мне остается для размещения облачного сервиса – это загрузить файл пакета сервиса созданного в Visual Studio в блоб, а затем вызвать REST API. Этот вызов будет состоять из адреса блоба, в котором расположен пакет и XML-данных полученных из конфигурационного файла облачного проекта. Этот код использует библиотеку Windows Azure Storage SDK, которая доступна в виде NuGet-пакета.

using Microsoft.WindowsAzure.Management.Compute;
using Microsoft.WindowsAzure.Management.Compute.Models;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System.IO;
using System.Threading.Tasks;
 
namespace MyCloudServiceManager
{
     internal partial class ManagementController
     {
         internal async Task DeployCloudService()
         {
             var storageConnectionString = await GetStorageAccountConnectionString();
 
             var account = CloudStorageAccount.Parse(storageConnectionString);
 
             var blobs = account.CreateCloudBlobClient();
 
             var container = blobs.GetContainerReference("deployments");
 
             await container.CreateIfNotExistsAsync();
 
             await container.SetPermissionsAsync(
                 new BlobContainerPermissions()
                 {
                     PublicAccess = BlobContainerPublicAccessType.Container
                 });
 
             var blob = container.GetBlockBlobReference(
                 Path.GetFileName(_parameters.PackageFilePath));
 
             await blob.UploadFromFileAsync(_parameters.PackageFilePath, FileMode.Open);
 
             await _computeManagementClient.Deployments.CreateAsync(_parameters.CloudServiceName,
                     DeploymentSlot.Production,
                     new DeploymentCreateParameters
                     {
                         Label = _parameters.CloudServiceName,
                         Name = _parameters.CloudServiceName + "Prod",
                         PackageUri = blob.Uri,
                         Configuration = File.ReadAllText(_parameters.ConfigurationFilePath),
                         StartDeployment = true
                     });
         }
     }
}

Весь код необходимый для создания приложения в Windows Azure создан. Напоследок, осталось написать немного кода для уничтожения приложения в облаке.

Удаление элементов в облаке Windows Azure

Удалять элементы в Windows Azure с помощью библиотек Windows Azure Management Libraries так же просто, как и создавать их. Код ниже очищает созданное хранилище, затем он одновременно удаляет размещенный код и сам облачный сервис.

using Microsoft.WindowsAzure.Management.Storage;
using Microsoft.WindowsAzure.Management.Compute;
using Microsoft.WindowsAzure.Management.Compute.Models;
 
namespace MyCloudServiceManager
{
     internal partial class ManagementController
     {
         internal void Cleanup()
         {
             _computeManagementClient.Deployments.DeleteBySlot(_parameters.CloudServiceName, DeploymentSlot.Production);
             _computeManagementClient.HostedServices.Delete(_parameters.CloudServiceName);
             _storageManagementClient.StorageAccounts.Delete(_parameters.StorageAccountName);
         }
     }
}

Учитывая все удобства при написании предыдущего кода, код для пользовательского интерфейса должен быть относительно простым.

Пользовательский интерфейс

Пользовательский интерфейс для нашего приложения относительно упрощен. Я всего лишь разместил пару кнопок на WPF-форму. Первая позволяет создавать необходимые элементы в Windows Azure и осуществлять размещение кода. Вторая удаляет элементы из облака. Ниже представлен XAML-код:

<Window x:Class="MyCloudServiceManager.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="Deploy Service" Height="166" Width="308">
     <Grid>
         <Grid.ColumnDefinitions>
             <ColumnDefinition Width="112*"/>
             <ColumnDefinition Width="125*"/>
         </Grid.ColumnDefinitions>
         <Button x:Name="_createButton" Content="Create" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="73,80,0,0" Grid.Column="1" Click="_createButton_Click"/>
         <Button x:Name="_deleteButton" Content="Delete" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="73,105,0,0" Grid.Column="1" Click="_deleteButton_Click"/>
     </Grid>
</Window>

Управляющий код тоже очень прост. В обработчике события нажатия на кнопку Create я создаю экземпляр ManagementController, передавая ему все необходимые параметры для создания компонент приложения в Windows Azure. Затем я вызываю методы контролера для создания элементов в облаке.

Я так же обрабатываю событие нажатия на кнопку Delete, удаляя и очищая все созданные ранее в облаке элементы.

using Microsoft.WindowsAzure.Management.Models;
using System.IO;
using System.Windows;
 
namespace MyCloudServiceManager
{
     public partial class MainWindow : Window
     {
         private ManagementController _controller;
         public MainWindow()
         {
             InitializeComponent();
         }
 
         private async void _createButton_Click(object sender, RoutedEventArgs e)
         {
             if (_controller == null)
             {
                 _controller = new ManagementController(
                     new ManagementControllerParameters
                     {
                         Base64EncodedCertificate = "MIIKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
                         SubscriptionId = "66c15fe5-XXXX-XXXX-XXXX-XXXXXXXXXX",
                         CloudServiceName = "ManagementLibraryDemoSvc01",
                         ConfigurationFilePath = "ServiceConfiguration.Cloud.cscfg",
                         PackageFilePath = "MyCloudService.cspkg",
                         Region = LocationNames.WestUS,
                         StorageAccountName = Path.GetFileNameWithoutExtension(Path.GetRandomFileName())
                     });
             }
 
             await _controller.CreateStorageAccount();
             await _controller.CreateCloudService();
             await _controller.DeployCloudService();
         }
 
         private void _deleteButton_Click(object sender, RoutedEventArgs e)
         {
             _controller.Cleanup();
         }
     }
}

Можно модифицировать этот код для использования возможностей Windows Storage SDK наблюдать на клиентской стороне за очередью сообщений в облачном хранилище. После того как облачный сервис завершит свою работу он отправит сообщение в очередь в облаке. Сообщение будет получено клиентом, который вызовет метод Cleanup и удалит все компоненты приложения из облака.

Бесконечные возможности автоматизации

Библиотеки Windows Azure Management Libraries предлагают прекрасный слой автоматизации между вашим кодом и Windows Azure. Вы можете использовать эти библиотеки для задач автоматизации всего спектра процессов создания и удаления компонент Windows Azure. В текущей версии мы предлагаем библиотеки для управления вычислительными мощностями и облачным хранилищем, а так же компонентами Windows Azure Web Sites. Со временем, мы добавим в библиотеки больше функций. Наша цель – предоставить вам возможность автоматизировать выполнения любой задачи в Windows Azure.

Мы с нетерпением ждем вашего отзыва о работе с библиотеками. Пожалуйста, пробуйте, экспериментируйте с Management Libraries и дайте нам знать для облегчений каких задач вы их используете. Мы открыты для любых ваших идей или вопросов. Код библиотек открыт, как и код многих других библиотек для Windows Azure, вы можете найти его в нашем репозитории на GitHub.

Это перевод оригинальной статьи Getting Started with the Windows Azure Management Libraries for .NET