Crear cuenta de almacenamiento

 

La Create Storage Account operación asincrónica, crea una nueva cuenta de almacenamiento en Microsoft Azure.

El Create Storage Account solicitud se puede especificar como sigue. Reemplace <subscription-id> con el identificador de suscripción.

MétodoURI de solicitud
POSThttps://management.core.windows.net/<subscription-id>/services/storageservices

Debe asegurarse de que la solicitud que se realice al servicio de administración sea segura. Para obtener más información, vea autenticar solicitudes de administración de servicios.

Parámetros URI

Ninguna.

Encabezados de solicitud

La tabla siguiente describe los encabezados de solicitud.

Encabezado de solicitudDescripción
Content-TypeRequerido. Establezca este encabezado en aplicación/xml.
x-ms-versionRequerido. Especifica la versión de la operación que se utiliza para esta solicitud. El valor de este encabezado debe establecerse en 2011-06-01 o superior. Para obtener más información acerca de los encabezados de control de versiones, vea versiones de administración de servicios.

Cuerpo de solicitud

El formato del cuerpo de solicitud es el siguiente:

<?xml version="1.0" encoding="utf-8"?> <CreateStorageServiceInput xmlns="http://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>  
  

En la tabla siguiente se describen los elementos del cuerpo de la solicitud.

Nombre de elementoDescripción
Nombre de servicioRequerido. Nombre para la cuenta de almacenamiento que es único dentro de Azure. Los nombres de cuentas de almacenamiento deben contener entre 3 y 24 y usar exclusivamente números y letras en minúscula.

Este nombre es el nombre del prefijo DNS y se puede utilizar para obtener acceso a blobs, colas y las tablas de la cuenta de almacenamiento.

Por ejemplo: http://ServiceName.blob.core.windows.net/mycontainer/
EtiquetaRequerido. Etiqueta de la cuenta de almacenamiento especificada como una cadena con codificación en base 64. La etiqueta puede tener hasta 100 caracteres. La etiqueta se puede utilizar para identificar la cuenta de almacenamiento con fines de seguimiento.
DescripciónOpcional. Descripción de la cuenta de almacenamiento. La descripción puede tener hasta 1024 caracteres.
UbicaciónRequerido si AffinityGroup no se ha especificado. Ubicación en la que se crea la cuenta de almacenamiento.

Puede incluir un ubicación o AffinityGroup elemento en el cuerpo de la solicitud, pero no ambos. Para enumerar las ubicaciones disponibles, use la Enumerar ubicaciones operación.
AffinityGroupRequerido si ubicación no se ha especificado. Nombre de un grupo de afinidad existente en la suscripción especificada.

Puede incluir un ubicación o AffinityGroup elemento en el cuerpo de la solicitud, pero no ambos. Para mostrar grupos de afinidad disponibles, utilice la Enumerar grupos de afinidad operación.
GeoReplicationEnabledOpcional. Especifica si la cuenta de almacenamiento se crea con la replicación geográfica habilitada. Si el elemento no se incluye en el cuerpo de la solicitud, el valor predeterminado es true. Si establece en true, los datos de la cuenta de almacenamiento se replican en más de una ubicación geográfica para habilitar resistencia frente a la pérdida de servicios catastrófica.

El GeoReplicationEnabled elemento sólo está disponible con la versión 2012-03-01 o posterior y se reemplaza por el elemento AccountType con la versión 2014-06-01 o versiones posteriores.
NombreOpcional. Representa el nombre de una propiedad de la cuenta de almacenamiento extendida. Cada propiedad extendida debe tener tanto un nombre como un valor definidos. Puede tener un máximo de 50 pares de valores/nombres de propiedad extendidos.

La longitud máxima del elemento Nombre es de 64 caracteres, solo los caracteres alfanuméricos y caracteres de subrayado son válidos en el Nombre y debe comenzar por una letra. Intentar utilizar otros caracteres, empezando el Nombre con un carácter no alfanumérico, o escribir un nombre idéntico al de otra propiedad extendida propiedad de la misma cuenta de almacenamiento, producirá un error de código de estado 400 (solicitud incorrecta).

El nombre elemento sólo está disponible con la versión 2012-03-01 o posterior.
ValorOpcional. Representa el valor de una propiedad de la cuenta de almacenamiento extendida. Cada propiedad extendida debe tener tanto un nombre como un valor definidos. Puede tener un máximo de 50 pares de valores/nombres de propiedad extendidos, y cada valor de propiedad extendido tiene una longitud máxima de 255 caracteres.

