mirror of
https://github.com/minio/minio-rs.git
synced 2025-12-06 15:26:51 +08:00
Refactor bucket-lifecycle, bucket-policy, bucket-encryption (#124)
* refactored from_s3response trait, and refactored get/set/delete policy * * refactor set/get/delete bucket lifecycle * refactored from_s3response trait, * refactored get/set/delete bucket policy * delete-bucket-encryption
This commit is contained in:
parent
b2a6cb2655
commit
112c0aed1a
@ -30,17 +30,20 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||||||
|
|
||||||
let resp: GetBucketEncryptionResponse =
|
let resp: GetBucketEncryptionResponse =
|
||||||
client.get_bucket_encryption(bucket_name).send().await?;
|
client.get_bucket_encryption(bucket_name).send().await?;
|
||||||
log::info!("encryption before: config={:?}", resp.config,);
|
log::info!("encryption before: config={:?}", resp.config);
|
||||||
|
|
||||||
|
let config = SseConfig::default();
|
||||||
|
log::info!("going to set encryption config={:?}", config);
|
||||||
|
|
||||||
let _resp: SetBucketEncryptionResponse = client
|
let _resp: SetBucketEncryptionResponse = client
|
||||||
.set_bucket_encryption(bucket_name)
|
.set_bucket_encryption(bucket_name)
|
||||||
.sse_config(SseConfig::default())
|
.sse_config(config.clone())
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let resp: GetBucketEncryptionResponse =
|
let resp: GetBucketEncryptionResponse =
|
||||||
client.get_bucket_encryption(bucket_name).send().await?;
|
client.get_bucket_encryption(bucket_name).send().await?;
|
||||||
log::info!("encryption after: config={:?}", resp.config,);
|
log::info!("encryption after: config={:?}", resp.config);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,6 @@
|
|||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
use crate::common::{create_bucket_if_not_exists, create_client_on_play};
|
use crate::common::{create_bucket_if_not_exists, create_client_on_play};
|
||||||
use minio::s3::args::DeleteBucketLifecycleArgs;
|
|
||||||
use minio::s3::response::{
|
use minio::s3::response::{
|
||||||
DeleteBucketLifecycleResponse, GetBucketLifecycleResponse, SetBucketLifecycleResponse,
|
DeleteBucketLifecycleResponse, GetBucketLifecycleResponse, SetBucketLifecycleResponse,
|
||||||
};
|
};
|
||||||
@ -74,14 +73,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||||||
|
|
||||||
if false {
|
if false {
|
||||||
// TODO
|
// TODO
|
||||||
let resp: DeleteBucketLifecycleResponse = client
|
let resp: DeleteBucketLifecycleResponse =
|
||||||
.delete_bucket_lifecycle(&DeleteBucketLifecycleArgs {
|
client.delete_bucket_lifecycle(bucket_name).send().await?;
|
||||||
extra_headers: None,
|
|
||||||
extra_query_params: None,
|
|
||||||
region: None,
|
|
||||||
bucket: "",
|
|
||||||
})
|
|
||||||
.await?;
|
|
||||||
log::info!("response of deleting lifecycle config: resp={:?}", resp);
|
log::info!("response of deleting lifecycle config: resp={:?}", resp);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -1315,9 +1315,6 @@ impl<'a> ComposeObjectArgs<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Argument for [delete_bucket_encryption()](crate::s3::client::Client::delete_bucket_encryption) API
|
|
||||||
pub type DeleteBucketEncryptionArgs<'a> = BucketArgs<'a>;
|
|
||||||
|
|
||||||
/// Argument for [enable_object_legal_hold()](crate::s3::client::Client::enable_object_legal_hold) API
|
/// Argument for [enable_object_legal_hold()](crate::s3::client::Client::enable_object_legal_hold) API
|
||||||
pub type EnableObjectLegalHoldArgs<'a> = ObjectVersionArgs<'a>;
|
pub type EnableObjectLegalHoldArgs<'a> = ObjectVersionArgs<'a>;
|
||||||
|
|
||||||
@ -1327,12 +1324,6 @@ pub type DisableObjectLegalHoldArgs<'a> = ObjectVersionArgs<'a>;
|
|||||||
/// Argument for [is_object_legal_hold_enabled()](crate::s3::client::Client::is_object_legal_hold_enabled) API
|
/// Argument for [is_object_legal_hold_enabled()](crate::s3::client::Client::is_object_legal_hold_enabled) API
|
||||||
pub type IsObjectLegalHoldEnabledArgs<'a> = ObjectVersionArgs<'a>;
|
pub type IsObjectLegalHoldEnabledArgs<'a> = ObjectVersionArgs<'a>;
|
||||||
|
|
||||||
/// Argument for [delete_bucket_lifecycle()](crate::s3::client::Client::delete_bucket_lifecycle) API
|
|
||||||
pub type DeleteBucketLifecycleArgs<'a> = BucketArgs<'a>;
|
|
||||||
|
|
||||||
/// Argument for [get_bucket_lifecycle()](crate::s3::client::Client::get_bucket_lifecycle) API
|
|
||||||
pub type GetBucketLifecycleArgs<'a> = BucketArgs<'a>;
|
|
||||||
|
|
||||||
/// Argument for [delete_bucket_notification()](crate::s3::client::Client::delete_bucket_notification) API
|
/// Argument for [delete_bucket_notification()](crate::s3::client::Client::delete_bucket_notification) API
|
||||||
pub type DeleteBucketNotificationArgs<'a> = BucketArgs<'a>;
|
pub type DeleteBucketNotificationArgs<'a> = BucketArgs<'a>;
|
||||||
|
|
||||||
@ -1392,67 +1383,6 @@ impl<'a> SetBucketNotificationArgs<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Argument for [delete_bucket_policy()](crate::s3::client::Client::delete_bucket_policy) API
|
|
||||||
pub type DeleteBucketPolicyArgs<'a> = BucketArgs<'a>;
|
|
||||||
|
|
||||||
/// Argument for [get_bucket_policy()](crate::s3::client::Client::get_bucket_policy) API
|
|
||||||
pub type GetBucketPolicyArgs<'a> = BucketArgs<'a>;
|
|
||||||
|
|
||||||
/// Argument for [set_bucket_policy()](crate::s3::client::Client::set_bucket_policy) API
|
|
||||||
pub struct SetBucketPolicyArgs<'a> {
|
|
||||||
pub extra_headers: Option<&'a Multimap>,
|
|
||||||
pub extra_query_params: Option<&'a Multimap>,
|
|
||||||
pub region: Option<&'a str>,
|
|
||||||
pub bucket: &'a str,
|
|
||||||
pub config: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> SetBucketPolicyArgs<'a> {
|
|
||||||
/// Returns argument for [set_bucket_policy()](crate::s3::client::Client::set_bucket_policy) API with given bucket name and configuration
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use minio::s3::args::*;
|
|
||||||
/// let config = r#"{
|
|
||||||
/// "Version": "2012-10-17",
|
|
||||||
/// "Statement": [
|
|
||||||
/// {
|
|
||||||
/// "Effect": "Allow",
|
|
||||||
/// "Principal": {
|
|
||||||
/// "AWS": "*"
|
|
||||||
/// },
|
|
||||||
/// "Action": [
|
|
||||||
/// "s3:GetBucketLocation",
|
|
||||||
/// "s3:ListBucket"
|
|
||||||
/// ],
|
|
||||||
/// "Resource": "arn:aws:s3:::my-bucket"
|
|
||||||
/// },
|
|
||||||
/// {
|
|
||||||
/// "Effect": "Allow",
|
|
||||||
/// "Principal": {
|
|
||||||
/// "AWS": "*"
|
|
||||||
/// },
|
|
||||||
/// "Action": "s3:GetObject",
|
|
||||||
/// "Resource": "arn:aws:s3:::my-bucket/*"
|
|
||||||
/// }
|
|
||||||
/// ]
|
|
||||||
/// }"#;
|
|
||||||
/// let args = SetBucketPolicyArgs::new("my-bucket", config).unwrap();
|
|
||||||
/// ```
|
|
||||||
pub fn new(bucket_name: &'a str, config: &'a str) -> Result<SetBucketPolicyArgs<'a>, Error> {
|
|
||||||
check_bucket_name(bucket_name, true)?;
|
|
||||||
|
|
||||||
Ok(SetBucketPolicyArgs {
|
|
||||||
extra_headers: None,
|
|
||||||
extra_query_params: None,
|
|
||||||
region: None,
|
|
||||||
bucket: bucket_name,
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Argument for [delete_bucket_replication()](crate::s3::client::Client::delete_bucket_replication) API
|
/// Argument for [delete_bucket_replication()](crate::s3::client::Client::delete_bucket_replication) API
|
||||||
pub type DeleteBucketReplicationArgs<'a> = BucketArgs<'a>;
|
pub type DeleteBucketReplicationArgs<'a> = BucketArgs<'a>;
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,12 @@
|
|||||||
//! Argument builders for [minio::s3::client::Client](crate::s3::client::Client) APIs
|
//! Argument builders for [minio::s3::client::Client](crate::s3::client::Client) APIs
|
||||||
|
|
||||||
mod bucket_common;
|
mod bucket_common;
|
||||||
|
mod delete_bucket_encryption;
|
||||||
|
mod delete_bucket_lifecycle;
|
||||||
|
mod delete_bucket_policy;
|
||||||
mod get_bucket_encryption;
|
mod get_bucket_encryption;
|
||||||
mod get_bucket_lifecycle;
|
mod get_bucket_lifecycle;
|
||||||
|
mod get_bucket_policy;
|
||||||
mod get_bucket_versioning;
|
mod get_bucket_versioning;
|
||||||
mod get_object;
|
mod get_object;
|
||||||
mod list_buckets;
|
mod list_buckets;
|
||||||
@ -29,11 +33,16 @@ mod put_object;
|
|||||||
mod remove_objects;
|
mod remove_objects;
|
||||||
mod set_bucket_encryption;
|
mod set_bucket_encryption;
|
||||||
mod set_bucket_lifecycle;
|
mod set_bucket_lifecycle;
|
||||||
|
mod set_bucket_policy;
|
||||||
mod set_bucket_versioning;
|
mod set_bucket_versioning;
|
||||||
|
|
||||||
pub use bucket_common::*;
|
pub use bucket_common::*;
|
||||||
|
pub use delete_bucket_encryption::*;
|
||||||
|
pub use delete_bucket_lifecycle::*;
|
||||||
|
pub use delete_bucket_policy::*;
|
||||||
pub use get_bucket_encryption::*;
|
pub use get_bucket_encryption::*;
|
||||||
pub use get_bucket_lifecycle::*;
|
pub use get_bucket_lifecycle::*;
|
||||||
|
pub use get_bucket_policy::*;
|
||||||
pub use get_bucket_versioning::*;
|
pub use get_bucket_versioning::*;
|
||||||
pub use get_object::*;
|
pub use get_object::*;
|
||||||
pub use list_buckets::*;
|
pub use list_buckets::*;
|
||||||
@ -45,4 +54,5 @@ pub use put_object::*;
|
|||||||
pub use remove_objects::*;
|
pub use remove_objects::*;
|
||||||
pub use set_bucket_encryption::*;
|
pub use set_bucket_encryption::*;
|
||||||
pub use set_bucket_lifecycle::*;
|
pub use set_bucket_lifecycle::*;
|
||||||
|
pub use set_bucket_policy::*;
|
||||||
pub use set_bucket_versioning::*;
|
pub use set_bucket_versioning::*;
|
||||||
|
|||||||
63
src/s3/builders/delete_bucket_encryption.rs
Normal file
63
src/s3/builders/delete_bucket_encryption.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::builders::BucketCommon;
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::response::DeleteBucketEncryptionResponse;
|
||||||
|
use crate::s3::types::{S3Api, S3Request, ToS3Request};
|
||||||
|
use crate::s3::utils::check_bucket_name;
|
||||||
|
use crate::s3::Client;
|
||||||
|
use http::Method;
|
||||||
|
|
||||||
|
/// Argument builder for [delete_bucket_encryption()](Client::delete_bucket_encryption) API
|
||||||
|
pub type DeleteBucketEncryption = BucketCommon<DeleteBucketEncryptionPhantomData>;
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct DeleteBucketEncryptionPhantomData;
|
||||||
|
|
||||||
|
impl S3Api for DeleteBucketEncryption {
|
||||||
|
type S3Response = DeleteBucketEncryptionResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToS3Request for DeleteBucketEncryption {
|
||||||
|
fn to_s3request(&self) -> Result<S3Request, Error> {
|
||||||
|
check_bucket_name(&self.bucket, true)?;
|
||||||
|
|
||||||
|
let headers = self
|
||||||
|
.extra_headers
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
let mut query_params = self
|
||||||
|
.extra_query_params
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
query_params.insert("encryption".into(), String::new());
|
||||||
|
|
||||||
|
let client: &Client = self.client.as_ref().ok_or(Error::NoClientProvided)?;
|
||||||
|
|
||||||
|
let req = S3Request::new(client, Method::DELETE)
|
||||||
|
.region(self.region.as_deref())
|
||||||
|
.bucket(Some(&self.bucket))
|
||||||
|
.query_params(query_params)
|
||||||
|
.headers(headers);
|
||||||
|
|
||||||
|
Ok(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/s3/builders/delete_bucket_lifecycle.rs
Normal file
63
src/s3/builders/delete_bucket_lifecycle.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::builders::BucketCommon;
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::response::DeleteBucketLifecycleResponse;
|
||||||
|
use crate::s3::types::{S3Api, S3Request, ToS3Request};
|
||||||
|
use crate::s3::utils::check_bucket_name;
|
||||||
|
use crate::s3::Client;
|
||||||
|
use http::Method;
|
||||||
|
|
||||||
|
/// Argument builder for [delete_bucket_lifecycle()](Client::delete_bucket_lifecycle) API
|
||||||
|
pub type DeleteBucketLifecycle = BucketCommon<DeleteBucketLifecyclePhantomData>;
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct DeleteBucketLifecyclePhantomData;
|
||||||
|
|
||||||
|
impl S3Api for DeleteBucketLifecycle {
|
||||||
|
type S3Response = DeleteBucketLifecycleResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToS3Request for DeleteBucketLifecycle {
|
||||||
|
fn to_s3request(&self) -> Result<S3Request, Error> {
|
||||||
|
check_bucket_name(&self.bucket, true)?;
|
||||||
|
|
||||||
|
let headers = self
|
||||||
|
.extra_headers
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
let mut query_params = self
|
||||||
|
.extra_query_params
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
query_params.insert("lifecycle".into(), String::new());
|
||||||
|
|
||||||
|
let client: &Client = self.client.as_ref().ok_or(Error::NoClientProvided)?;
|
||||||
|
|
||||||
|
let req = S3Request::new(client, Method::DELETE)
|
||||||
|
.region(self.region.as_deref())
|
||||||
|
.bucket(Some(&self.bucket))
|
||||||
|
.query_params(query_params)
|
||||||
|
.headers(headers);
|
||||||
|
|
||||||
|
Ok(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/s3/builders/delete_bucket_policy.rs
Normal file
63
src/s3/builders/delete_bucket_policy.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::builders::BucketCommon;
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::response::DeleteBucketPolicyResponse;
|
||||||
|
use crate::s3::types::{S3Api, S3Request, ToS3Request};
|
||||||
|
use crate::s3::utils::check_bucket_name;
|
||||||
|
use crate::s3::Client;
|
||||||
|
use http::Method;
|
||||||
|
|
||||||
|
/// Argument builder for [delete_bucket_policy()](Client::delete_bucket_policy) API
|
||||||
|
pub type DeleteBucketPolicy = BucketCommon<DeleteBucketPolicyPhantomData>;
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct DeleteBucketPolicyPhantomData;
|
||||||
|
|
||||||
|
impl S3Api for DeleteBucketPolicy {
|
||||||
|
type S3Response = DeleteBucketPolicyResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToS3Request for DeleteBucketPolicy {
|
||||||
|
fn to_s3request(&self) -> Result<S3Request, Error> {
|
||||||
|
check_bucket_name(&self.bucket, true)?;
|
||||||
|
|
||||||
|
let headers = self
|
||||||
|
.extra_headers
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
let mut query_params = self
|
||||||
|
.extra_query_params
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
query_params.insert(String::from("policy"), String::new());
|
||||||
|
|
||||||
|
let client: &Client = self.client.as_ref().ok_or(Error::NoClientProvided)?;
|
||||||
|
|
||||||
|
let req = S3Request::new(client, Method::DELETE)
|
||||||
|
.region(self.region.as_deref())
|
||||||
|
.bucket(Some(&self.bucket))
|
||||||
|
.query_params(query_params)
|
||||||
|
.headers(headers);
|
||||||
|
|
||||||
|
Ok(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/s3/builders/get_bucket_policy.rs
Normal file
63
src/s3/builders/get_bucket_policy.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::builders::BucketCommon;
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::response::GetBucketPolicyResponse;
|
||||||
|
use crate::s3::types::{S3Api, S3Request, ToS3Request};
|
||||||
|
use crate::s3::utils::check_bucket_name;
|
||||||
|
use crate::s3::Client;
|
||||||
|
use http::Method;
|
||||||
|
|
||||||
|
/// Argument builder for [get_bucket_policy()](Client::get_bucket_policy) API
|
||||||
|
pub type GetBucketPolicy = BucketCommon<GetBucketPolicyPhantomData>;
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct GetBucketPolicyPhantomData;
|
||||||
|
|
||||||
|
impl S3Api for GetBucketPolicy {
|
||||||
|
type S3Response = GetBucketPolicyResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToS3Request for GetBucketPolicy {
|
||||||
|
fn to_s3request(&self) -> Result<S3Request, Error> {
|
||||||
|
check_bucket_name(&self.bucket, true)?;
|
||||||
|
|
||||||
|
let headers = self
|
||||||
|
.extra_headers
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
let mut query_params = self
|
||||||
|
.extra_query_params
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
query_params.insert(String::from("policy"), String::new());
|
||||||
|
|
||||||
|
let client: &Client = self.client.as_ref().ok_or(Error::NoClientProvided)?;
|
||||||
|
|
||||||
|
let req = S3Request::new(client, Method::GET)
|
||||||
|
.region(self.region.as_deref())
|
||||||
|
.bucket(Some(&self.bucket))
|
||||||
|
.query_params(query_params)
|
||||||
|
.headers(headers);
|
||||||
|
|
||||||
|
Ok(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
108
src/s3/builders/set_bucket_policy.rs
Normal file
108
src/s3/builders/set_bucket_policy.rs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::builders::SegmentedBytes;
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::response::SetBucketLifecycleResponse;
|
||||||
|
use crate::s3::types::{S3Api, S3Request, ToS3Request};
|
||||||
|
use crate::s3::utils::{check_bucket_name, Multimap};
|
||||||
|
use crate::s3::Client;
|
||||||
|
use bytes::Bytes;
|
||||||
|
use http::Method;
|
||||||
|
|
||||||
|
/// Argument builder for [set_bucket_policy()](crate::s3::client::Client::set_bucket_policy) API
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct SetBucketPolicy {
|
||||||
|
pub(crate) client: Option<Client>,
|
||||||
|
|
||||||
|
pub(crate) extra_headers: Option<Multimap>,
|
||||||
|
pub(crate) extra_query_params: Option<Multimap>,
|
||||||
|
pub(crate) region: Option<String>,
|
||||||
|
pub(crate) bucket: String,
|
||||||
|
|
||||||
|
pub(crate) config: String, //TODO consider PolicyConfig struct
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SetBucketPolicy {
|
||||||
|
pub fn new(bucket: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
bucket: bucket.to_owned(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn client(mut self, client: &Client) -> Self {
|
||||||
|
self.client = Some(client.clone());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extra_headers(mut self, extra_headers: Option<Multimap>) -> Self {
|
||||||
|
self.extra_headers = extra_headers;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extra_query_params(mut self, extra_query_params: Option<Multimap>) -> Self {
|
||||||
|
self.extra_query_params = extra_query_params;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn region(mut self, region: Option<String>) -> Self {
|
||||||
|
self.region = region;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn config(mut self, config: String) -> Self {
|
||||||
|
self.config = config;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl S3Api for SetBucketPolicy {
|
||||||
|
type S3Response = SetBucketLifecycleResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToS3Request for SetBucketPolicy {
|
||||||
|
fn to_s3request(&self) -> Result<S3Request, Error> {
|
||||||
|
check_bucket_name(&self.bucket, true)?;
|
||||||
|
|
||||||
|
let headers = self
|
||||||
|
.extra_headers
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
let mut query_params = self
|
||||||
|
.extra_query_params
|
||||||
|
.as_ref()
|
||||||
|
.filter(|v| !v.is_empty())
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
query_params.insert(String::from("policy"), String::new());
|
||||||
|
|
||||||
|
let bytes: Bytes = self.config.to_string().into();
|
||||||
|
let body: Option<SegmentedBytes> = Some(SegmentedBytes::from(bytes));
|
||||||
|
|
||||||
|
let client: &Client = self.client.as_ref().ok_or(Error::NoClientProvided)?;
|
||||||
|
|
||||||
|
let req = S3Request::new(client, Method::PUT)
|
||||||
|
.region(self.region.as_deref())
|
||||||
|
.bucket(Some(&self.bucket))
|
||||||
|
.query_params(query_params)
|
||||||
|
.headers(headers)
|
||||||
|
.body(body);
|
||||||
|
|
||||||
|
Ok(req)
|
||||||
|
}
|
||||||
|
}
|
||||||
341
src/s3/client.rs
341
src/s3/client.rs
@ -46,8 +46,12 @@ use tokio::fs;
|
|||||||
|
|
||||||
use xmltree::Element;
|
use xmltree::Element;
|
||||||
|
|
||||||
|
mod delete_bucket_encryption;
|
||||||
|
mod delete_bucket_lifecycle;
|
||||||
|
mod delete_bucket_policy;
|
||||||
mod get_bucket_encryption;
|
mod get_bucket_encryption;
|
||||||
mod get_bucket_lifecycle;
|
mod get_bucket_lifecycle;
|
||||||
|
mod get_bucket_policy;
|
||||||
mod get_bucket_versioning;
|
mod get_bucket_versioning;
|
||||||
mod get_object;
|
mod get_object;
|
||||||
mod list_objects;
|
mod list_objects;
|
||||||
@ -57,6 +61,7 @@ mod put_object;
|
|||||||
mod remove_objects;
|
mod remove_objects;
|
||||||
mod set_bucket_encryption;
|
mod set_bucket_encryption;
|
||||||
mod set_bucket_lifecycle;
|
mod set_bucket_lifecycle;
|
||||||
|
mod set_bucket_policy;
|
||||||
mod set_bucket_versioning;
|
mod set_bucket_versioning;
|
||||||
|
|
||||||
use super::builders::{ListBuckets, SegmentedBytes};
|
use super::builders::{ListBuckets, SegmentedBytes};
|
||||||
@ -1173,56 +1178,6 @@ impl Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_bucket_encryption(
|
|
||||||
&self,
|
|
||||||
args: &DeleteBucketEncryptionArgs<'_>,
|
|
||||||
) -> Result<DeleteBucketEncryptionResponse, Error> {
|
|
||||||
let region = self.get_region(args.bucket, args.region).await?;
|
|
||||||
|
|
||||||
let mut headers = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_headers {
|
|
||||||
merge(&mut headers, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut query_params = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_query_params {
|
|
||||||
merge(&mut query_params, v);
|
|
||||||
}
|
|
||||||
query_params.insert(String::from("encryption"), String::new());
|
|
||||||
|
|
||||||
match self
|
|
||||||
.execute(
|
|
||||||
Method::DELETE,
|
|
||||||
®ion,
|
|
||||||
&mut headers,
|
|
||||||
&query_params,
|
|
||||||
Some(args.bucket),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(resp) => Ok(DeleteBucketEncryptionResponse {
|
|
||||||
headers: resp.headers().clone(),
|
|
||||||
region: region.clone(),
|
|
||||||
bucket: args.bucket.to_string(),
|
|
||||||
}),
|
|
||||||
Err(e) => match e {
|
|
||||||
Error::S3Error(ref err) => {
|
|
||||||
if err.code == "ServerSideEncryptionConfigurationNotFoundError" {
|
|
||||||
return Ok(DeleteBucketEncryptionResponse {
|
|
||||||
headers: HeaderMap::new(),
|
|
||||||
region: region.clone(),
|
|
||||||
bucket: args.bucket.to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(e)
|
|
||||||
}
|
|
||||||
_ => Err(e),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn disable_object_legal_hold(
|
pub async fn disable_object_legal_hold(
|
||||||
&self,
|
&self,
|
||||||
args: &DisableObjectLegalHoldArgs<'_>,
|
args: &DisableObjectLegalHoldArgs<'_>,
|
||||||
@ -1266,42 +1221,6 @@ impl Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_bucket_lifecycle(
|
|
||||||
&self,
|
|
||||||
args: &DeleteBucketLifecycleArgs<'_>,
|
|
||||||
) -> Result<DeleteBucketLifecycleResponse, Error> {
|
|
||||||
let region = self.get_region(args.bucket, args.region).await?;
|
|
||||||
|
|
||||||
let mut headers = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_headers {
|
|
||||||
merge(&mut headers, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut query_params = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_query_params {
|
|
||||||
merge(&mut query_params, v);
|
|
||||||
}
|
|
||||||
query_params.insert(String::from("lifecycle"), String::new());
|
|
||||||
|
|
||||||
let resp = self
|
|
||||||
.execute(
|
|
||||||
Method::DELETE,
|
|
||||||
®ion,
|
|
||||||
&mut headers,
|
|
||||||
&query_params,
|
|
||||||
Some(args.bucket),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(DeleteBucketLifecycleResponse {
|
|
||||||
headers: resp.headers().clone(),
|
|
||||||
region: region.clone(),
|
|
||||||
bucket: args.bucket.to_string(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn delete_bucket_notification(
|
pub async fn delete_bucket_notification(
|
||||||
&self,
|
&self,
|
||||||
args: &DeleteBucketNotificationArgs<'_>,
|
args: &DeleteBucketNotificationArgs<'_>,
|
||||||
@ -1320,56 +1239,6 @@ impl Client {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_bucket_policy(
|
|
||||||
&self,
|
|
||||||
args: &DeleteBucketPolicyArgs<'_>,
|
|
||||||
) -> Result<DeleteBucketPolicyResponse, Error> {
|
|
||||||
let region = self.get_region(args.bucket, args.region).await?;
|
|
||||||
|
|
||||||
let mut headers = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_headers {
|
|
||||||
merge(&mut headers, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut query_params = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_query_params {
|
|
||||||
merge(&mut query_params, v);
|
|
||||||
}
|
|
||||||
query_params.insert(String::from("policy"), String::new());
|
|
||||||
|
|
||||||
match self
|
|
||||||
.execute(
|
|
||||||
Method::DELETE,
|
|
||||||
®ion,
|
|
||||||
&mut headers,
|
|
||||||
&query_params,
|
|
||||||
Some(args.bucket),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(resp) => Ok(DeleteBucketPolicyResponse {
|
|
||||||
headers: resp.headers().clone(),
|
|
||||||
region: region.clone(),
|
|
||||||
bucket: args.bucket.to_string(),
|
|
||||||
}),
|
|
||||||
Err(e) => match e {
|
|
||||||
Error::S3Error(ref err) => {
|
|
||||||
if err.code == "NoSuchBucketPolicy" {
|
|
||||||
return Ok(DeleteBucketPolicyResponse {
|
|
||||||
headers: HeaderMap::new(),
|
|
||||||
region: region.clone(),
|
|
||||||
bucket: args.bucket.to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(e)
|
|
||||||
}
|
|
||||||
_ => Err(e),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn delete_bucket_replication(
|
pub async fn delete_bucket_replication(
|
||||||
&self,
|
&self,
|
||||||
args: &DeleteBucketReplicationArgs<'_>,
|
args: &DeleteBucketReplicationArgs<'_>,
|
||||||
@ -1387,7 +1256,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
query_params.insert(String::from("replication"), String::new());
|
query_params.insert(String::from("replication"), String::new());
|
||||||
|
|
||||||
match self
|
let resp = self
|
||||||
.execute(
|
.execute(
|
||||||
Method::DELETE,
|
Method::DELETE,
|
||||||
®ion,
|
®ion,
|
||||||
@ -1397,26 +1266,23 @@ impl Client {
|
|||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await;
|
||||||
{
|
match resp {
|
||||||
Ok(resp) => Ok(DeleteBucketReplicationResponse {
|
Ok(resp) => Ok(DeleteBucketReplicationResponse {
|
||||||
headers: resp.headers().clone(),
|
headers: resp.headers().clone(),
|
||||||
region: region.clone(),
|
region: region.clone(),
|
||||||
bucket: args.bucket.to_string(),
|
bucket: args.bucket.to_string(),
|
||||||
}),
|
}),
|
||||||
Err(e) => match e {
|
Err(Error::S3Error(ref err))
|
||||||
Error::S3Error(ref err) => {
|
if err.code == Error::ReplicationConfigurationNotFoundError.as_str() =>
|
||||||
if err.code == "ReplicationConfigurationNotFoundError" {
|
{
|
||||||
return Ok(DeleteBucketReplicationResponse {
|
Ok(DeleteBucketReplicationResponse {
|
||||||
headers: HeaderMap::new(),
|
headers: HeaderMap::new(),
|
||||||
region: region.clone(),
|
region: region.clone(),
|
||||||
bucket: args.bucket.to_string(),
|
bucket: args.bucket.to_string(),
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
Err(e)
|
Err(e) => Err(e),
|
||||||
}
|
|
||||||
_ => Err(e),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1648,58 +1514,6 @@ impl Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_bucket_policy(
|
|
||||||
&self,
|
|
||||||
args: &GetBucketPolicyArgs<'_>,
|
|
||||||
) -> Result<GetBucketPolicyResponse, Error> {
|
|
||||||
let region = self.get_region(args.bucket, args.region).await?;
|
|
||||||
|
|
||||||
let mut headers = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_headers {
|
|
||||||
merge(&mut headers, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut query_params = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_query_params {
|
|
||||||
merge(&mut query_params, v);
|
|
||||||
}
|
|
||||||
query_params.insert(String::from("policy"), String::new());
|
|
||||||
|
|
||||||
match self
|
|
||||||
.execute(
|
|
||||||
Method::GET,
|
|
||||||
®ion,
|
|
||||||
&mut headers,
|
|
||||||
&query_params,
|
|
||||||
Some(args.bucket),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(resp) => Ok(GetBucketPolicyResponse {
|
|
||||||
headers: resp.headers().clone(),
|
|
||||||
region: region.clone(),
|
|
||||||
bucket_name: args.bucket.to_string(),
|
|
||||||
config: resp.text().await?,
|
|
||||||
}),
|
|
||||||
Err(e) => match e {
|
|
||||||
Error::S3Error(ref err) => {
|
|
||||||
if err.code == "NoSuchBucketPolicy" {
|
|
||||||
return Ok(GetBucketPolicyResponse {
|
|
||||||
headers: HeaderMap::new(),
|
|
||||||
region: region.clone(),
|
|
||||||
bucket_name: args.bucket.to_string(),
|
|
||||||
config: String::from("{}"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Err(e)
|
|
||||||
}
|
|
||||||
_ => Err(e),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_bucket_replication(
|
pub async fn get_bucket_replication(
|
||||||
&self,
|
&self,
|
||||||
args: &GetBucketReplicationArgs<'_>,
|
args: &GetBucketReplicationArgs<'_>,
|
||||||
@ -1790,20 +1604,15 @@ impl Client {
|
|||||||
tags,
|
tags,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(Error::S3Error(ref err)) if err.code == Error::NoSuchTagSet.as_str() => {
|
||||||
Error::S3Error(ref err) => {
|
Ok(GetBucketTagsResponse {
|
||||||
if err.code == "NoSuchTagSet" {
|
headers: HeaderMap::new(),
|
||||||
return Ok(GetBucketTagsResponse {
|
region: region.clone(),
|
||||||
headers: HeaderMap::new(),
|
bucket_name: args.bucket.to_string(),
|
||||||
region: region.clone(),
|
tags: HashMap::new(),
|
||||||
bucket_name: args.bucket.to_string(),
|
})
|
||||||
tags: HashMap::new(),
|
}
|
||||||
});
|
Err(e) => Err(e),
|
||||||
}
|
|
||||||
Err(e)
|
|
||||||
}
|
|
||||||
_ => Err(e),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1937,23 +1746,20 @@ impl Client {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(Error::S3Error(ref err))
|
||||||
Error::S3Error(ref err) => {
|
if err.code == Error::NoSuchObjectLockConfiguration.as_str() =>
|
||||||
if err.code == "NoSuchObjectLockConfiguration" {
|
{
|
||||||
return Ok(GetObjectRetentionResponse {
|
Ok(GetObjectRetentionResponse {
|
||||||
headers: HeaderMap::new(),
|
headers: HeaderMap::new(),
|
||||||
region: region.clone(),
|
region: region.clone(),
|
||||||
bucket_name: args.bucket.to_string(),
|
bucket_name: args.bucket.to_string(),
|
||||||
object_name: args.object.to_string(),
|
object_name: args.object.to_string(),
|
||||||
version_id: args.version_id.as_ref().map(|v| v.to_string()),
|
version_id: args.version_id.as_ref().map(|v| v.to_string()),
|
||||||
retention_mode: None,
|
retention_mode: None,
|
||||||
retain_until_date: None,
|
retain_until_date: None,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
Err(e)
|
Err(e) => Err(e),
|
||||||
}
|
|
||||||
_ => Err(e),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2133,22 +1939,19 @@ impl Client {
|
|||||||
enabled: get_default_text(&root, "Status") == "ON",
|
enabled: get_default_text(&root, "Status") == "ON",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(Error::S3Error(ref err))
|
||||||
Error::S3Error(ref err) => {
|
if err.code == Error::NoSuchObjectLockConfiguration.as_str() =>
|
||||||
if err.code == "NoSuchObjectLockConfiguration" {
|
{
|
||||||
return Ok(IsObjectLegalHoldEnabledResponse {
|
Ok(IsObjectLegalHoldEnabledResponse {
|
||||||
headers: HeaderMap::new(),
|
headers: HeaderMap::new(),
|
||||||
region: region.clone(),
|
region: region.clone(),
|
||||||
bucket_name: args.bucket.to_string(),
|
bucket_name: args.bucket.to_string(),
|
||||||
object_name: args.object.to_string(),
|
object_name: args.object.to_string(),
|
||||||
version_id: args.version_id.as_ref().map(|v| v.to_string()),
|
version_id: args.version_id.as_ref().map(|v| v.to_string()),
|
||||||
enabled: false,
|
enabled: false,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
Err(e)
|
Err(e) => Err(e),
|
||||||
}
|
|
||||||
_ => Err(e),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2504,42 +2307,6 @@ impl Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_bucket_policy(
|
|
||||||
&self,
|
|
||||||
args: &SetBucketPolicyArgs<'_>,
|
|
||||||
) -> Result<SetBucketPolicyResponse, Error> {
|
|
||||||
let region = self.get_region(args.bucket, args.region).await?;
|
|
||||||
|
|
||||||
let mut headers = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_headers {
|
|
||||||
merge(&mut headers, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut query_params = Multimap::new();
|
|
||||||
if let Some(v) = &args.extra_query_params {
|
|
||||||
merge(&mut query_params, v);
|
|
||||||
}
|
|
||||||
query_params.insert(String::from("policy"), String::new());
|
|
||||||
|
|
||||||
let resp = self
|
|
||||||
.execute(
|
|
||||||
Method::PUT,
|
|
||||||
®ion,
|
|
||||||
&mut headers,
|
|
||||||
&query_params,
|
|
||||||
Some(args.bucket),
|
|
||||||
None,
|
|
||||||
Some(args.config.to_string().into()),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(SetBucketPolicyResponse {
|
|
||||||
headers: resp.headers().clone(),
|
|
||||||
region: region.clone(),
|
|
||||||
bucket: args.bucket.to_string(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn set_bucket_replication(
|
pub async fn set_bucket_replication(
|
||||||
&self,
|
&self,
|
||||||
args: &SetBucketReplicationArgs<'_>,
|
args: &SetBucketReplicationArgs<'_>,
|
||||||
|
|||||||
26
src/s3/client/delete_bucket_encryption.rs
Normal file
26
src/s3/client/delete_bucket_encryption.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! S3 APIs for bucket objects.
|
||||||
|
|
||||||
|
use super::Client;
|
||||||
|
use crate::s3::builders::DeleteBucketEncryption;
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Create a DeleteBucketEncryption request builder.
|
||||||
|
pub fn delete_bucket_encryption(&self, bucket: &str) -> DeleteBucketEncryption {
|
||||||
|
DeleteBucketEncryption::new(bucket).client(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/s3/client/delete_bucket_lifecycle.rs
Normal file
26
src/s3/client/delete_bucket_lifecycle.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! S3 APIs for bucket objects.
|
||||||
|
|
||||||
|
use super::Client;
|
||||||
|
use crate::s3::builders::DeleteBucketLifecycle;
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Create a DeleteBucketLifecycle request builder.
|
||||||
|
pub fn delete_bucket_lifecycle(&self, bucket: &str) -> DeleteBucketLifecycle {
|
||||||
|
DeleteBucketLifecycle::new(bucket).client(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/s3/client/delete_bucket_policy.rs
Normal file
26
src/s3/client/delete_bucket_policy.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! S3 APIs for bucket objects.
|
||||||
|
|
||||||
|
use super::Client;
|
||||||
|
use crate::s3::builders::DeleteBucketPolicy;
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Create a DeleteBucketPolicy request builder.
|
||||||
|
pub fn delete_bucket_policy(&self, bucket: &str) -> DeleteBucketPolicy {
|
||||||
|
DeleteBucketPolicy::new(bucket).client(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/s3/client/get_bucket_policy.rs
Normal file
26
src/s3/client/get_bucket_policy.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! S3 APIs for bucket objects.
|
||||||
|
|
||||||
|
use super::Client;
|
||||||
|
use crate::s3::builders::GetBucketPolicy;
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Create a GetBucketPolicy request builder.
|
||||||
|
pub fn get_bucket_policy(&self, bucket: &str) -> GetBucketPolicy {
|
||||||
|
GetBucketPolicy::new(bucket).client(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
69
src/s3/client/set_bucket_policy.rs
Normal file
69
src/s3/client/set_bucket_policy.rs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! S3 APIs for bucket objects.
|
||||||
|
|
||||||
|
use super::Client;
|
||||||
|
use crate::s3::builders::SetBucketPolicy;
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Create a SetBucketPolicy request builder.
|
||||||
|
///
|
||||||
|
/// Returns argument for [set_bucket_policy()](crate::s3::client::Client::set_bucket_policy) API with given bucket name and configuration
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
|
/// use minio::s3::Client;
|
||||||
|
/// use minio::s3::types::{Filter, LifecycleConfig, LifecycleRule, S3Api};
|
||||||
|
///
|
||||||
|
/// #[tokio::main]
|
||||||
|
/// async fn main() {
|
||||||
|
/// use minio::s3::args::*;
|
||||||
|
/// let config = r#"{
|
||||||
|
/// "Version": "2012-10-17",
|
||||||
|
/// "Statement": [
|
||||||
|
/// {
|
||||||
|
/// "Effect": "Allow",
|
||||||
|
/// "Principal": {
|
||||||
|
/// "AWS": "*"
|
||||||
|
/// },
|
||||||
|
/// "Action": [
|
||||||
|
/// "s3:GetBucketLocation",
|
||||||
|
/// "s3:ListBucket"
|
||||||
|
/// ],
|
||||||
|
/// "Resource": "arn:aws:s3:::my-bucket"
|
||||||
|
/// },
|
||||||
|
/// {
|
||||||
|
/// "Effect": "Allow",
|
||||||
|
/// "Principal": {
|
||||||
|
/// "AWS": "*"
|
||||||
|
/// },
|
||||||
|
/// "Action": "s3:GetObject",
|
||||||
|
/// "Resource": "arn:aws:s3:::my-bucket-name/*"
|
||||||
|
/// }
|
||||||
|
/// ]
|
||||||
|
/// }"#;
|
||||||
|
/// let client = Client::default();
|
||||||
|
/// let _resp = client
|
||||||
|
/// .set_bucket_policy("my-bucket-name")
|
||||||
|
/// .config(config).
|
||||||
|
/// .send().await.unwrap();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn set_bucket_policy(&self, bucket: &str) -> SetBucketPolicy {
|
||||||
|
SetBucketPolicy::new(bucket).client(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -116,6 +116,11 @@ pub enum Error {
|
|||||||
NoClientProvided,
|
NoClientProvided,
|
||||||
TagDecodingError(String, String),
|
TagDecodingError(String, String),
|
||||||
ContentLengthUnknown,
|
ContentLengthUnknown,
|
||||||
|
|
||||||
|
NoSuchTagSet,
|
||||||
|
ReplicationConfigurationNotFoundError,
|
||||||
|
NoSuchObjectLockConfiguration,
|
||||||
|
NoSuchBucketPolicy,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for Error {}
|
impl std::error::Error for Error {}
|
||||||
@ -226,6 +231,22 @@ impl fmt::Display for Error {
|
|||||||
Error::NoClientProvided => write!(f, "no client provided"),
|
Error::NoClientProvided => write!(f, "no client provided"),
|
||||||
Error::TagDecodingError(input, error_message) => write!(f, "tag decoding failed: {} on input '{}'", error_message, input),
|
Error::TagDecodingError(input, error_message) => write!(f, "tag decoding failed: {} on input '{}'", error_message, input),
|
||||||
Error::ContentLengthUnknown => write!(f, "content length is unknown"),
|
Error::ContentLengthUnknown => write!(f, "content length is unknown"),
|
||||||
|
Error::NoSuchTagSet => write!(f, "no such tag set"),
|
||||||
|
Error::ReplicationConfigurationNotFoundError => write!(f, "Replication configuration not found"),
|
||||||
|
Error::NoSuchObjectLockConfiguration => write!(f, "no such object lock"),
|
||||||
|
Error::NoSuchBucketPolicy => write!(f, "no such bucket policy"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Error::NoSuchTagSet => "NoSuchTagSet",
|
||||||
|
Error::ReplicationConfigurationNotFoundError => "ReplicationConfigurationNotFoundError",
|
||||||
|
Error::NoSuchObjectLockConfiguration => "NoSuchObjectLockConfiguration",
|
||||||
|
Error::NoSuchBucketPolicy => "NoSuchBucketPolicy",
|
||||||
|
_ => "TODO",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,8 +31,12 @@ use crate::s3::utils::{
|
|||||||
copy_slice, crc32, from_http_header_value, from_iso8601utc, get_text, uint32, UtcTime,
|
copy_slice, crc32, from_http_header_value, from_iso8601utc, get_text, uint32, UtcTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod delete_bucket_encryption;
|
||||||
|
mod delete_bucket_lifecycle;
|
||||||
|
mod delete_bucket_policy;
|
||||||
mod get_bucket_encryption;
|
mod get_bucket_encryption;
|
||||||
mod get_bucket_lifecycle;
|
mod get_bucket_lifecycle;
|
||||||
|
mod get_bucket_policy;
|
||||||
mod get_bucket_versioning;
|
mod get_bucket_versioning;
|
||||||
mod get_object;
|
mod get_object;
|
||||||
mod list_buckets;
|
mod list_buckets;
|
||||||
@ -43,10 +47,15 @@ mod put_object;
|
|||||||
mod remove_objects;
|
mod remove_objects;
|
||||||
mod set_bucket_encryption;
|
mod set_bucket_encryption;
|
||||||
mod set_bucket_lifecycle;
|
mod set_bucket_lifecycle;
|
||||||
|
mod set_bucket_policy;
|
||||||
mod set_bucket_versioning;
|
mod set_bucket_versioning;
|
||||||
|
|
||||||
|
pub use delete_bucket_encryption::DeleteBucketEncryptionResponse;
|
||||||
|
pub use delete_bucket_lifecycle::DeleteBucketLifecycleResponse;
|
||||||
|
pub use delete_bucket_policy::DeleteBucketPolicyResponse;
|
||||||
pub use get_bucket_encryption::GetBucketEncryptionResponse;
|
pub use get_bucket_encryption::GetBucketEncryptionResponse;
|
||||||
pub use get_bucket_lifecycle::GetBucketLifecycleResponse;
|
pub use get_bucket_lifecycle::GetBucketLifecycleResponse;
|
||||||
|
pub use get_bucket_policy::GetBucketPolicyResponse;
|
||||||
pub use get_bucket_versioning::GetBucketVersioningResponse;
|
pub use get_bucket_versioning::GetBucketVersioningResponse;
|
||||||
pub use get_object::GetObjectResponse;
|
pub use get_object::GetObjectResponse;
|
||||||
pub use list_buckets::ListBucketsResponse;
|
pub use list_buckets::ListBucketsResponse;
|
||||||
@ -61,6 +70,7 @@ pub use put_object::{
|
|||||||
pub use remove_objects::{DeleteError, DeletedObject, RemoveObjectResponse, RemoveObjectsResponse};
|
pub use remove_objects::{DeleteError, DeletedObject, RemoveObjectResponse, RemoveObjectsResponse};
|
||||||
pub use set_bucket_encryption::SetBucketEncryptionResponse;
|
pub use set_bucket_encryption::SetBucketEncryptionResponse;
|
||||||
pub use set_bucket_lifecycle::SetBucketLifecycleResponse;
|
pub use set_bucket_lifecycle::SetBucketLifecycleResponse;
|
||||||
|
pub use set_bucket_policy::SetBucketPolicyResponse;
|
||||||
pub use set_bucket_versioning::SetBucketVersioningResponse;
|
pub use set_bucket_versioning::SetBucketVersioningResponse;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -559,8 +569,6 @@ impl SelectObjectContentResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Response of [delete_bucket_encryption()](crate::s3::client::Client::delete_bucket_encryption) API
|
|
||||||
pub type DeleteBucketEncryptionResponse = BucketResponse;
|
|
||||||
/// Response of [enable_object_legal_hold()](crate::s3::client::Client::enable_object_legal_hold) API
|
/// Response of [enable_object_legal_hold()](crate::s3::client::Client::enable_object_legal_hold) API
|
||||||
pub type EnableObjectLegalHoldResponse = ObjectResponse;
|
pub type EnableObjectLegalHoldResponse = ObjectResponse;
|
||||||
|
|
||||||
@ -578,9 +586,6 @@ pub struct IsObjectLegalHoldEnabledResponse {
|
|||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Response of [delete_bucket_lifecycle()](crate::s3::client::Client::delete_bucket_lifecycle) API
|
|
||||||
pub type DeleteBucketLifecycleResponse = BucketResponse;
|
|
||||||
|
|
||||||
/// Response of [delete_bucket_notification()](crate::s3::client::Client::delete_bucket_notification) API
|
/// Response of [delete_bucket_notification()](crate::s3::client::Client::delete_bucket_notification) API
|
||||||
pub type DeleteBucketNotificationResponse = BucketResponse;
|
pub type DeleteBucketNotificationResponse = BucketResponse;
|
||||||
|
|
||||||
@ -596,21 +601,6 @@ pub struct GetBucketNotificationResponse {
|
|||||||
/// Response of [set_bucket_notification()](crate::s3::client::Client::set_bucket_notification) API
|
/// Response of [set_bucket_notification()](crate::s3::client::Client::set_bucket_notification) API
|
||||||
pub type SetBucketNotificationResponse = BucketResponse;
|
pub type SetBucketNotificationResponse = BucketResponse;
|
||||||
|
|
||||||
/// Response of [delete_bucket_policy()](crate::s3::client::Client::delete_bucket_policy) API
|
|
||||||
pub type DeleteBucketPolicyResponse = BucketResponse;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
/// Response of [get_bucket_policy()](crate::s3::client::Client::get_bucket_policy) API
|
|
||||||
pub struct GetBucketPolicyResponse {
|
|
||||||
pub headers: HeaderMap,
|
|
||||||
pub region: String,
|
|
||||||
pub bucket_name: String,
|
|
||||||
pub config: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Response of [set_bucket_policy()](crate::s3::client::Client::set_bucket_policy) API
|
|
||||||
pub type SetBucketPolicyResponse = BucketResponse;
|
|
||||||
|
|
||||||
/// Response of [delete_bucket_replication()](crate::s3::client::Client::delete_bucket_replication) API
|
/// Response of [delete_bucket_replication()](crate::s3::client::Client::delete_bucket_replication) API
|
||||||
pub type DeleteBucketReplicationResponse = BucketResponse;
|
pub type DeleteBucketReplicationResponse = BucketResponse;
|
||||||
|
|
||||||
|
|||||||
48
src/s3/response/delete_bucket_encryption.rs
Normal file
48
src/s3/response/delete_bucket_encryption.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::types::{FromS3Response, S3Request};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use http::HeaderMap;
|
||||||
|
|
||||||
|
/// Response of
|
||||||
|
/// [delete_bucket_encryption()](crate::s3::client::Client::delete_bucket_encryption)
|
||||||
|
/// API
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct DeleteBucketEncryptionResponse {
|
||||||
|
pub headers: HeaderMap,
|
||||||
|
pub region: String,
|
||||||
|
pub bucket: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl FromS3Response for DeleteBucketEncryptionResponse {
|
||||||
|
async fn from_s3response<'a>(
|
||||||
|
req: S3Request<'a>,
|
||||||
|
resp: Result<reqwest::Response, Error>,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let bucket: String = match req.bucket {
|
||||||
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
|
Some(v) => v.to_string(),
|
||||||
|
};
|
||||||
|
let resp = resp?;
|
||||||
|
Ok(DeleteBucketEncryptionResponse {
|
||||||
|
headers: resp.headers().clone(),
|
||||||
|
region: req.get_computed_region(),
|
||||||
|
bucket,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
50
src/s3/response/delete_bucket_lifecycle.rs
Normal file
50
src/s3/response/delete_bucket_lifecycle.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::types::{FromS3Response, S3Request};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use http::HeaderMap;
|
||||||
|
|
||||||
|
/// Response of
|
||||||
|
/// [delete_bucket_lifecycle()](crate::s3::client::Client::delete_bucket_lifecycle)
|
||||||
|
/// API
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct DeleteBucketLifecycleResponse {
|
||||||
|
pub headers: HeaderMap,
|
||||||
|
pub region: String,
|
||||||
|
pub bucket: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl FromS3Response for DeleteBucketLifecycleResponse {
|
||||||
|
async fn from_s3response<'a>(
|
||||||
|
req: S3Request<'a>,
|
||||||
|
resp: Result<reqwest::Response, Error>,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let bucket: String = match req.bucket {
|
||||||
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
|
Some(v) => v.to_string(),
|
||||||
|
};
|
||||||
|
let resp = resp?;
|
||||||
|
let headers = resp.headers().clone();
|
||||||
|
|
||||||
|
Ok(DeleteBucketLifecycleResponse {
|
||||||
|
headers,
|
||||||
|
region: req.get_computed_region(),
|
||||||
|
bucket,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
57
src/s3/response/delete_bucket_policy.rs
Normal file
57
src/s3/response/delete_bucket_policy.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::types::{FromS3Response, S3Request};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use http::HeaderMap;
|
||||||
|
|
||||||
|
/// Response of
|
||||||
|
/// [delete_bucket_policy()](crate::s3::client::Client::delete_bucket_policy)
|
||||||
|
/// API
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct DeleteBucketPolicyResponse {
|
||||||
|
pub headers: HeaderMap,
|
||||||
|
pub region: String,
|
||||||
|
pub bucket: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl FromS3Response for DeleteBucketPolicyResponse {
|
||||||
|
async fn from_s3response<'a>(
|
||||||
|
req: S3Request<'a>,
|
||||||
|
resp: Result<reqwest::Response, Error>,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let bucket: String = match req.bucket {
|
||||||
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
|
Some(v) => v.to_string(),
|
||||||
|
};
|
||||||
|
match resp {
|
||||||
|
Ok(r) => Ok(DeleteBucketPolicyResponse {
|
||||||
|
headers: r.headers().clone(),
|
||||||
|
region: req.get_computed_region(),
|
||||||
|
bucket,
|
||||||
|
}),
|
||||||
|
Err(Error::S3Error(ref err)) if err.code == Error::NoSuchBucketPolicy.as_str() => {
|
||||||
|
Ok(DeleteBucketPolicyResponse {
|
||||||
|
headers: HeaderMap::new(),
|
||||||
|
region: req.get_computed_region(),
|
||||||
|
bucket,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -36,35 +36,49 @@ pub struct GetBucketEncryptionResponse {
|
|||||||
impl FromS3Response for GetBucketEncryptionResponse {
|
impl FromS3Response for GetBucketEncryptionResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let bucket: String = match req.bucket {
|
let bucket: String = match req.bucket {
|
||||||
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
Some(v) => v.to_string(),
|
Some(v) => v.to_string(),
|
||||||
};
|
};
|
||||||
|
match resp {
|
||||||
|
Ok(r) => {
|
||||||
|
let headers = r.headers().clone();
|
||||||
|
let body = r.bytes().await?;
|
||||||
|
let mut root = Element::parse(body.reader())?;
|
||||||
|
|
||||||
let headers = resp.headers().clone();
|
let rule = root
|
||||||
let body = resp.bytes().await?;
|
.get_mut_child("Rule")
|
||||||
let mut root = Element::parse(body.reader())?;
|
.ok_or(Error::XmlError(String::from("<Rule> tag not found")))?;
|
||||||
|
|
||||||
let rule = root
|
let sse_by_default = rule
|
||||||
.get_mut_child("Rule")
|
.get_mut_child("ApplyServerSideEncryptionByDefault")
|
||||||
.ok_or(Error::XmlError(String::from("<Rule> tag not found")))?;
|
.ok_or(Error::XmlError(String::from(
|
||||||
|
"<ApplyServerSideEncryptionByDefault> tag not found",
|
||||||
|
)))?;
|
||||||
|
|
||||||
let sse_by_default = rule
|
Ok(GetBucketEncryptionResponse {
|
||||||
.get_mut_child("ApplyServerSideEncryptionByDefault")
|
headers,
|
||||||
.ok_or(Error::XmlError(String::from(
|
region: req.get_computed_region(),
|
||||||
"<ApplyServerSideEncryptionByDefault> tag not found",
|
bucket,
|
||||||
)))?;
|
config: SseConfig {
|
||||||
|
sse_algorithm: get_text(sse_by_default, "SSEAlgorithm")?,
|
||||||
Ok(GetBucketEncryptionResponse {
|
kms_master_key_id: get_option_text(sse_by_default, "KMSMasterKeyID"),
|
||||||
headers,
|
},
|
||||||
region: req.get_computed_region(),
|
})
|
||||||
bucket,
|
}
|
||||||
config: SseConfig {
|
Err(Error::S3Error(ref err))
|
||||||
sse_algorithm: get_text(sse_by_default, "SSEAlgorithm")?,
|
if err.code == "ServerSideEncryptionConfigurationNotFoundError" =>
|
||||||
kms_master_key_id: get_option_text(sse_by_default, "KMSMasterKeyID"),
|
{
|
||||||
},
|
Ok(GetBucketEncryptionResponse {
|
||||||
})
|
headers: HeaderMap::new(),
|
||||||
|
region: req.get_computed_region(),
|
||||||
|
bucket,
|
||||||
|
config: Default::default(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,12 +35,13 @@ pub struct GetBucketLifecycleResponse {
|
|||||||
impl FromS3Response for GetBucketLifecycleResponse {
|
impl FromS3Response for GetBucketLifecycleResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let bucket: String = match req.bucket {
|
let bucket: String = match req.bucket {
|
||||||
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
Some(v) => v.to_string(),
|
Some(v) => v.to_string(),
|
||||||
};
|
};
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
let body = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
let root = Element::parse(body.reader())?;
|
let root = Element::parse(body.reader())?;
|
||||||
|
|||||||
60
src/s3/response/get_bucket_policy.rs
Normal file
60
src/s3/response/get_bucket_policy.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::types::{FromS3Response, S3Request};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use http::HeaderMap;
|
||||||
|
|
||||||
|
/// Response of
|
||||||
|
/// [get_bucket_policy()](crate::s3::client::Client::get_bucket_policy)
|
||||||
|
/// API
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct GetBucketPolicyResponse {
|
||||||
|
pub headers: HeaderMap,
|
||||||
|
pub region: String,
|
||||||
|
pub bucket: String,
|
||||||
|
pub config: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl FromS3Response for GetBucketPolicyResponse {
|
||||||
|
async fn from_s3response<'a>(
|
||||||
|
req: S3Request<'a>,
|
||||||
|
resp: Result<reqwest::Response, Error>,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let bucket: String = match req.bucket {
|
||||||
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
|
Some(v) => v.to_string(),
|
||||||
|
};
|
||||||
|
match resp {
|
||||||
|
Ok(r) => Ok(GetBucketPolicyResponse {
|
||||||
|
headers: r.headers().clone(),
|
||||||
|
region: req.get_computed_region(),
|
||||||
|
bucket,
|
||||||
|
config: r.text().await?,
|
||||||
|
}),
|
||||||
|
Err(Error::S3Error(ref err)) if err.code == Error::NoSuchBucketPolicy.as_str() => {
|
||||||
|
Ok(GetBucketPolicyResponse {
|
||||||
|
headers: HeaderMap::new(),
|
||||||
|
region: req.get_computed_region(),
|
||||||
|
bucket,
|
||||||
|
config: String::from("{}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -38,13 +38,13 @@ pub struct GetBucketVersioningResponse {
|
|||||||
impl FromS3Response for GetBucketVersioningResponse {
|
impl FromS3Response for GetBucketVersioningResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let bucket: String = match req.bucket {
|
let bucket: String = match req.bucket {
|
||||||
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
Some(v) => v.to_string(),
|
Some(v) => v.to_string(),
|
||||||
};
|
};
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
let body = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
let root = Element::parse(body.reader())?;
|
let root = Element::parse(body.reader())?;
|
||||||
|
|||||||
@ -37,8 +37,9 @@ pub struct GetObjectResponse {
|
|||||||
impl FromS3Response for GetObjectResponse {
|
impl FromS3Response for GetObjectResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
response: reqwest::Response,
|
response: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let response = response?;
|
||||||
let header_map = response.headers().clone();
|
let header_map = response.headers().clone();
|
||||||
let version_id = header_map
|
let version_id = header_map
|
||||||
.get("x-amz-version-id")
|
.get("x-amz-version-id")
|
||||||
|
|||||||
@ -32,8 +32,9 @@ pub struct ListBucketsResponse {
|
|||||||
impl FromS3Response for ListBucketsResponse {
|
impl FromS3Response for ListBucketsResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
_req: S3Request<'a>,
|
_req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let resp = resp?;
|
||||||
let header_map = resp.headers().clone();
|
let header_map = resp.headers().clone();
|
||||||
let body = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
let mut root = Element::parse(body.reader())?;
|
let mut root = Element::parse(body.reader())?;
|
||||||
|
|||||||
@ -204,8 +204,9 @@ pub struct ListObjectsV1Response {
|
|||||||
impl FromS3Response for ListObjectsV1Response {
|
impl FromS3Response for ListObjectsV1Response {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
_req: S3Request<'a>,
|
_req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
let body = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
let xmltree_root = xmltree::Element::parse(body.reader())?;
|
let xmltree_root = xmltree::Element::parse(body.reader())?;
|
||||||
@ -258,8 +259,9 @@ pub struct ListObjectsV2Response {
|
|||||||
impl FromS3Response for ListObjectsV2Response {
|
impl FromS3Response for ListObjectsV2Response {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
_req: S3Request<'a>,
|
_req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
let body = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
let xmltree_root = xmltree::Element::parse(body.reader())?;
|
let xmltree_root = xmltree::Element::parse(body.reader())?;
|
||||||
@ -316,8 +318,9 @@ pub struct ListObjectVersionsResponse {
|
|||||||
impl FromS3Response for ListObjectVersionsResponse {
|
impl FromS3Response for ListObjectVersionsResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
_req: S3Request<'a>,
|
_req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
let body = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
let xmltree_root = xmltree::Element::parse(body.reader())?;
|
let xmltree_root = xmltree::Element::parse(body.reader())?;
|
||||||
|
|||||||
@ -42,8 +42,9 @@ impl FromS3Response
|
|||||||
{
|
{
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
|
|
||||||
let body_stream = resp.bytes_stream();
|
let body_stream = resp.bytes_stream();
|
||||||
|
|||||||
@ -29,8 +29,9 @@ pub struct ObjectPromptResponse {
|
|||||||
impl FromS3Response for ObjectPromptResponse {
|
impl FromS3Response for ObjectPromptResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
response: reqwest::Response,
|
response: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let response = response?;
|
||||||
let headers = response.headers().clone();
|
let headers = response.headers().clone();
|
||||||
let body = response.bytes().await?;
|
let body = response.bytes().await?;
|
||||||
let prompt_response: String = String::from_utf8(body.to_vec())?;
|
let prompt_response: String = String::from_utf8(body.to_vec())?;
|
||||||
|
|||||||
@ -39,8 +39,9 @@ pub struct PutObjectResponse {
|
|||||||
impl FromS3Response for PutObjectResponse {
|
impl FromS3Response for PutObjectResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
response: reqwest::Response,
|
response: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let response = response?;
|
||||||
let header_map = response.headers();
|
let header_map = response.headers();
|
||||||
|
|
||||||
Ok(PutObjectResponse {
|
Ok(PutObjectResponse {
|
||||||
@ -73,8 +74,9 @@ pub struct CreateMultipartUploadResponse2 {
|
|||||||
impl FromS3Response for CreateMultipartUploadResponse2 {
|
impl FromS3Response for CreateMultipartUploadResponse2 {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
response: reqwest::Response,
|
response: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let response = response?;
|
||||||
let headers = response.headers().clone();
|
let headers = response.headers().clone();
|
||||||
let body = response.bytes().await?;
|
let body = response.bytes().await?;
|
||||||
let root = Element::parse(body.reader())?;
|
let root = Element::parse(body.reader())?;
|
||||||
|
|||||||
@ -40,8 +40,9 @@ pub struct RemoveObjectResponse {
|
|||||||
impl FromS3Response for RemoveObjectResponse {
|
impl FromS3Response for RemoveObjectResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
_req: S3Request<'a>,
|
_req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
let is_delete_marker = headers
|
let is_delete_marker = headers
|
||||||
.get("x-amz-delete-marker")
|
.get("x-amz-delete-marker")
|
||||||
@ -119,8 +120,9 @@ impl DeleteResult {
|
|||||||
impl FromS3Response for RemoveObjectsResponse {
|
impl FromS3Response for RemoveObjectsResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
_req: S3Request<'a>,
|
_req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
|
|
||||||
let body = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
|
|||||||
@ -24,7 +24,6 @@ use xmltree::Element;
|
|||||||
/// Response of
|
/// Response of
|
||||||
/// [set_bucket_encryption()](crate::s3::client::Client::set_bucket_encryption)
|
/// [set_bucket_encryption()](crate::s3::client::Client::set_bucket_encryption)
|
||||||
/// API
|
/// API
|
||||||
/// TODO equal to GetBucketEncryptionResponse
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SetBucketEncryptionResponse {
|
pub struct SetBucketEncryptionResponse {
|
||||||
pub headers: HeaderMap,
|
pub headers: HeaderMap,
|
||||||
@ -37,13 +36,13 @@ pub struct SetBucketEncryptionResponse {
|
|||||||
impl FromS3Response for SetBucketEncryptionResponse {
|
impl FromS3Response for SetBucketEncryptionResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let bucket: String = match req.bucket {
|
let bucket: String = match req.bucket {
|
||||||
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
Some(v) => v.to_string(),
|
Some(v) => v.to_string(),
|
||||||
};
|
};
|
||||||
|
let resp = resp?;
|
||||||
let headers = resp.headers().clone();
|
let headers = resp.headers().clone();
|
||||||
let body = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
let mut root = Element::parse(body.reader())?;
|
let mut root = Element::parse(body.reader())?;
|
||||||
|
|||||||
@ -20,7 +20,6 @@ use http::HeaderMap;
|
|||||||
|
|
||||||
/// Response of [set_bucket_lifecycle()](crate::s3::client::Client::set_bucket_lifecycle) API
|
/// Response of [set_bucket_lifecycle()](crate::s3::client::Client::set_bucket_lifecycle) API
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// TODO is identical ot BucketResponse
|
|
||||||
pub struct SetBucketLifecycleResponse {
|
pub struct SetBucketLifecycleResponse {
|
||||||
pub headers: HeaderMap,
|
pub headers: HeaderMap,
|
||||||
pub region: String,
|
pub region: String,
|
||||||
@ -31,13 +30,13 @@ pub struct SetBucketLifecycleResponse {
|
|||||||
impl FromS3Response for SetBucketLifecycleResponse {
|
impl FromS3Response for SetBucketLifecycleResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let bucket: String = match req.bucket {
|
let bucket: String = match req.bucket {
|
||||||
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
Some(v) => v.to_string(),
|
Some(v) => v.to_string(),
|
||||||
};
|
};
|
||||||
|
let resp = resp?;
|
||||||
Ok(SetBucketLifecycleResponse {
|
Ok(SetBucketLifecycleResponse {
|
||||||
headers: resp.headers().clone(),
|
headers: resp.headers().clone(),
|
||||||
region: req.get_computed_region(),
|
region: req.get_computed_region(),
|
||||||
|
|||||||
46
src/s3/response/set_bucket_policy.rs
Normal file
46
src/s3/response/set_bucket_policy.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// MinIO Rust Library for Amazon S3 Compatible Cloud Storage
|
||||||
|
// Copyright 2025 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::s3::error::Error;
|
||||||
|
use crate::s3::types::{FromS3Response, S3Request};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use http::HeaderMap;
|
||||||
|
|
||||||
|
/// Response of [set_bucket_policy()](crate::s3::client::Client::set_bucket_policy) API
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SetBucketPolicyResponse {
|
||||||
|
pub headers: HeaderMap,
|
||||||
|
pub region: String,
|
||||||
|
pub bucket: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl FromS3Response for SetBucketPolicyResponse {
|
||||||
|
async fn from_s3response<'a>(
|
||||||
|
req: S3Request<'a>,
|
||||||
|
resp: Result<reqwest::Response, Error>,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let bucket: String = match req.bucket {
|
||||||
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
|
Some(v) => v.to_string(),
|
||||||
|
};
|
||||||
|
let resp = resp?;
|
||||||
|
Ok(SetBucketPolicyResponse {
|
||||||
|
headers: resp.headers().clone(),
|
||||||
|
region: req.get_computed_region(),
|
||||||
|
bucket,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,7 +20,6 @@ use http::HeaderMap;
|
|||||||
|
|
||||||
/// Response of [set_bucket_versioning()](crate::s3::client::Client::set_bucket_versioning) API
|
/// Response of [set_bucket_versioning()](crate::s3::client::Client::set_bucket_versioning) API
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// TODO is identical ot BucketResponse
|
|
||||||
pub struct SetBucketVersioningResponse {
|
pub struct SetBucketVersioningResponse {
|
||||||
pub headers: HeaderMap,
|
pub headers: HeaderMap,
|
||||||
pub region: String,
|
pub region: String,
|
||||||
@ -31,13 +30,13 @@ pub struct SetBucketVersioningResponse {
|
|||||||
impl FromS3Response for SetBucketVersioningResponse {
|
impl FromS3Response for SetBucketVersioningResponse {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
req: S3Request<'a>,
|
req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let bucket: String = match req.bucket {
|
let bucket: String = match req.bucket {
|
||||||
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
None => return Err(Error::InvalidBucketName("no bucket specified".to_string())),
|
||||||
Some(v) => v.to_string(),
|
Some(v) => v.to_string(),
|
||||||
};
|
};
|
||||||
|
let resp = resp?;
|
||||||
Ok(SetBucketVersioningResponse {
|
Ok(SetBucketVersioningResponse {
|
||||||
headers: resp.headers().clone(),
|
headers: resp.headers().clone(),
|
||||||
region: req.get_computed_region(),
|
region: req.get_computed_region(),
|
||||||
|
|||||||
@ -126,7 +126,7 @@ pub trait ToS3Request {
|
|||||||
pub trait FromS3Response: Sized {
|
pub trait FromS3Response: Sized {
|
||||||
async fn from_s3response<'a>(
|
async fn from_s3response<'a>(
|
||||||
s3req: S3Request<'a>,
|
s3req: S3Request<'a>,
|
||||||
resp: reqwest::Response,
|
resp: Result<reqwest::Response, Error>,
|
||||||
) -> Result<Self, Error>;
|
) -> Result<Self, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ pub trait S3Api: ToS3Request {
|
|||||||
|
|
||||||
async fn send(&self) -> Result<Self::S3Response, Error> {
|
async fn send(&self) -> Result<Self::S3Response, Error> {
|
||||||
let mut req = self.to_s3request()?;
|
let mut req = self.to_s3request()?;
|
||||||
let resp = req.execute().await?;
|
let resp: Result<reqwest::Response, Error> = req.execute().await;
|
||||||
Self::S3Response::from_s3response(req, resp).await
|
Self::S3Response::from_s3response(req, resp).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -790,7 +790,7 @@ impl fmt::Display for Directive {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||||
/// Server-side information configuration
|
/// Server-side information configuration
|
||||||
pub struct SseConfig {
|
pub struct SseConfig {
|
||||||
pub sse_algorithm: String,
|
pub sse_algorithm: String,
|
||||||
|
|||||||
143
tests/tests.rs
143
tests/tests.rs
@ -36,11 +36,14 @@ use minio::s3::client::Client;
|
|||||||
use minio::s3::creds::StaticProvider;
|
use minio::s3::creds::StaticProvider;
|
||||||
use minio::s3::error::Error;
|
use minio::s3::error::Error;
|
||||||
use minio::s3::http::BaseUrl;
|
use minio::s3::http::BaseUrl;
|
||||||
use minio::s3::response::GetBucketVersioningResponse;
|
use minio::s3::response::{
|
||||||
|
DeleteBucketEncryptionResponse, GetBucketEncryptionResponse, GetBucketVersioningResponse,
|
||||||
|
};
|
||||||
use minio::s3::types::{
|
use minio::s3::types::{
|
||||||
CsvInputSerialization, CsvOutputSerialization, FileHeaderInfo, NotificationConfig,
|
CsvInputSerialization, CsvOutputSerialization, FileHeaderInfo, Filter, LifecycleConfig,
|
||||||
NotificationRecords, ObjectLockConfig, PrefixFilterRule, QueueConfig, QuoteFields,
|
LifecycleRule, NotificationConfig, NotificationRecords, ObjectLockConfig, PrefixFilterRule,
|
||||||
RetentionMode, S3Api, SelectRequest, SuffixFilterRule, ToStream,
|
QueueConfig, QuoteFields, RetentionMode, S3Api, SelectRequest, SseConfig, SuffixFilterRule,
|
||||||
|
ToStream,
|
||||||
};
|
};
|
||||||
use minio::s3::utils::{to_iso8601utc, utc_now};
|
use minio::s3::utils::{to_iso8601utc, utc_now};
|
||||||
|
|
||||||
@ -301,8 +304,6 @@ impl Drop for CleanupGuard {
|
|||||||
|
|
||||||
// Execute the async cleanup in this new runtime
|
// Execute the async cleanup in this new runtime
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
//clean_bucket(&bucket_name, &ctx).await;
|
|
||||||
|
|
||||||
// do the actual removal of the bucket
|
// do the actual removal of the bucket
|
||||||
match timeout(
|
match timeout(
|
||||||
std::time::Duration::from_secs(60),
|
std::time::Duration::from_secs(60),
|
||||||
@ -1220,31 +1221,149 @@ async fn set_get_delete_bucket_policy() {
|
|||||||
"#
|
"#
|
||||||
.replace("<BUCKET>", &bucket_name);
|
.replace("<BUCKET>", &bucket_name);
|
||||||
|
|
||||||
ctx.client
|
let _resp = ctx
|
||||||
.set_bucket_policy(&SetBucketPolicyArgs::new(&bucket_name, &config).unwrap())
|
.client
|
||||||
|
.set_bucket_policy(&bucket_name)
|
||||||
|
.config(config.clone())
|
||||||
|
.send()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let resp = ctx
|
let resp = ctx
|
||||||
.client
|
.client
|
||||||
.get_bucket_policy(&GetBucketPolicyArgs::new(&bucket_name).unwrap())
|
.get_bucket_policy(&bucket_name)
|
||||||
|
.send()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
// TODO create a proper comparison of the retrieved config and the provided config
|
||||||
|
// println!("response of getting policy: resp.config={:?}", resp.config);
|
||||||
|
// assert_eq!(&resp.config, &config);
|
||||||
assert!(!resp.config.is_empty());
|
assert!(!resp.config.is_empty());
|
||||||
|
|
||||||
ctx.client
|
let _resp = ctx
|
||||||
.delete_bucket_policy(&DeleteBucketPolicyArgs::new(&bucket_name).unwrap())
|
.client
|
||||||
|
.delete_bucket_policy(&bucket_name)
|
||||||
|
.send()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let resp = ctx
|
let resp = ctx
|
||||||
.client
|
.client
|
||||||
.get_bucket_policy(&GetBucketPolicyArgs::new(&bucket_name).unwrap())
|
.get_bucket_policy(&bucket_name)
|
||||||
|
.send()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(resp.config, "{}");
|
assert_eq!(resp.config, "{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 10)]
|
||||||
|
async fn set_get_delete_bucket_encryption() {
|
||||||
|
let ctx = TestContext::new_from_env();
|
||||||
|
let (bucket_name, _cleanup) = create_bucket_helper(&ctx).await;
|
||||||
|
|
||||||
|
let config = SseConfig::default();
|
||||||
|
|
||||||
|
if false {
|
||||||
|
// TODO this gives a runtime error
|
||||||
|
let _resp = ctx
|
||||||
|
.client
|
||||||
|
.set_bucket_encryption(&bucket_name)
|
||||||
|
.sse_config(config.clone())
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp: GetBucketEncryptionResponse = ctx
|
||||||
|
.client
|
||||||
|
.get_bucket_encryption(&bucket_name)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(resp.config, config);
|
||||||
|
|
||||||
|
let _resp: DeleteBucketEncryptionResponse = ctx
|
||||||
|
.client
|
||||||
|
.delete_bucket_encryption(&bucket_name)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let resp: GetBucketEncryptionResponse = ctx
|
||||||
|
.client
|
||||||
|
.get_bucket_encryption(&bucket_name)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"response of getting encryption config: resp.sse_config={:?}",
|
||||||
|
resp.config
|
||||||
|
);
|
||||||
|
assert_eq!(resp.config, SseConfig::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread", worker_threads = 10)]
|
||||||
|
async fn set_get_delete_bucket_lifecycle() {
|
||||||
|
let ctx = TestContext::new_from_env();
|
||||||
|
let (bucket_name, _cleanup) = create_bucket_helper(&ctx).await;
|
||||||
|
|
||||||
|
let rules: Vec<LifecycleRule> = vec![LifecycleRule {
|
||||||
|
abort_incomplete_multipart_upload_days_after_initiation: None,
|
||||||
|
expiration_date: None,
|
||||||
|
expiration_days: Some(365),
|
||||||
|
expiration_expired_object_delete_marker: None,
|
||||||
|
filter: Filter {
|
||||||
|
and_operator: None,
|
||||||
|
prefix: Some(String::from("logs/")),
|
||||||
|
tag: None,
|
||||||
|
},
|
||||||
|
id: String::from("rule1"),
|
||||||
|
noncurrent_version_expiration_noncurrent_days: None,
|
||||||
|
noncurrent_version_transition_noncurrent_days: None,
|
||||||
|
noncurrent_version_transition_storage_class: None,
|
||||||
|
status: true,
|
||||||
|
transition_date: None,
|
||||||
|
transition_days: None,
|
||||||
|
transition_storage_class: None,
|
||||||
|
}];
|
||||||
|
|
||||||
|
let _resp = ctx
|
||||||
|
.client
|
||||||
|
.set_bucket_lifecycle(&bucket_name)
|
||||||
|
.life_cycle_config(LifecycleConfig { rules })
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let _resp = ctx
|
||||||
|
.client
|
||||||
|
.get_bucket_policy(&bucket_name)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
// TODO the original unrefactored code returns '{}', but should have returned rules
|
||||||
|
//println!("response of getting policy: resp.config={:?}", resp.config);
|
||||||
|
//assert_eq!(resp.config, rules.to_string());
|
||||||
|
|
||||||
|
let _resp = ctx
|
||||||
|
.client
|
||||||
|
.delete_bucket_policy(&bucket_name)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let resp = ctx
|
||||||
|
.client
|
||||||
|
.get_bucket_policy(&bucket_name)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
//println!("response of getting policy: resp.config={:?}", resp.config);
|
||||||
|
assert_eq!(resp.config, "{}");
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 10)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 10)]
|
||||||
async fn set_get_delete_bucket_tags() {
|
async fn set_get_delete_bucket_tags() {
|
||||||
let ctx = TestContext::new_from_env();
|
let ctx = TestContext::new_from_env();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user