Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions sdk/storage/azure_storage_blob/src/clients/blob_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@ use crate::{
generated::clients::PageBlobClient as GeneratedPageBlobClient,
generated::models::{
BlobClientAcquireLeaseResult, BlobClientBreakLeaseResult, BlobClientChangeLeaseResult,
BlobClientDownloadResult, BlobClientGetAccountInfoResult, BlobClientGetPropertiesResult,
BlobClientReleaseLeaseResult, BlobClientRenewLeaseResult, BlockBlobClientUploadResult,
BlobClientDeleteImmutabilityPolicyResult, BlobClientDownloadResult,
BlobClientGetAccountInfoResult, BlobClientGetPropertiesResult,
BlobClientReleaseLeaseResult, BlobClientRenewLeaseResult,
BlobClientSetImmutabilityPolicyResult, BlockBlobClientUploadResult,
},
models::{
AccessTier, BlobClientAcquireLeaseOptions, BlobClientBreakLeaseOptions,
BlobClientChangeLeaseOptions, BlobClientDeleteOptions, BlobClientDownloadOptions,
BlobClientGetAccountInfoOptions, BlobClientGetPropertiesOptions, BlobClientGetTagsOptions,
BlobClientReleaseLeaseOptions, BlobClientRenewLeaseOptions, BlobClientSetMetadataOptions,
BlobClientSetPropertiesOptions, BlobClientSetTagsOptions, BlobClientSetTierOptions,
BlobTags, BlockBlobClientUploadOptions, StorageErrorCode,
BlobClientChangeLeaseOptions, BlobClientDeleteImmutabilityPolicyOptions,
BlobClientDeleteOptions, BlobClientDownloadOptions, BlobClientGetAccountInfoOptions,
BlobClientGetPropertiesOptions, BlobClientGetTagsOptions, BlobClientReleaseLeaseOptions,
BlobClientRenewLeaseOptions, BlobClientSetImmutabilityPolicyOptions,
BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, BlobClientSetTagsOptions,
BlobClientSetTierOptions, BlobTags, BlockBlobClientUploadOptions, StorageErrorCode,
},
pipeline::StorageHeadersPolicy,
AppendBlobClient, BlobClientOptions, BlockBlobClient, PageBlobClient,
Expand Down Expand Up @@ -436,4 +439,28 @@ impl BlobClient {
Err(e) => Err(e),
}
}

/// Sets the immutability policy on the blob.
///
/// # Arguments
///
/// * `options` - Optional configuration for the request.
pub async fn set_immutability_policy(
&self,
options: Option<BlobClientSetImmutabilityPolicyOptions<'_>>,
) -> Result<Response<BlobClientSetImmutabilityPolicyResult, NoFormat>> {
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<BlobClientDeleteImmutabilityPolicyOptions<'_>>,
) -> Result<Response<BlobClientDeleteImmutabilityPolicyResult, NoFormat>> {
self.client.delete_immutability_policy(options).await
}
}
30 changes: 15 additions & 15 deletions sdk/storage/azure_storage_blob/src/generated/models/enums_impl.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions sdk/storage/azure_storage_blob/src/models/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// Licensed under the MIT License.

use crate::models::{
AppendBlobClientCreateOptions, BlobTag, BlobTags, BlockBlobClientUploadBlobFromUrlOptions,
BlockBlobClientUploadOptions, PageBlobClientCreateOptions,
AppendBlobClientCreateOptions, BlobImmutabilityPolicyMode, BlobTag, BlobTags,
BlockBlobClientUploadBlobFromUrlOptions, BlockBlobClientUploadOptions, ImmutabilityPolicyMode,
PageBlobClientCreateOptions,
};
use std::collections::HashMap;

Expand Down Expand Up @@ -108,3 +109,13 @@ impl From<HashMap<String, String>> for BlobTags {
}
}
}