El valor elemento sólo está disponible con la versión 2012-03-01 o posterior.
SecondaryReadEnabledOpcional. Indica que la lectura secundaria está habilitada para la cuenta de almacenamiento.

Los valores posibles son:

- true
- false

El SecondaryReadEnabled elemento sólo está disponible con la versión 2013-11-01 o posterior y se reemplaza por el elemento AccountType con la versión 2014-06-01 o versiones posteriores.
AccountTypeEspecifica si la cuenta admite almacenamiento con redundancia local, almacenamiento con redundancia geográfica, almacenamiento con redundancia de zona o almacenamiento con redundancia geográfica con acceso de lectura.

Los valores posibles son:

- Standard_LRS
- Standard_ZRS
- Standard_GRS
- Standard_RAGRS
- Premium_LRS

El AccountType elemento sólo está disponible con la versión 2014-06-01 o posterior y reemplaza los elementos SecondaryReadEnabled y GeoReplicationEnabled.

El Premium_LRS elemento sólo está disponible con la versión 2014-10-01 o posterior. Note: Un Standard_ZRS cuenta no se puede cambiar a otro tipo de cuenta más adelante y otros tipos de cuenta no puede cambiarse a Standard_ZRS. Lo mismo sucede con Premium_LRS cuentas.

La respuesta incluye un código de estado HTTP, un conjunto de encabezados de respuesta y un cuerpo de respuesta.

Código de estado

Una operación correcta devuelve el código de estado 200 Correcto. Para obtener información acerca de los códigos de estado, vea estado de administración del servicio y los códigos de Error.

Encabezados de respuesta

La respuesta para esta operación incluye los encabezados siguientes. La respuesta también puede incluir otros encabezados HTTP estándar. Todos los encabezados estándar se ajustan a la especificación del protocolo HTTP/1.1.

Encabezado de respuestaDescripción
x-ms-request-idValor que identifica de forma exclusiva una solicitud realizada ante el servicio de administración. Para una operación asincrónica, puede llamar a Obtener el estado de la operación con el valor del encabezado para determinar si la operación se ha completado, ha generado un error o aún está en curso.

Cuerpo de respuesta

Ninguna.

Puede crear cuentas de almacenamiento mediante programación con el crear cuenta de almacenamiento operación hasta los límites disponibles en la suscripción. Para obtener información acerca de los límites relacionados con las cuentas de almacenamiento, consulte suscripción de Azure y límites de servicio, cuotas y restricciones.

La operación se devuelve inmediatamente con un identificador de la solicitud, mientras Azure crea la cuenta de almacenamiento de forma asincrónica, porque proporcionar una nueva cuenta de almacenamiento puede tardar varios minutos. Para saber cuándo se ha completado la operación de creación de la cuenta de almacenamiento, puede sondear la Obtener el estado de la operación operación con el identificador de solicitud. Esto devuelve un cuerpo XML con un operación elemento que contiene un estado elemento que tendrá un valor de InProgress, Failed, o Succeeded, dependiendo del estado de la creación de la cuenta de almacenamiento. Si se sondea hasta que el estado es Failed o Succeeded, el operación elemento contendrá un código de estado en el StatusCode elemento y las operaciones con errores contendrán información de error adicional en el Error elemento.

La información de objetivos de rendimiento y escalabilidad de almacenamiento de Azure también le ayudará al planear las necesidades de almacenamiento.

Este programa de consola de ejemplo crea una nueva cuenta de almacenamiento, establecer la descripción, etiqueta, ubicación y estado de replicación geográfica mediante el crear cuenta de almacenamiento operación, a continuación, sondea la Obtener el estado de la operación operación con la solicitud devuelve el identificador de la crear cuenta de almacenamiento operación hasta que la llamada ha tenido éxito, error, o se ha agotado el sondeo. Por último, se llama Obtener propiedades de la cuenta de almacenamiento para mostrar las propiedades de la nueva cuenta de almacenamiento. Establezca el valor de la x-ms-version encabezado en la Version de cadena, el identificador de suscripción en SubscriptionId, la huella digital de certificado de administración en Thumbprint, y establecer ServiceName en un nombre de cuenta de almacenamiento único para ejecutar el ejemplo.

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 = "http://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); } } }  
  

Este programa de ejemplo genera un resultado de la consola parecido al siguiente cuando se ejecuta:

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="http://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:  

Mostrar: