diff --git a/sdk/storage/azure_storage_blob/src/clients/blob_client.rs b/sdk/storage/azure_storage_blob/src/clients/blob_client.rs index 1486d1e0c6..a7a16db6c6 100644 --- a/sdk/storage/azure_storage_blob/src/clients/blob_client.rs +++ b/sdk/storage/azure_storage_blob/src/clients/blob_client.rs @@ -4,17 +4,19 @@ use crate::{ generated::clients::BlobClient as GeneratedBlobClient, generated::models::{ - BlobClientDownloadResult, BlobClientGetPropertiesResult, - BlockBlobClientCommitBlockListResult, BlockBlobClientStageBlockResult, - BlockBlobClientUploadResult, + BlobClientDeleteImmutabilityPolicyResult, BlobClientDownloadResult, + BlobClientGetAccountInfoResult, BlobClientGetPropertiesResult, + BlobClientSetImmutabilityPolicyResult, BlockBlobClientCommitBlockListResult, + BlockBlobClientStageBlockResult, BlockBlobClientUploadResult, }, models::{AccessTier, BlockList, BlockListType, BlockLookupList}, pipeline::StorageHeadersPolicy, - BlobClientDeleteOptions, BlobClientDownloadOptions, BlobClientGetPropertiesOptions, - BlobClientOptions, BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, - BlobClientSetTierOptions, BlockBlobClientCommitBlockListOptions, - BlockBlobClientGetBlockListOptions, BlockBlobClientStageBlockOptions, - BlockBlobClientUploadOptions, + BlobClientDeleteImmutabilityPolicyOptions, BlobClientDeleteOptions, BlobClientDownloadOptions, + BlobClientGetAccountInfoOptions, BlobClientGetPropertiesOptions, BlobClientOptions, + BlobClientSetImmutabilityPolicyOptions, BlobClientSetMetadataOptions, + BlobClientSetPropertiesOptions, BlobClientSetTierOptions, + BlockBlobClientCommitBlockListOptions, BlockBlobClientGetBlockListOptions, + BlockBlobClientStageBlockOptions, BlockBlobClientUploadOptions, }; use azure_core::{ credentials::TokenCredential, @@ -250,4 +252,41 @@ impl BlobClient { ) -> Result> { self.client.set_tier(tier, options).await } + + /// Gets information related to the Storage account in which the blob resides. + /// This includes the `sku_name` and `account_kind`. + /// + /// # Arguments + /// + /// * `options` - Optional configuration for the request. + pub async fn get_account_info( + &self, + options: Option>, + ) -> Result> { + self.client.get_account_info(options).await + } + + /// Sets the immutability policy on the blob. + /// + /// # Arguments + /// + /// * `options` - Optional configuration for the request. + pub async fn set_immutability_policy( + &self, + options: Option>, + ) -> Result> { + self.client.set_immutability_policy(options).await + } + + /// Deletes the immutability policy on the blob. + /// + /// # Arguments + /// + /// * `options` - Optional configuration for the request. + pub async fn delete_immutability_policy( + &self, + options: Option>, + ) -> Result> { + self.client.delete_immutability_policy(options).await + } } diff --git a/sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs b/sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs index 6db5693378..8fedf81a10 100644 --- a/sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs +++ b/sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs @@ -3,10 +3,14 @@ use crate::{ generated::clients::BlobContainerClient as GeneratedBlobContainerClient, - generated::models::BlobContainerClientGetPropertiesResult, pipeline::StorageHeadersPolicy, + generated::models::{ + BlobContainerClientGetAccountInfoResult, BlobContainerClientGetPropertiesResult, + }, + pipeline::StorageHeadersPolicy, BlobClient, BlobClientOptions, BlobContainerClientCreateOptions, - BlobContainerClientDeleteOptions, BlobContainerClientGetPropertiesOptions, - BlobContainerClientOptions, BlobContainerClientSetMetadataOptions, + BlobContainerClientDeleteOptions, BlobContainerClientGetAccountInfoOptions, + BlobContainerClientGetPropertiesOptions, BlobContainerClientOptions, + BlobContainerClientSetMetadataOptions, }; use azure_core::{ credentials::TokenCredential, @@ -153,4 +157,17 @@ impl BlobContainerClient { ) -> Result> { self.client.get_properties(options).await } + + /// Gets information related to the Storage account in which the container resides. + /// This includes the `sku_name` and `account_kind`. + /// + /// # Arguments + /// + /// * `options` - Optional configuration for the request. + pub async fn get_account_info( + &self, + options: Option>, + ) -> Result> { + self.client.get_account_info(options).await + } } diff --git a/sdk/storage/azure_storage_blob/src/clients/blob_service_client.rs b/sdk/storage/azure_storage_blob/src/clients/blob_service_client.rs index 9fe27e40b2..7214be775e 100644 --- a/sdk/storage/azure_storage_blob/src/clients/blob_service_client.rs +++ b/sdk/storage/azure_storage_blob/src/clients/blob_service_client.rs @@ -3,8 +3,10 @@ use crate::{ generated::clients::BlobServiceClient as GeneratedBlobServiceClient, - models::StorageServiceProperties, pipeline::StorageHeadersPolicy, BlobContainerClient, - BlobContainerClientOptions, BlobServiceClientGetPropertiesOptions, BlobServiceClientOptions, + generated::models::BlobServiceClientGetAccountInfoResult, models::StorageServiceProperties, + pipeline::StorageHeadersPolicy, BlobContainerClient, BlobContainerClientOptions, + BlobServiceClientGetAccountInfoOptions, BlobServiceClientGetPropertiesOptions, + BlobServiceClientOptions, }; use azure_core::{ credentials::TokenCredential, @@ -97,4 +99,17 @@ impl BlobServiceClient { ) -> Result> { self.client.get_properties(options).await } + + /// Gets information related to the Storage account. + /// This includes the `sku_name` and `account_kind`. + /// + /// # Arguments + /// + /// * `options` - Optional configuration for the request. + pub async fn get_account_info( + &self, + options: Option>, + ) -> Result> { + self.client.get_account_info(options).await + } } diff --git a/sdk/storage/azure_storage_blob/src/lib.rs b/sdk/storage/azure_storage_blob/src/lib.rs index 75460580b8..3abdf6343f 100644 --- a/sdk/storage/azure_storage_blob/src/lib.rs +++ b/sdk/storage/azure_storage_blob/src/lib.rs @@ -16,10 +16,13 @@ pub use crate::generated::clients::{ BlobClientOptions, BlobContainerClientOptions, BlobServiceClientOptions, }; pub use crate::generated::models::{ - BlobClientDeleteOptions, BlobClientDownloadOptions, BlobClientGetPropertiesOptions, - BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, BlobClientSetTierOptions, - BlobContainerClientCreateOptions, BlobContainerClientDeleteOptions, + BlobClientDeleteImmutabilityPolicyOptions, BlobClientDeleteOptions, BlobClientDownloadOptions, + BlobClientGetAccountInfoOptions, BlobClientGetPropertiesOptions, + BlobClientSetImmutabilityPolicyOptions, BlobClientSetMetadataOptions, + BlobClientSetPropertiesOptions, BlobClientSetTierOptions, BlobContainerClientCreateOptions, + BlobContainerClientDeleteOptions, BlobContainerClientGetAccountInfoOptions, BlobContainerClientGetPropertiesOptions, BlobContainerClientSetMetadataOptions, + BlobImmutabilityPolicyMode, BlobServiceClientGetAccountInfoOptions, BlobServiceClientGetPropertiesOptions, BlockBlobClientCommitBlockListOptions, BlockBlobClientGetBlockListOptions, BlockBlobClientStageBlockOptions, BlockBlobClientUploadOptions, @@ -27,12 +30,16 @@ pub use crate::generated::models::{ pub mod models { pub use crate::generated::models::{ - AccessTier, ArchiveStatus, BlobClientDownloadResult, BlobClientDownloadResultHeaders, + AccessTier, AccountKind, ArchiveStatus, BlobClientDeleteImmutabilityPolicyResult, + BlobClientDeleteImmutabilityPolicyResultHeaders, BlobClientDownloadResult, + BlobClientDownloadResultHeaders, BlobClientGetAccountInfoResultHeaders, BlobClientGetPropertiesResult, BlobClientGetPropertiesResultHeaders, - BlobContainerClientGetPropertiesResult, BlobContainerClientGetPropertiesResultHeaders, - BlobImmutabilityPolicyMode, BlobType, BlockBlobClientCommitBlockListResult, - BlockBlobClientStageBlockResult, BlockBlobClientUploadResult, BlockList, BlockListType, - BlockLookupList, CopyStatus, LeaseState, LeaseStatus, PublicAccessType, RehydratePriority, - StorageServiceProperties, + BlobClientSetImmutabilityPolicyResult, BlobClientSetImmutabilityPolicyResultHeaders, + BlobContainerClientGetAccountInfoResultHeaders, BlobContainerClientGetPropertiesResult, + BlobContainerClientGetPropertiesResultHeaders, BlobImmutabilityPolicyMode, + BlobServiceClientGetAccountInfoResultHeaders, BlobType, + BlockBlobClientCommitBlockListResult, BlockBlobClientStageBlockResult, + BlockBlobClientUploadResult, BlockList, BlockListType, BlockLookupList, CopyStatus, + LeaseState, LeaseStatus, PublicAccessType, RehydratePriority, StorageServiceProperties, }; } diff --git a/sdk/storage/azure_storage_blob/tests/blob_client.rs b/sdk/storage/azure_storage_blob/tests/blob_client.rs index e0cec43d36..9538ee05b0 100644 --- a/sdk/storage/azure_storage_blob/tests/blob_client.rs +++ b/sdk/storage/azure_storage_blob/tests/blob_client.rs @@ -8,13 +8,16 @@ use azure_core::{ use azure_core_test::{recorded, TestContext}; use azure_storage_blob::{ models::{ - AccessTier, BlobClientDownloadResultHeaders, BlobClientGetPropertiesResultHeaders, - BlockListType, BlockLookupList, LeaseState, + AccessTier, AccountKind, BlobClientDownloadResultHeaders, + BlobClientGetAccountInfoResultHeaders, BlobClientGetPropertiesResultHeaders, + BlobImmutabilityPolicyMode, BlockListType, BlockLookupList, LeaseState, }, - BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, BlockBlobClientUploadOptions, + BlobClientSetImmutabilityPolicyOptions, BlobClientSetMetadataOptions, + BlobClientSetPropertiesOptions, BlockBlobClientUploadOptions, }; use azure_storage_blob_test::{create_test_blob, get_blob_client, get_container_client}; use std::{collections::HashMap, error::Error}; +use time::OffsetDateTime; #[recorded::test] async fn test_get_blob_properties(ctx: TestContext) -> Result<(), Box> { @@ -455,3 +458,73 @@ async fn test_set_access_tier(ctx: TestContext) -> Result<(), Box> { container_client.delete_container(None).await?; Ok(()) } + +#[recorded::test] +async fn test_get_account_info(ctx: TestContext) -> Result<(), Box> { + // Recording Setup + let recording = ctx.recording(); + let blob_client = get_blob_client(None, recording)?; + + // Act + let response = blob_client.get_account_info(None).await?; + + // Assert + let sku_name = response.sku_name()?; + let account_kind = response.account_kind()?; + + assert!(sku_name.is_some()); + assert_eq!(AccountKind::StorageV2, account_kind.unwrap()); + + Ok(()) +} + +#[recorded::test] +async fn test_immutability_policy(ctx: TestContext) -> Result<(), Box> { + // TODO: Support versioning, will also need some way to indicate this needs to be versioned + // TODO: In Python, we use the management client to enable ImmutableStorageWithVersioning + + // Recording Setup + let recording = ctx.recording(); + let container_client = get_container_client(recording)?; + let blob_client = get_blob_client( + Some(container_client.container_name().to_string()), + recording, + )?; + container_client.create_container(None).await?; + create_test_blob(&blob_client).await?; + + // Act + let response = blob_client.get_properties(None).await?; + let immutability_policy = response.immutability_policy_mode()?; + assert!(immutability_policy.is_none()); + + // Set Immutability Policy + let set_immutability_policy_options = BlobClientSetImmutabilityPolicyOptions { + immutability_policy_expiry: Some( + OffsetDateTime::now_utc().saturating_add(time::Duration::minutes(5)), + ), + immutability_policy_mode: Some(BlobImmutabilityPolicyMode::Unlocked), + ..Default::default() + }; + blob_client + .set_immutability_policy(Some(set_immutability_policy_options)) + .await?; + + let response = blob_client.get_properties(None).await?; + // Assert + let immutability_policy = response.immutability_policy_mode()?; + assert_eq!( + BlobImmutabilityPolicyMode::Mutable, + immutability_policy.unwrap() + ); + + // Delete Immutability Policy + blob_client.delete_immutability_policy(None).await?; + + let response = blob_client.get_properties(None).await?; + // Assert + let immutability_policy = response.immutability_policy_mode()?; + assert!(immutability_policy.is_none()); + + Ok(()) +} diff --git a/sdk/storage/azure_storage_blob/tests/blob_container_client.rs b/sdk/storage/azure_storage_blob/tests/blob_container_client.rs index e5f37eaa27..4bb7eefc79 100644 --- a/sdk/storage/azure_storage_blob/tests/blob_container_client.rs +++ b/sdk/storage/azure_storage_blob/tests/blob_container_client.rs @@ -4,7 +4,10 @@ use azure_core::http::StatusCode; use azure_core_test::{recorded, TestContext}; use azure_storage_blob::{ - models::{BlobContainerClientGetPropertiesResultHeaders, LeaseState}, + models::{ + AccountKind, BlobContainerClientGetAccountInfoResultHeaders, + BlobContainerClientGetPropertiesResultHeaders, LeaseState, + }, BlobContainerClientSetMetadataOptions, }; use azure_storage_blob_test::get_container_client; @@ -83,3 +86,22 @@ async fn test_set_container_metadata(ctx: TestContext) -> Result<(), Box Result<(), Box> { + // Recording Setup + let recording = ctx.recording(); + let container_client = get_container_client(recording)?; + + // Act + let response = container_client.get_account_info(None).await?; + + // Assert + let sku_name = response.sku_name()?; + let account_kind = response.account_kind()?; + + assert!(sku_name.is_some()); + assert_eq!(AccountKind::StorageV2, account_kind.unwrap()); + + Ok(()) +} diff --git a/sdk/storage/azure_storage_blob/tests/blob_service_client.rs b/sdk/storage/azure_storage_blob/tests/blob_service_client.rs index 957adfb2b4..12ae337aa4 100644 --- a/sdk/storage/azure_storage_blob/tests/blob_service_client.rs +++ b/sdk/storage/azure_storage_blob/tests/blob_service_client.rs @@ -2,7 +2,10 @@ // Licensed under the MIT License. use azure_core_test::{recorded, TestContext}; -use azure_storage_blob::BlobServiceClientGetPropertiesOptions; +use azure_storage_blob::{ + models::{AccountKind, BlobServiceClientGetAccountInfoResultHeaders}, + BlobServiceClientGetPropertiesOptions, +}; use azure_storage_blob_test::get_blob_service_client; use std::error::Error; @@ -22,3 +25,22 @@ async fn test_get_service_properties(ctx: TestContext) -> Result<(), Box Result<(), Box> { + // Recording Setup + let recording = ctx.recording(); + let service_client = get_blob_service_client(recording)?; + + // Act + let response = service_client.get_account_info(None).await?; + + // Assert + let sku_name = response.sku_name()?; + let account_kind = response.account_kind()?; + + assert!(sku_name.is_some()); + assert_eq!(AccountKind::StorageV2, account_kind.unwrap()); + + Ok(()) +}