// Converts a `ImmutabilityPolicyMode` into an `BlobImmutabilityPolicyMode`.
impl From<ImmutabilityPolicyMode> for BlobImmutabilityPolicyMode {
fn from(mode: ImmutabilityPolicyMode) -> Self {
match mode {
ImmutabilityPolicyMode::Locked => BlobImmutabilityPolicyMode::Locked,
ImmutabilityPolicyMode::Unlocked => BlobImmutabilityPolicyMode::Unlocked,
}
}
}
19 changes: 10 additions & 9 deletions sdk/storage/azure_storage_blob/src/models/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ pub use crate::generated::models::{
BlobClientBreakLeaseResultHeaders, BlobClientChangeLeaseOptions, BlobClientChangeLeaseResult,
BlobClientChangeLeaseResultHeaders, BlobClientCopyFromUrlResult,
BlobClientCopyFromUrlResultHeaders, BlobClientCreateSnapshotResult,
BlobClientCreateSnapshotResultHeaders, BlobClientDeleteImmutabilityPolicyResult,
BlobClientDeleteImmutabilityPolicyResultHeaders, BlobClientDeleteOptions,
BlobClientDownloadOptions, BlobClientDownloadResult, BlobClientDownloadResultHeaders,
BlobClientGetAccountInfoOptions, BlobClientGetAccountInfoResult,
BlobClientGetAccountInfoResultHeaders, BlobClientGetPropertiesOptions,
BlobClientGetPropertiesResult, BlobClientGetPropertiesResultHeaders, BlobClientGetTagsOptions,
BlobClientReleaseLeaseOptions, BlobClientReleaseLeaseResult,
BlobClientReleaseLeaseResultHeaders, BlobClientRenewLeaseOptions, BlobClientRenewLeaseResult,
BlobClientRenewLeaseResultHeaders, BlobClientSetExpiryResult, BlobClientSetExpiryResultHeaders,
BlobClientCreateSnapshotResultHeaders, BlobClientDeleteImmutabilityPolicyOptions,
BlobClientDeleteImmutabilityPolicyResult, BlobClientDeleteImmutabilityPolicyResultHeaders,
BlobClientDeleteOptions, BlobClientDownloadOptions, BlobClientDownloadResult,
BlobClientDownloadResultHeaders, BlobClientGetAccountInfoOptions,
BlobClientGetAccountInfoResult, BlobClientGetAccountInfoResultHeaders,
BlobClientGetPropertiesOptions, BlobClientGetPropertiesResult,
BlobClientGetPropertiesResultHeaders, BlobClientGetTagsOptions, BlobClientReleaseLeaseOptions,
BlobClientReleaseLeaseResult, BlobClientReleaseLeaseResultHeaders, BlobClientRenewLeaseOptions,
BlobClientRenewLeaseResult, BlobClientRenewLeaseResultHeaders, BlobClientSetExpiryResult,
BlobClientSetExpiryResultHeaders, BlobClientSetImmutabilityPolicyOptions,
BlobClientSetImmutabilityPolicyResult, BlobClientSetImmutabilityPolicyResultHeaders,
BlobClientSetLegalHoldResult, BlobClientSetLegalHoldResultHeaders,
BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, BlobClientSetTagsOptions,
Expand Down
48 changes: 47 additions & 1 deletion sdk/storage/azure_storage_blob/tests/blob_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use azure_core::{
http::{ClientOptions, RequestContent, StatusCode},
time::OffsetDateTime,
Bytes,
};
use azure_core_test::{recorded, Matcher, TestContext};
Expand All @@ -12,8 +13,10 @@ use azure_storage_blob::{
BlobClientChangeLeaseResultHeaders, BlobClientDownloadOptions,
BlobClientDownloadResultHeaders, BlobClientGetAccountInfoResultHeaders,
BlobClientGetPropertiesOptions, BlobClientGetPropertiesResultHeaders,
BlobClientSetImmutabilityPolicyOptions, BlobClientSetImmutabilityPolicyResultHeaders,
BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, BlobClientSetTierOptions,
BlockBlobClientUploadOptions, LeaseState,
BlobImmutabilityPolicyMode, BlockBlobClientUploadOptions, ImmutabilityPolicyMode,
LeaseState,
},
BlobClient, BlobClientOptions, BlobContainerClient, BlobContainerClientOptions,
};
Expand Down Expand Up @@ -644,3 +647,46 @@ async fn test_encoding_edge_cases(ctx: TestContext) -> Result<(), Box<dyn Error>

Ok(())
}

#[recorded::test]
async fn test_immutability_policy(ctx: TestContext) -> Result<(), Box<dyn Error>> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing against a regular Storage account yields:

HTTP/1.1 400 ImmutableStorageWithVersioning: feature is not enabled.

Testing against versioned without immutable storage on:

ImmutableStorageWithVersioningIsNotEnabledImmutableStorageWithVersioning: feature is not enabled.

So, as a result, had to use a versioned account + immutable storage with versioning enabled.

As a result, having the same issues with deleting the container as set_legal_hold:

ContainerImmutableStorageWithVersioningEnabledThe requested operation is not allowed as the container has a immutable storage with versioning enabled.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mark as playback only for now, I guess. Open an issue to track getting proper clean up on this and the legal hold tests so we can enable them to run Live.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#3358
Done, will mark playback only once we get set_legal_hold merged since I unfortunately did not base it off of that PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't you update your test-resources.bicep file? That's the whole reason it's there and you should be using it, just like in all other languages (I wrote those original scripts for every Azure SDK language). I'd rather we don't have a confusing concept of "playback-only" tests. That implies you have to record them at some point which means modifying source which means people have to manually interject at least a couple times. Just use a #[tokio::test] with a MockHttpClient from our azure_core_test crate instead. I do that in lots of places. Pretty easy to use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heaths, we need to mark these tests as playback only because containers with immutability policies (and legal holds) are very difficult to clean up. They require the management plane to do so which we don't have yet in Rust. We will try and figure out a way to delete them and change them to regular recorded tests later. There is nothing that can be changed in the bicep to accomplish this.

We have the concept of playback only in every other language and we use it sparingly for situations like this. It would be nice to have that concept available in Rust. Mocking would require extra effort and means these tests will work and look different than the rest of our tests.

//TODO: Point to versioning account, add datetimes to recording variables
// Recording Setup
let recording = ctx.recording();
let container_client = get_container_client(recording, false).await?;
let blob_client = container_client.blob_client(&get_blob_name(recording));
container_client.create_container(None).await?;
create_test_blob(&blob_client, None, None).await?;
let test_expiry_time = Some(OffsetDateTime::now_utc() + Duration::from_secs(300));
let test_immutability_policy_mode = ImmutabilityPolicyMode::Unlocked;

// Set Immutability Policy
let immutability_policy_options = BlobClientSetImmutabilityPolicyOptions {
immutability_policy_expiry: test_expiry_time.clone(),
immutability_policy_mode: Some(test_immutability_policy_mode),
..Default::default()
};
let response = blob_client
.set_immutability_policy(Some(immutability_policy_options))
.await?;

// Assert
let mode = response.immutability_policy_mode()?;
let expires_on = response.immutability_policy_expires_on()?;

let response_mode: BlobImmutabilityPolicyMode = test_immutability_policy_mode.into();
assert_eq!(response_mode, mode.unwrap());
assert_eq!(test_expiry_time, expires_on);

// Delete Immutability Policy
blob_client.delete_immutability_policy(None).await?;
let response = blob_client.get_properties(None).await?;

// Assert
let mode = response.immutability_policy_mode()?;
let expires_on = response.immutability_policy_expires_on()?;
assert!(mode.is_none());
assert!(expires_on.is_none());

Ok(())
}
2 changes: 1 addition & 1 deletion sdk/storage/azure_storage_blob/tsp-location.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
directory: specification/storage/Microsoft.BlobStorage
commit: 6b5a0fdadca03abe0b8e91a68a62cd1e639ed55e
commit: 64da9cf708dfbae0ff9ca2cde6829b123d9966bb
repo: Azure/azure-rest-api-specs
additionalDirectories:
Loading