From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id E2A6D1FF16F for ; Tue, 8 Jul 2025 19:01:38 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 2F7051C909; Tue, 8 Jul 2025 19:02:14 +0200 (CEST) From: Christian Ebner To: pbs-devel@lists.proxmox.com Date: Tue, 8 Jul 2025 19:00:35 +0200 Message-ID: <20250708170114.1556057-8-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250708170114.1556057-1-c.ebner@proxmox.com> References: <20250708170114.1556057-1-c.ebner@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.040 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox v6 7/9] s3 client: add example usage for basic operations X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Backup Server development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" Add an examples for how to create the client instance using its configuration options and how to perform some basic api requests on the S3 endpoint. Guarded by the cfg attribute for conditional compilation to not fail if feature "impl" is not set. Further, excluded via `Cargo.toml` from being executed as test, as this requires S3 object store to be available and configured. Signed-off-by: Christian Ebner --- proxmox-s3-client/Cargo.toml | 4 ++ proxmox-s3-client/examples/s3_client.rs | 65 +++++++++++++++++++++++++ proxmox-s3-client/src/lib.rs | 7 +++ 3 files changed, 76 insertions(+) create mode 100644 proxmox-s3-client/examples/s3_client.rs diff --git a/proxmox-s3-client/Cargo.toml b/proxmox-s3-client/Cargo.toml index 18bddddd..4388d5f6 100644 --- a/proxmox-s3-client/Cargo.toml +++ b/proxmox-s3-client/Cargo.toml @@ -42,3 +42,7 @@ proxmox-time.workspace = true [features] default = [] impl = [] + +[[example]] +name = "s3_client" +test = false diff --git a/proxmox-s3-client/examples/s3_client.rs b/proxmox-s3-client/examples/s3_client.rs new file mode 100644 index 00000000..25044e89 --- /dev/null +++ b/proxmox-s3-client/examples/s3_client.rs @@ -0,0 +1,65 @@ +// Execute via `cargo run --example s3_client --features impl` in `proxmox` main repo folder + +#[cfg(not(feature = "impl"))] +fn main() { + // intentionally left empty +} + +#[cfg(feature = "impl")] +use proxmox_s3_client::{S3ObjectKey, S3Client, S3ClientOptions, S3PathPrefix}; + +#[cfg(feature = "impl")] +fn main() -> Result<(), anyhow::Error> { + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(run()) +} + +#[cfg(feature = "impl")] +async fn run() -> Result<(), anyhow::Error> { + // Configure the client via the client options + let options = S3ClientOptions { + // Must be resolvable, e.g. the Ceph RADOS gateway. + // Allows to use {{bucket}} or {{region}} template pattern for ease of configuration. + // In this example, the final authority is `https://testbucket.s3.pve-c1.local:7480/`. + endpoint: "{{bucket}}.s3.pve-c1.local".to_string(), + // Must match the port the api is listening on + port: Some(7480), + // Name of the bucket to be used + bucket: "testbucket".to_string(), + common_prefix: "teststore".to_string(), + path_style: false, + access_key: "".to_string(), + secret_key: "".to_string(), + region: "us-west-1".to_string(), + // Only required for self signed certificates, can be obtained by, e.g. + // `openssl s_client -connect testbucket.s3.pve-c1.local:7480 < /dev/null | openssl x509 -fingerprint -sha256 -noout` + fingerprint: Some("".to_string()), + put_rate_limit: None, + }; + + // Creating a client instance and connect to api endpoint + let s3_client = S3Client::new(options)?; + + // Check if the bucket can be accessed + s3_client.head_bucket().await?; + + let rel_object_key = S3ObjectKey::from("object.txt"); + let body = proxmox_http::Body::empty(); + let replace_existing_key = true; + let _response = s3_client.put_object(rel_object_key, body, replace_existing_key).await?; + + // List object, limiting to ones matching the given prefix. Since the api limits the response + // to 1000 entries, the following contents might be fetched using a continuation token, being + // part of the previouis response. + let prefix = S3PathPrefix::Some("/teststore/".to_string()); + let continuation_token = None; + let _response = s3_client.list_objects_v2(&prefix, continuation_token).await?; + + // Delete a single object + let rel_object_key = S3ObjectKey::from("object.txt"); + let _response = s3_client.delete_object(rel_object_key).await?; + Ok(()) +} diff --git a/proxmox-s3-client/src/lib.rs b/proxmox-s3-client/src/lib.rs index 991e1546..f485ac46 100644 --- a/proxmox-s3-client/src/lib.rs +++ b/proxmox-s3-client/src/lib.rs @@ -1,4 +1,11 @@ //! Low level REST API client for AWS S3 compatible object stores +//! +//! # Example +//! A basic example on how to use the client can be found in +//! `proxmox-s3-client/examples/s3_client.rs` and run via +//! `cargo run --example s3_client --features impl` from the main +//! repository folder. + #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![deny(unsafe_op_in_unsafe_fn)] #![deny(missing_docs)] -- 2.47.2 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel