From 4ff8dc6d8b95cc816043a9f178c603f9a6434173 Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Thu, 24 Feb 2022 11:04:45 -0800 Subject: [PATCH] Make it possible to configure the default credentials cache (#1220) * Make it possible to configure the default credentials cache * Update changelog * Add settings directly to the `DefaultCredentialsChain` builder * Improve doc comments for `load_timeout` --- CHANGELOG.next.toml | 6 ++ .../src/default_provider/credentials.rs | 69 +++++++++++++- .../src/meta/credentials/lazy_caching.rs | 90 +++++++++++++++---- 3 files changed, 148 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index bda6a5d10d..6b1ba2fe60 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -58,3 +58,9 @@ message = "Fixed a bug in S3 that prevented the `content-length` and `content-ty references = ["smithy-rs#1216", "aws-sdk-rust#466"] meta = { "breaking" = false, "tada" = false, "bug" = true } author = "jdisanti" + +[[aws-sdk-rust]] +message = "Made it possible to change settings, such as load timeout, on the credential cache used by the `DefaultCredentialsChain`." +references = ["smithy-rs#1220", "aws-sdk-rust#462"] +meta = { "breaking" = false, "tada" = true, "bug" = false } +author = "jdisanti" diff --git a/aws/rust-runtime/aws-config/src/default_provider/credentials.rs b/aws/rust-runtime/aws-config/src/default_provider/credentials.rs index c8b11811aa..16a79af63f 100644 --- a/aws/rust-runtime/aws-config/src/default_provider/credentials.rs +++ b/aws/rust-runtime/aws-config/src/default_provider/credentials.rs @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0. */ -use aws_types::credentials; use std::borrow::Cow; +use std::time::Duration; -use aws_types::credentials::{future, ProvideCredentials}; +use aws_types::credentials::{self, future, ProvideCredentials}; use tracing::Instrument; use crate::environment::credentials::EnvironmentVariableCredentialsProvider; @@ -114,6 +114,71 @@ impl Builder { self } + /// Timeout for the entire credential loading chain. + /// + /// Defaults to 5 seconds. + pub fn load_timeout(mut self, timeout: Duration) -> Self { + self.set_load_timeout(Some(timeout)); + self + } + + /// Timeout for the entire credential loading chain. + /// + /// Defaults to 5 seconds. + pub fn set_load_timeout(&mut self, timeout: Option) -> &mut Self { + self.credential_cache.set_load_timeout(timeout); + self + } + + /// Amount of time before the actual credential expiration time + /// where credentials are considered expired. + /// + /// For example, if credentials are expiring in 15 minutes, and the buffer time is 10 seconds, + /// then any requests made after 14 minutes and 50 seconds will load new credentials. + /// + /// Defaults to 10 seconds. + pub fn buffer_time(mut self, buffer_time: Duration) -> Self { + self.set_buffer_time(Some(buffer_time)); + self + } + + /// Amount of time before the actual credential expiration time + /// where credentials are considered expired. + /// + /// For example, if credentials are expiring in 15 minutes, and the buffer time is 10 seconds, + /// then any requests made after 14 minutes and 50 seconds will load new credentials. + /// + /// Defaults to 10 seconds. + pub fn set_buffer_time(&mut self, buffer_time: Option) -> &mut Self { + self.credential_cache.set_buffer_time(buffer_time); + self + } + + /// Default expiration time to set on credentials if they don't have an expiration time. + /// + /// This is only used if the given [`ProvideCredentials`] returns + /// [`Credentials`](aws_types::Credentials) that don't have their `expiry` set. + /// This must be at least 15 minutes. + /// + /// Defaults to 15 minutes. + pub fn default_credential_expiration(mut self, duration: Duration) -> Self { + self.set_default_credential_expiration(Some(duration)); + self + } + + /// Default expiration time to set on credentials if they don't have an expiration time. + /// + /// This is only used if the given [`ProvideCredentials`] returns + /// [`Credentials`](aws_types::Credentials) that don't have their `expiry` set. + /// This must be at least 15 minutes. + /// + /// Defaults to 15 minutes. + pub fn set_default_credential_expiration(&mut self, duration: Option) -> &mut Self { + self.credential_cache + .set_default_credential_expiration(duration); + self + } + /// Add an additional credential source for the ProfileProvider /// /// Assume role profiles may specify named credential sources: diff --git a/aws/rust-runtime/aws-config/src/meta/credentials/lazy_caching.rs b/aws/rust-runtime/aws-config/src/meta/credentials/lazy_caching.rs index 76ddb64e38..0154a2492b 100644 --- a/aws/rust-runtime/aws-config/src/meta/credentials/lazy_caching.rs +++ b/aws/rust-runtime/aws-config/src/meta/credentials/lazy_caching.rs @@ -167,41 +167,101 @@ mod builder { /// An implementation of [`ProvideCredentials`] that will be used to load /// the cached credentials once they're expired. pub fn load(mut self, loader: impl ProvideCredentials + 'static) -> Self { - self.load = Some(Arc::new(loader)); + self.set_load(Some(loader)); self } - /// Implementation of [`AsyncSleep`] to use for timeouts. This enables use of - /// the `LazyCachingCredentialsProvider` with other async runtimes. + /// An implementation of [`ProvideCredentials`] that will be used to load + /// the cached credentials once they're expired. + pub fn set_load(&mut self, loader: Option) -> &mut Self { + self.load = loader.map(|l| Arc::new(l) as Arc); + self + } + + /// Implementation of [`AsyncSleep`] to use for timeouts. + /// + /// This enables use of the `LazyCachingCredentialsProvider` with other async runtimes. /// If using Tokio as the async runtime, this should be set to an instance of /// [`TokioSleep`](aws_smithy_async::rt::sleep::TokioSleep). pub fn sleep(mut self, sleep: impl AsyncSleep + 'static) -> Self { - self.sleep = Some(Arc::new(sleep)); + self.set_sleep(Some(sleep)); self } - /// (Optional) Timeout for the given [`ProvideCredentials`] implementation. + /// Implementation of [`AsyncSleep`] to use for timeouts. + /// + /// This enables use of the `LazyCachingCredentialsProvider` with other async runtimes. + /// If using Tokio as the async runtime, this should be set to an instance of + /// [`TokioSleep`](aws_smithy_async::rt::sleep::TokioSleep). + pub fn set_sleep(&mut self, sleep: Option) -> &mut Self { + self.sleep = sleep.map(|s| Arc::new(s) as Arc); + self + } + + /// Timeout for the given [`ProvideCredentials`] implementation. + /// /// Defaults to 5 seconds. pub fn load_timeout(mut self, timeout: Duration) -> Self { - self.load_timeout = Some(timeout); + self.set_load_timeout(Some(timeout)); self } - /// (Optional) Amount of time before the actual credential expiration time - /// where credentials are considered expired. For example, if credentials are expiring - /// in 15 minutes, and the buffer time is 10 seconds, then any requests made after - /// 14 minutes and 50 seconds will load new credentials. Defaults to 10 seconds. + /// Timeout for the given [`ProvideCredentials`] implementation. + /// + /// Defaults to 5 seconds. + pub fn set_load_timeout(&mut self, timeout: Option) -> &mut Self { + self.load_timeout = timeout; + self + } + + /// Amount of time before the actual credential expiration time + /// where credentials are considered expired. + /// + /// For example, if credentials are expiring in 15 minutes, and the buffer time is 10 seconds, + /// then any requests made after 14 minutes and 50 seconds will load new credentials. + /// + /// Defaults to 10 seconds. pub fn buffer_time(mut self, buffer_time: Duration) -> Self { - self.buffer_time = Some(buffer_time); + self.set_buffer_time(Some(buffer_time)); + self + } + + /// Amount of time before the actual credential expiration time + /// where credentials are considered expired. + /// + /// For example, if credentials are expiring in 15 minutes, and the buffer time is 10 seconds, + /// then any requests made after 14 minutes and 50 seconds will load new credentials. + /// + /// Defaults to 10 seconds. + pub fn set_buffer_time(&mut self, buffer_time: Option) -> &mut Self { + self.buffer_time = buffer_time; self } - /// (Optional) Default expiration time to set on credentials if they don't - /// have an expiration time. This is only used if the given [`ProvideCredentials`] - /// returns [`Credentials`](aws_types::Credentials) that don't have their `expiry` set. + /// Default expiration time to set on credentials if they don't have an expiration time. + /// + /// This is only used if the given [`ProvideCredentials`] returns + /// [`Credentials`](aws_types::Credentials) that don't have their `expiry` set. /// This must be at least 15 minutes. + /// + /// Defaults to 15 minutes. pub fn default_credential_expiration(mut self, duration: Duration) -> Self { - self.default_credential_expiration = Some(duration); + self.set_default_credential_expiration(Some(duration)); + self + } + + /// Default expiration time to set on credentials if they don't have an expiration time. + /// + /// This is only used if the given [`ProvideCredentials`] returns + /// [`Credentials`](aws_types::Credentials) that don't have their `expiry` set. + /// This must be at least 15 minutes. + /// + /// Defaults to 15 minutes. + pub fn set_default_credential_expiration( + &mut self, + duration: Option, + ) -> &mut Self { + self.default_credential_expiration = duration; self }