Создать учетную запись хранения
Create Storage Account
Асинхронная операция создает новую учетную запись хранилища в Microsoft Azure.
Запрос
Create Storage Account
Можно составить следующим образом. Замените <subscription-id>
с вашим идентификатором подписки.
Метод | URI запроса |
---|---|
POST | https://management.core.windows.net/<subscription-id>/services/storageservices |
Необходимо убедиться, что запрос к службе управления безопасен. Дополнительные сведения см. в разделе Проверка подлинности запросов управления службами.
Параметры URI
Отсутствует.
Заголовки запроса
В следующей таблице описаны заголовки запросов.
Заголовок запроса | Описание |
---|---|
Content-Type |
Обязательно. Задайте для этого заголовка application/xml . |
x-ms-version |
Обязательно. Задает версию операции, используемой для этого запроса. Значение этого заголовка должно быть присвоено 2011-06-01 или более поздней версии. Дополнительные сведения об управлении версиями заголовков см. в разделе Управление версиями службы управления. |
Текст запроса
Далее приведен формат текста запроса.
<?xml version="1.0" encoding="utf-8"?> <CreateStorageServiceInput xmlns="https://schemas.microsoft.com/windowsazure"> <ServiceName>name-of-storage-account</ServiceName> <Description>description-of-storage-account</Description> <Label>base64-encoded-label</Label> <AffinityGroup>name-of-affinity-group</AffinityGroup> <Location>location-of-storage-account</Location> <GeoReplicationEnabled>geo-replication-indicator</GeoReplicationEnabled> <ExtendedProperties> <ExtendedProperty> <Name>property-name</Name> <Value>property-value</Value> </ExtendedProperty> </ExtendedProperties> <SecondaryReadEnabled>secondary-read-indicator</SecondaryReadEnabled> <AccountType>type-of-storage-account</AccountType> </CreateStorageServiceInput>
В следующей таблице описываются элементы текста запроса.
Имя элемента | Описание |
Service Name | Обязательно. Имя для учетной записи хранения, уникальное в пределах Azure. Имена учетной записи хранения должны содержать от 3 до 24 символов (только цифры и строчные буквы). Это имя — имя префикса DNS, и оно может использоваться для получения доступа к BLOB-объектам, очередям и таблицам в учетной записи хранения. Например: http://ServiceName.blob.core.windows.net/mycontainer/ |
Метка | Обязательно. Метка для учетной записи хранилища, указанная в виде строки в кодировке base64. Метка может содержать до 100 символов. Эта метка может обозначать учетную запись хранилища для отслеживания. |
Описание | Необязательно. Описание учетной записи хранения. Описание может иметь длину до 1 024 символов. |
Местоположение | Обязателен, если AffinityGroup не указан. Расположение, где создана учетная запись хранения. Можно включить расположение или AffinityGroup элемент в тексте запроса, но не оба. Отображение списка доступных расположений, используйте Перечисление расположений операции. |
Территориальная группа | Обязателен, если расположение не указан. Имя существующей территориальной группы в указанной подписке. Можно включить расположение или AffinityGroup элемент в тексте запроса, но не оба. Чтобы получить список доступных территориальных групп, Перечисление территориальных групп операции. |
GeoReplicationEnabled | Необязательно. Указывает, включена ли географическая репликация при создании учетной записи хранения. Если элемент не включен в текст запроса, значением по умолчанию является true . Если значение true , данные в учетной записи хранилища реплицируются по более чем одному географическому местоположению для обеспечения устойчивости в случае катастрофической потери службы.GeoReplicationEnabled Элемент только в версии 2012-03-01 или более поздней версии и заменен элементом AccountType, начиная с версии 2014-06-01 или более поздней версии. |
Название | Необязательно. Представляет собой имя расширенного свойства учетной записи хранения. Каждое расширенное свойство должно иметь и заданное имя, и значение. Может быть максимум 50 пар из имени и значения расширенных свойств. Максимальная длина имени элемента — 64 символа, в имени допустимы только буквенно-цифровые символы и знаки подчеркивания и имя должно начинаться с буквы. Попытка использовать другие символы, начать имя не с буквы или ввести имя, которое уже имеется у другого расширенного свойства в той же учетной записи хранения, приведет к ошибке с кодом состояния 400 (неправильный запрос). Имя элемент только в версии 2012-03-01 или более поздней версии. |
Значение | Необязательно. Представляет собой значение расширенного свойства учетной записи хранения. Каждое расширенное свойство должно иметь и заданное имя, и значение. Можно задать не более 50 пар из имени и значения расширенных свойств, максимальное значение каждого расширенного свойства — 255 символов. Значение элемент только в версии 2012-03-01 или более поздней версии. |
SecondaryReadEnabled | Необязательно. Указывает, включено ли вторичное чтение для учетной записи хранилища. Возможные значения: - true - false SecondaryReadEnabled Элемент только в версии 2013-11-01 или более поздней версии и заменен элементом AccountType, начиная с версии 2014-06-01 или более поздней версии. |
AccountType | Указывает, поддерживает ли учетная запись локально избыточное хранилище, геоизбыточное хранилище, хранилище, избыточное в пределах зоны, или геоизбыточное хранилище с доступом на чтение. Возможные значения: - Standard_LRS - Standard_ZRS - Standard_GRS - Standard_RAGRS - Premium_LRS AccountType Элемент только в версии 2014-06-01 или более поздней версии и заменяет элементы SecondaryReadEnabled и GeoReplicationEnabled.Premium_LRS Элемент только в версии 2014-10-01 или более поздней версии. Note: Объект Standard_ZRS учетной записи не может быть изменено в другой тип учетной записи и нельзя изменить тип учетной записи Standard_ZRS . То же касается Premium_LRS учетные записи. |
Ответ
Ответ включает код состояния HTTP, набор заголовков ответа и текст ответа.
Код состояния
Успешная операция возвращает код состояния 200 (ОК). Сведения о кодах состояния см. в разделе состояние службы управления и коды ошибок.
Заголовки ответа
Ответ для этой операции включает следующие заголовки. Ответ может также включать дополнительные стандартные заголовки HTTP. Все стандартные заголовки соответствуют спецификации протокола HTTP/1.1.
Заголовок ответа | Описание |
---|---|
x-ms-request-id |
Значение, которое однозначно определяет запрос к службе управления. Для асинхронной операции можно вызвать Получение состояния операции со значением заголовка, чтобы определить, завершена ли операция, произошел ли сбой, или она все еще выполняется. |
Текст ответа
Отсутствует.
Примечания
Можно создать учетные записи хранения программно с Создать учетную запись хранилища операции в установленных пределах для вашей подписки. Сведения об ограничениях, связанных с учетными записями хранения см. в разделе подписки Azure и ограничения служб, квоты и ограничения.
Операция сразу же возвращает данные с ИД запроса, тогда как создание учетной записи хранения выполняется асинхронно Azure, поскольку провизионирование новой учетной записи хранения может занимать несколько минут. Чтобы выяснить, по завершении операции создания учетной записи хранилища, можно опросить Получение состояния операции операции с идентификатором запроса. Возвращает текст XML с операции элемента, содержащего состояние элемент которого будет иметь значение InProgress
, Failed
, или Succeeded
, в зависимости от состояния создания учетной записи хранилища. При опросе до возврата состояния Failed
или Succeeded
, операции будет содержать код состояния в StatusCode элемент, а операции с ошибками будут содержать дополнительные сведения об ошибке в Ошибка элемент.
Сведения в целевые показатели по производительности и масштабируемости хранилища Azure может также помочь при планировании потребности хранения.
Пример
Эта консольная программа создает новую учетную запись хранилища, задавая описание, метку, расположение и состояние географической репликации с помощью Создать учетную запись хранилища затем выполняет опрос Получение состояния операции операции с Идентификатором запроса, возвращенным от Создать учетную запись хранилища операции до успешного вызова, сбой, или истекло время ожидания опроса. Наконец, он вызывает Получение свойств учетной записи хранения для отображения свойств для учетной записи хранилища. Задайте значение x-ms-version
заголовка в Version
строку, идентификатор подписки в SubscriptionId
, отпечаток сертификата управления в Thumbprint
, и ServiceName уникальный хранилища имя учетной записи для запуска образца.
namespace Microsoft.WindowsAzure.ServiceManagementRESTAPI.Samples { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Xml; using System.Xml.Linq; public class Program { // Set these constants with your values to run the sample. private const string Version = "2011-12-01"; private const string Thumbprint = "management-certificate-thumbprint"; private const string SubscriptionId = "subscription-identifier"; private const string ServiceName = "unique-storage-account-name"; // This is the common namespace for all Service Management REST API XML data. private static XNamespace wa = "https://schemas.microsoft.com/windowsazure"; /// <summary> /// The operation status values from PollGetOperationStatus. /// </summary> private enum OperationStatus { InProgress, Failed, Succeeded, TimedOut } /// <summary> /// Gets or sets the certificate that matches the Thumbprint value. /// </summary> private static X509Certificate2 Certificate { get; set; } static void Main(string[] args) { try { Certificate = GetStoreCertificate(Thumbprint); // Create the new storage account with the following values: string description = "Description for my example storage account"; string label = "My example storage account label"; string location = "North Central US"; bool? enableGeoReplication = true; string requestId = CreateStorageAccount( ServiceName, description, label, null, location, enableGeoReplication); Console.WriteLine( "Called Create Storage Account operation: requestId {0}", requestId); // Loop on Get Operation Status for result of storage creation OperationResult result = PollGetOperationStatus( requestId, pollIntervalSeconds: 20, timeoutSeconds: 180); switch (result.Status) { case OperationStatus.TimedOut: Console.WriteLine( "Poll of Get Operation Status timed out: " + "Operation {0} is still in progress after {1} seconds.", requestId, (int)result.RunningTime.TotalSeconds); break; case OperationStatus.Failed: Console.WriteLine( "Failed: Operation {0} failed after " + "{1} seconds with status {2} ({3}) - {4}: {5}", requestId, (int)result.RunningTime.TotalSeconds, (int)result.StatusCode, result.StatusCode, result.Code, result.Message); break; case OperationStatus.Succeeded: Console.WriteLine( "Succeeded: Operation {0} completed " + "after {1} seconds with status {2} ({3})", requestId, (int)result.RunningTime.TotalSeconds, (int)result.StatusCode, result.StatusCode); break; } // Display the property values for the new storage account. // Convert the Label property to a readable value for display. XElement updatedProperties = GetStorageAccountProperties(ServiceName); XElement labelElement = updatedProperties.Descendants(wa + "Label").First(); labelElement.Value = labelElement.Value.FromBase64(); Console.WriteLine( "New Storage Account Properties for {0}:{1}{2}", ServiceName, Environment.NewLine, updatedProperties.ToString(SaveOptions.OmitDuplicateNamespaces)); } catch (Exception ex) { Console.WriteLine("Exception caught in Main:"); Console.WriteLine(ex.Message); } Console.Write("Press any key to continue:"); Console.ReadKey(); } /// <summary> /// Calls the Get Storage Account Properties operation in the Service /// Management REST API for the specified subscription and storage account /// name and returns the StorageService XML element from the response. /// </summary> /// <param name="serviceName">The name of the storage account.</param> /// <returns>The StorageService XML element from the response.</returns> private static XElement GetStorageAccountProperties( string serviceName) { string uriFormat = "https://management.core.windows.net/{0}" + "/services/storageservices/{1}"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, serviceName)); XDocument responseBody; InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody); return responseBody.Element(wa + "StorageService"); } /// <summary> /// Calls the Create Storage Account operation in the Service Management /// REST API for the specified subscription, storage account name, /// description, label, location or affinity group, and geo-replication /// enabled setting. /// </summary> /// <param name="serviceName">The name of the storage account to update.</param> /// <param name="description">The new description for the storage account.</param> /// <param name="label">The new label for the storage account.</param> /// <param name="affinityGroup">The affinity group name, or null to use a location.</param> /// <param name="location">The location name, or null to use an affinity group.</param> /// <param name="geoReplicationEnabled">The new geo-replication setting, if applicable. /// This optional parameter defaults to null.</param> /// <returns>The requestId for the operation.</returns> private static string CreateStorageAccount( string serviceName, string description, string label, string affinityGroup, string location, bool? geoReplicationEnabled = null) { string uriFormat = "https://management.core.windows.net/{0}" + "/services/storageservices"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId)); // Location and Affinity Group are mutually exclusive. // Use the location if it isn't null or empty. XElement locationOrAffinityGroup = String.IsNullOrEmpty(location) ? new XElement(wa + "AffinityGroup", affinityGroup) : new XElement(wa + "Location", location); // Create the request XML document XDocument requestBody = new XDocument( new XDeclaration("1.0", "UTF-8", "no"), new XElement( wa + "CreateStorageServiceInput", new XElement(wa + "ServiceName", serviceName), new XElement(wa + "Description", description), new XElement(wa + "Label", label.ToBase64()), locationOrAffinityGroup)); // Add the GeoReplicationEnabled element if the version supports it. if ((geoReplicationEnabled != null) && (String.CompareOrdinal(Version, "2011-12-01") >= 0)) { requestBody.Element( wa + "CreateStorageServiceInput").Add( new XElement( wa + "GeoReplicationEnabled", geoReplicationEnabled.ToString().ToLowerInvariant())); } XDocument responseBody; return InvokeRequest( uri, "POST", HttpStatusCode.Accepted, requestBody, out responseBody); } /// <summary> /// Calls the Get Operation Status operation in the Service /// Management REST API for the specified subscription and requestId /// and returns the Operation XML element from the response. /// </summary> /// <param name="requestId">The requestId of the operation to track.</param> /// <returns>The Operation XML element from the response.</returns> private static XElement GetOperationStatus( string requestId) { string uriFormat = "https://management.core.windows.net/{0}" + "/operations/{1}"; Uri uri = new Uri(String.Format(uriFormat, SubscriptionId, requestId)); XDocument responseBody; InvokeRequest(uri, "GET", HttpStatusCode.OK, null, out responseBody); return responseBody.Element(wa + "Operation"); } /// <summary> /// The results from PollGetOperationStatus are passed in this struct. /// </summary> private struct OperationResult { // The status: InProgress, Failed, Succeeded, or TimedOut. public OperationStatus Status { get; set; } // The http status code of the requestId operation, if any. public HttpStatusCode StatusCode { get; set; } // The approximate running time for PollGetOperationStatus. public TimeSpan RunningTime { get; set; } // The error code for the failed operation. public string Code { get; set; } // The message for the failed operation. public string Message { get; set; } } /// <summary> /// Polls Get Operation Status for the operation specified by requestId /// every pollIntervalSeconds until timeoutSeconds have passed or the /// operation has returned a Failed or Succeeded status. /// </summary> /// <param name="requestId">The requestId of the operation to get status for.</param> /// <param name="pollIntervalSeconds">The interval between calls to Get Operation Status.</param> /// <param name="timeoutSeconds">The maximum number of seconds to poll.</param> /// <returns>An OperationResult structure with status or error information.</returns> private static OperationResult PollGetOperationStatus( string requestId, int pollIntervalSeconds, int timeoutSeconds) { OperationResult result = new OperationResult(); DateTime beginPollTime = DateTime.UtcNow; TimeSpan pollInterval = new TimeSpan(0, 0, pollIntervalSeconds); DateTime endPollTime = beginPollTime + new TimeSpan(0, 0, timeoutSeconds); bool done = false; while (!done) { XElement operation = GetOperationStatus(requestId); result.RunningTime = DateTime.UtcNow - beginPollTime; try { // Turn the Status string into an OperationStatus value result.Status = (OperationStatus)Enum.Parse( typeof(OperationStatus), operation.Element(wa + "Status").Value); } catch (Exception) { throw new ApplicationException(string.Format( "Get Operation Status {0} returned unexpected status: {1}{2}", requestId, Environment.NewLine, operation.ToString(SaveOptions.OmitDuplicateNamespaces))); } switch (result.Status) { case OperationStatus.InProgress: Console.WriteLine( "In progress for {0} seconds", (int)result.RunningTime.TotalSeconds); Thread.Sleep((int)pollInterval.TotalMilliseconds); break; case OperationStatus.Failed: result.StatusCode = (HttpStatusCode)Convert.ToInt32( operation.Element(wa + "HttpStatusCode").Value); XElement error = operation.Element(wa + "Error"); result.Code = error.Element(wa + "Code").Value; result.Message = error.Element(wa + "Message").Value; done = true; break; case OperationStatus.Succeeded: result.StatusCode = (HttpStatusCode)Convert.ToInt32( operation.Element(wa + "HttpStatusCode").Value); done = true; break; } if (!done && DateTime.UtcNow > endPollTime) { result.Status = OperationStatus.TimedOut; done = true; } } return result; } /// <summary> /// Gets the certificate matching the thumbprint from the local store. /// Throws an ArgumentException if a matching certificate is not found. /// </summary> /// <param name="thumbprint">The thumbprint of the certificate to find.</param> /// <returns>The certificate with the specified thumbprint.</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)); } /// <summary> /// A helper function to invoke a Service Management REST API operation. /// Throws an ApplicationException on unexpected status code results. /// </summary> /// <param name="uri">The URI of the operation to invoke using a web request.</param> /// <param name="method">The method of the web request, GET, PUT, POST, or DELETE.</param> /// <param name="expectedCode">The expected status code.</param> /// <param name="requestBody">The XML body to send with the web request. Use null to send no request body.</param> /// <param name="responseBody">The XML body returned by the request, if any.</param> /// <returns>The requestId returned by the operation.</returns> private static string InvokeRequest( Uri uri, string method, HttpStatusCode expectedCode, XDocument requestBody, out XDocument responseBody) { responseBody = null; string requestId = String.Empty; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri); request.Method = method; request.Headers.Add("x-ms-Version", Version); request.ClientCertificates.Add(Certificate); request.ContentType = "application/xml"; if (requestBody != null) { using (Stream requestStream = request.GetRequestStream()) { using (StreamWriter streamWriter = new StreamWriter( requestStream, System.Text.UTF8Encoding.UTF8)) { requestBody.Save(streamWriter, SaveOptions.DisableFormatting); } } } HttpWebResponse response; HttpStatusCode statusCode = HttpStatusCode.Unused; try { response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { // GetResponse throws a WebException for 4XX and 5XX status codes response = (HttpWebResponse)ex.Response; } try { statusCode = response.StatusCode; if (response.ContentLength > 0) { using (XmlReader reader = XmlReader.Create(response.GetResponseStream())) { responseBody = XDocument.Load(reader); } } if (response.Headers != null) { requestId = response.Headers["x-ms-request-id"]; } } finally { response.Close(); } if (!statusCode.Equals(expectedCode)) { throw new ApplicationException(string.Format( "Call to {0} returned an error:{1}Status Code: {2} ({3}):{1}{4}", uri.ToString(), Environment.NewLine, (int)statusCode, statusCode, responseBody.ToString(SaveOptions.OmitDuplicateNamespaces))); } return requestId; } } /// <summary> /// Helpful extension methods for converting strings to and from Base-64. /// </summary> public static class StringExtensions { /// <summary> /// Converts a UTF-8 string to a Base-64 version of the string. /// </summary> /// <param name="s">The string to convert to Base-64.</param> /// <returns>The Base-64 converted string.</returns> public static string ToBase64(this string s) { byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s); return Convert.ToBase64String(bytes); } /// <summary> /// Converts a Base-64 encoded string to UTF-8. /// </summary> /// <param name="s">The string to convert from Base-64.</param> /// <returns>The converted UTF-8 string.</returns> public static string FromBase64(this string s) { byte[] bytes = Convert.FromBase64String(s); return System.Text.Encoding.UTF8.GetString(bytes); } } }
Этот пример программы производит консольный вывод, имеющий примерно такой вид:
Called Create Storage Account operation: requestId 8ba8bd9cdc50472892a0b3cd3659b297 In progress for 0 seconds In progress for 20 seconds In progress for 41 seconds In progress for 61 seconds In progress for 82 seconds In progress for 103 seconds Succeeded: Operation 8ba8bd9cdc50472892a0b3cd3659b297 completed after 123 seconds with status 200 (OK) New Storage Account Properties for myexamplestorage1: <StorageService xmlns="https://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Url>https://management.core.windows.net/01234567-89ab-cdef-0123-456789abcdef/services/storageservices/myexamplestorage1</Url> <ServiceName>myexamplestorage1</ServiceName> <StorageServiceProperties> <Description>Description for my example storage account</Description> <Location>North Central US</Location> <Label>My example storage account label</Label> <Status>Created</Status> <Endpoints> <Endpoint>http://myexamplestorage1.blob.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.queue.core.windows.net/</Endpoint> <Endpoint>http://myexamplestorage1.table.core.windows.net/</Endpoint> </Endpoints> <GeoReplicationEnabled>true</GeoReplicationEnabled> <GeoPrimaryRegion>usnorth</GeoPrimaryRegion> <StatusOfPrimary>Available</StatusOfPrimary> <GeoSecondaryRegion>ussouth</GeoSecondaryRegion> <StatusOfSecondary>Available</StatusOfSecondary> </StorageServiceProperties> </StorageService> Press any key to continue: