mr-brobot commented on code in PR #4161:
URL: https://github.com/apache/arrow-rs/pull/4161#discussion_r1181758270
##########
object_store/src/aws/profile.rs:
##########
@@ -0,0 +1,99 @@
+#![cfg(feature = "aws_profile")]
+
+use aws_config::profile::ProfileFileCredentialsProvider;
+use aws_config::provider_config::ProviderConfig;
+use aws_credential_types::provider::ProvideCredentials;
+use aws_types::region::Region;
+use futures::future::BoxFuture;
+use std::sync::Arc;
+use std::time::Instant;
+use std::time::SystemTime;
+
+use super::credential::CredentialProvider;
+use crate::aws::AwsCredential;
+use crate::client::token::{TemporaryToken, TokenCache};
+use crate::Result;
+
+#[derive(Debug)]
+pub struct ProfileProvider {
+ name: String,
+ region: Option<String>,
+ cache: TokenCache<Arc<AwsCredential>>,
+}
+
+impl ProfileProvider {
+ pub fn new(name: String, region: Option<String>) -> Self {
+ Self {
+ name,
+ region,
+ cache: Default::default(),
+ }
+ }
+}
+
+impl CredentialProvider for ProfileProvider {
+ fn get_credential(&self) -> BoxFuture<'_, Result<Arc<AwsCredential>>> {
+ Box::pin(self.cache.get_or_insert_with(move || async move {
+ let region = match self.region.clone() {
+ Some(r) => Some(Region::new(r)),
+ None => None,
+ };
+
+ let config = ProviderConfig::default().with_region(region);
+
+ let credentials = ProfileFileCredentialsProvider::builder()
+ .configure(&config)
+ .profile_name(&self.name)
+ .build();
+
+ let c = credentials.provide_credentials().await.map_err(|source| {
+ crate::Error::Generic {
+ store: "S3",
+ source: Box::new(source),
+ }
+ })?;
+ let t_now = SystemTime::now();
+ let expiry = c
+ .expiry()
+ .and_then(|e| e.duration_since(t_now).ok())
+ .map(|ttl| Instant::now() + ttl);
+
+ Ok(TemporaryToken {
+ token: Arc::new(AwsCredential {
+ key_id: c.access_key_id().to_string(),
+ secret_key: c.secret_access_key().to_string(),
+ token: c.session_token().map(ToString::to_string),
+ }),
+ expiry,
+ })
+ }))
+ }
+}
+
+#[cfg(not(test))]
+mod region {
+ use super::*;
+ use crate::aws::region::RegionProvider;
+ use aws_config::meta::region::ProvideRegion;
+ use aws_config::profile::region::Builder as ProfileRegionBuilder;
+
+ impl RegionProvider for ProfileProvider {
+ #[tokio::main(flavor = "current_thread")]
Review Comment:
I'd like to use the `BoxFuture` approach, but would that work when calling
via a synchronous function? This method is only called from
`AmazonS3Builder::build` when determining the region to use in the resulting
`AmazonS3` object.
Maybe the right thing to do is make `get_region` async, and let the caller
decide how to await/block depending on context/call pattern?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]