Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for BehaviorMajorVersions #3151

Merged
merged 9 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,35 @@ references = ["smithy-rs#3160"]
meta = { "breaking" = true, "tada" = false, "bug" = false }
author = "jdisanti"

[[aws-sdk-rust]]
message = """Clients now require a `BehaviorMajorVersion` to be provided. For must customers, `latest` is the best choice. This will be enabled automatically if you enable the `behavior-version-latest` cargo feature on `aws-config` or on an SDK crate. For customers that wish to pin to a specific behavior major version, it can be set in `aws-config` or when constructing the service client.

```rust
async fn example() {
// with aws-config
let conf = aws_config::from_env_with_version(aws_config::BehaviorMajorVersion::v2023_11_09());

// when creating a client
let client = my_service::Client::from_conf(my_service::Config::builder().behavior_major_version(..).<other params>.build());
}
```"""
references = ["smithy-rs#3151"]
author = "rcoh"
meta = { "breaking" = true, "tada" = false, "bug" = false }

[[smithy-rs]]
message = """Clients now require a `BehaviorMajorVersion` to be provided. For must customers, `latest` is the best choice. This will be enabled automatically if you enable the `behavior-version-latest` cargo feature on `aws-config` or on an SDK crate. For customers that wish to pin to a specific behavior major version, it can be set in `aws-config` or when constructing the service client.

```rust
async fn example() {
// when creating a client
let client = my_service::Client::from_conf(my_service::Config::builder().behavior_major_version(..).<other params>.build());
}
```"""
references = ["smithy-rs#3151"]
author = "rcoh"
meta = { "breaking" = true, "tada" = false, "bug" = false }

[[aws-sdk-rust]]
message = "Add `ProvideErrorMetadata` impl for service `Error` type."
references = ["aws-sdk-rust#780", "smithy-rs#3189"]
Expand Down
2 changes: 1 addition & 1 deletion aws/SDK_README.md.hb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The SDK provides one crate per AWS service. You must add [Tokio](https://crates.

```toml
[dependencies]
aws-config = "{{sdk_version_aws_config}}"
aws-config = { version= "{{sdk_version_aws_config}}", features = ["behavior-version-latest"] }
aws-sdk-dynamodb = "{{sdk_version_aws_sdk_dynamodb}}"
tokio = { version = "1", features = ["full"] }
```
Expand Down
2 changes: 2 additions & 0 deletions aws/rust-runtime/aws-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license = "Apache-2.0"
repository = "https://github.com/smithy-lang/smithy-rs"

[features]
behavior-version-latest = []
client-hyper = ["aws-smithy-runtime/connector-hyper-0-14-x"]
rustls = ["aws-smithy-runtime/tls-rustls", "client-hyper"]
allow-compilation = [] # our tests use `cargo test --all-features` and native-tls breaks CI
Expand Down Expand Up @@ -71,6 +72,7 @@ serde_json = "1"
hyper-rustls = { version = "0.24", features = ["webpki-tokio", "http2", "http1"] }
aws-smithy-async = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-async", features = ["rt-tokio", "test-util"] }


[package.metadata.docs.rs]
all-features = true
targets = ["x86_64-unknown-linux-gnu"]
Expand Down
1 change: 1 addition & 0 deletions aws/rust-runtime/aws-config/external-types.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ allowed_external_types = [
"aws_smithy_runtime_api::client::http::SharedHttpClient",
"aws_smithy_runtime_api::client::identity::ResolveCachedIdentity",
"aws_smithy_runtime_api::client::identity::ResolveIdentity",
"aws_smithy_runtime_api::client::behavior_version::BehaviorMajorVersion",
"aws_smithy_runtime_api::client::orchestrator::HttpResponse",
"aws_smithy_runtime_api::client::result::SdkError",
"aws_smithy_types::body::SdkBody",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ mod tests {
use crate::profile::profile_file::{ProfileFileKind, ProfileFiles};
use crate::provider_config::ProviderConfig;
use crate::test_case::{no_traffic_client, InstantSleep};
use aws_smithy_runtime_api::client::behavior_version::BehaviorMajorVersion;
use aws_types::os_shim_internal::{Env, Fs};

#[tokio::test]
Expand All @@ -117,7 +118,7 @@ mod tests {
#[tokio::test]
async fn profile_name_override() {
let fs = Fs::from_slice(&[("test_config", "[profile custom]\nsdk_ua_app_id = correct")]);
let conf = crate::from_env()
let conf = crate::from_env_with_version(BehaviorMajorVersion::latest())
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should rename this to defaults_with_version, and load_from_env_with_version to load_defaults_with_version. In fact, maybe even remove the _with_version part.

.sleep_impl(InstantSleep)
.fs(fs)
.http_client(no_traffic_client())
Expand Down
89 changes: 77 additions & 12 deletions aws/rust-runtime/aws-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
rustdoc::missing_crate_level_docs,
unreachable_pub
)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]

//! `aws-config` provides implementations of region and credential resolution.
//!
Expand All @@ -25,14 +26,15 @@
//!
//! Load default SDK configuration:
//! ```no_run
//! # mod aws_sdk_dynamodb {
//! use aws_config::BehaviorMajorVersion;
//! mod aws_sdk_dynamodb {
//! # pub struct Client;
//! # impl Client {
//! # pub fn new(config: &aws_types::SdkConfig) -> Self { Client }
//! # }
//! # }
//! # async fn docs() {
//! let config = aws_config::load_from_env().await;
//! let config = aws_config::load_from_env_with_version(BehaviorMajorVersion::v2023_11_09()).await;
//! let client = aws_sdk_dynamodb::Client::new(&config);
//! # }
//! ```
Expand All @@ -48,6 +50,7 @@
//! # async fn docs() {
//! # use aws_config::meta::region::RegionProviderChain;
//! let region_provider = RegionProviderChain::default_provider().or_else("us-east-1");
//! // Note: requires the `behavior-version-latest` feature enabled
//! let config = aws_config::from_env().region(region_provider).load().await;
//! let client = aws_sdk_dynamodb::Client::new(&config);
//! # }
Expand Down Expand Up @@ -84,7 +87,7 @@
//! # fn custom_provider(base: &SdkConfig) -> impl ProvideCredentials {
//! # base.credentials_provider().unwrap().clone()
//! # }
//! let sdk_config = aws_config::load_from_env().await;
//! let sdk_config = aws_config::load_from_env_with_version(aws_config::BehaviorMajorVersion::latest()).await;
//! let custom_credentials_provider = custom_provider(&sdk_config);
//! let dynamo_config = aws_sdk_dynamodb::config::Builder::from(&sdk_config)
//! .credentials_provider(custom_credentials_provider)
Expand All @@ -94,9 +97,11 @@
//! ```

pub use aws_smithy_http::endpoint;
pub use aws_smithy_runtime_api::client::behavior_version::BehaviorMajorVersion;
// Re-export types from aws-types
pub use aws_types::{
app_name::{AppName, InvalidAppName},
region::Region,
SdkConfig,
};
/// Load default sources for all configuration with override support
Expand Down Expand Up @@ -137,24 +142,68 @@ pub mod web_identity_token;

/// Create an environment loader for AWS Configuration
///
/// This loader will always set [`BehaviorMajorVersion::latest`].
///
/// # Examples
/// ```no_run
/// # async fn create_config() {
/// use aws_types::region::Region;
/// let config = aws_config::from_env().region("us-east-1").load().await;
/// # }
/// ```
#[cfg(feature = "behavior-version-latest")]
pub fn from_env() -> ConfigLoader {
ConfigLoader::default().behavior_major_version(BehaviorMajorVersion::latest())
}

/// Load configuration from the environment
#[cfg(not(feature = "behavior-version-latest"))]
#[deprecated(
note = "To enable the default behavior version, enable the `behavior-version-latest` feature. Alternatively, you can use [`from_env_with_version`]. This function will be removed in the next release."
)]
pub fn from_env() -> ConfigLoader {
ConfigLoader::default()
ConfigLoader::default().behavior_major_version(BehaviorMajorVersion::latest())
}

/// Load configuration from the environment
#[cfg(not(feature = "behavior-version-latest"))]
#[deprecated(
note = "To enable the default behavior version, enable the `behavior-version-latest` feature. Alternatively, you can use [`load_from_env_with_version`]. This function will be removed in the next release."
)]
pub async fn load_from_env() -> SdkConfig {
load_from_env_with_version(BehaviorMajorVersion::latest()).await
}

/// Create an environment loader for AWS Configuration
///
/// # Examples
/// ```no_run
/// # async fn create_config() {
/// use aws_config::BehaviorMajorVersion;
/// let config = aws_config::from_env_with_version(BehaviorMajorVersion::v2023_11_09())
/// .region("us-east-1")
/// .load()
/// .await;
/// # }
/// ```
pub fn from_env_with_version(version: BehaviorMajorVersion) -> ConfigLoader {
ConfigLoader::default().behavior_major_version(version)
}

/// Load a default configuration from the environment
///
/// Convenience wrapper equivalent to `aws_config::from_env().load().await`
pub async fn load_from_env() -> aws_types::SdkConfig {
#[cfg(feature = "behavior-version-latest")]
pub async fn load_from_env() -> SdkConfig {
from_env().load().await
}

/// Load a default configuration from the environment
///
/// Convenience wrapper equivalent to `aws_config::from_env_with_version(BehaviorMajorVersion::latest()).load().await`
pub async fn load_from_env_with_version(version: BehaviorMajorVersion) -> SdkConfig {
from_env_with_version(version).load().await
}

mod loader {
use crate::default_provider::use_dual_stack::use_dual_stack_provider;
use crate::default_provider::use_fips::use_fips_provider;
Expand All @@ -165,6 +214,7 @@ mod loader {
use aws_credential_types::provider::{ProvideCredentials, SharedCredentialsProvider};
use aws_smithy_async::rt::sleep::{default_async_sleep, AsyncSleep, SharedAsyncSleep};
use aws_smithy_async::time::{SharedTimeSource, TimeSource};
use aws_smithy_runtime_api::client::behavior_version::BehaviorMajorVersion;
use aws_smithy_runtime_api::client::http::HttpClient;
use aws_smithy_runtime_api::client::identity::{ResolveCachedIdentity, SharedIdentityCache};
use aws_smithy_runtime_api::shared::IntoShared;
Expand Down Expand Up @@ -212,9 +262,19 @@ mod loader {
time_source: Option<SharedTimeSource>,
env: Option<Env>,
fs: Option<Fs>,
behavior_major_version: Option<BehaviorMajorVersion>,
}

impl ConfigLoader {
/// Sets the [`BehaviorMajorVersion`] used to build [`SdkConfig`](aws_types::SdkConfig).
pub fn behavior_major_version(
mut self,
behavior_major_version: BehaviorMajorVersion,
) -> Self {
self.behavior_major_version = Some(behavior_major_version);
self
}

/// Override the region used to build [`SdkConfig`](aws_types::SdkConfig).
///
/// # Examples
Expand Down Expand Up @@ -571,7 +631,7 @@ mod loader {
/// .enable_http1()
/// .build();
/// let provider_config = ProviderConfig::default().with_tcp_connector(custom_https_connector);
/// let shared_config = aws_config::from_env().configure(provider_config).load().await;
/// let shared_config = aws_config::from_env_with_version(BehaviorVersion::latest()).configure(provider_config).load().await;
/// # }
/// ```
#[deprecated(
Expand Down Expand Up @@ -692,6 +752,7 @@ mod loader {
.timeout_config(timeout_config)
.time_source(time_source);

builder.set_behavior_major_version(self.behavior_major_version);
builder.set_http_client(self.http_client);
builder.set_app_name(app_name);
builder.set_identity_cache(self.identity_cache);
Expand Down Expand Up @@ -721,7 +782,8 @@ mod loader {
mod test {
use crate::profile::profile_file::{ProfileFileKind, ProfileFiles};
use crate::test_case::{no_traffic_client, InstantSleep};
use crate::{from_env, ConfigLoader};
use crate::BehaviorMajorVersion;
use crate::{from_env_with_version, ConfigLoader};
use aws_credential_types::provider::ProvideCredentials;
use aws_smithy_async::rt::sleep::TokioSleep;
use aws_smithy_runtime::client::http::test_util::{infallible_client_fn, NeverClient};
Expand All @@ -742,7 +804,7 @@ mod loader {
]);
let fs =
Fs::from_slice(&[("test_config", "[profile custom]\nsdk-ua-app-id = correct")]);
let loader = from_env()
let loader = from_env_with_version(BehaviorMajorVersion::latest())
.sleep_impl(TokioSleep::new())
.env(env)
.fs(fs)
Expand Down Expand Up @@ -786,7 +848,7 @@ mod loader {
}

fn base_conf() -> ConfigLoader {
from_env()
from_env_with_version(BehaviorMajorVersion::latest())
.sleep_impl(InstantSleep)
.http_client(no_traffic_client())
}
Expand Down Expand Up @@ -816,7 +878,10 @@ mod loader {
#[cfg(feature = "rustls")]
#[tokio::test]
async fn disable_default_credentials() {
let config = from_env().no_credentials().load().await;
let config = from_env_with_version(BehaviorMajorVersion::latest())
.no_credentials()
.load()
.await;
assert!(config.identity_cache().is_none());
assert!(config.credentials_provider().is_none());
}
Expand All @@ -829,7 +894,7 @@ mod loader {
movable.fetch_add(1, Ordering::Relaxed);
http::Response::new("ok!")
});
let config = from_env()
let config = from_env_with_version(BehaviorMajorVersion::latest())
.fs(Fs::from_slice(&[]))
.env(Env::from_slice(&[]))
.http_client(http_client.clone())
Expand Down
3 changes: 2 additions & 1 deletion aws/rust-runtime/aws-config/src/provider_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ impl ProviderConfig {
.region(self.region())
.time_source(self.time_source())
.use_fips(self.use_fips().unwrap_or_default())
.use_dual_stack(self.use_dual_stack().unwrap_or_default());
.use_dual_stack(self.use_dual_stack().unwrap_or_default())
.behavior_major_version(crate::BehaviorMajorVersion::latest());
builder.set_http_client(self.http_client.clone());
builder.set_sleep_impl(self.sleep_impl.clone());
builder.build()
Expand Down
5 changes: 4 additions & 1 deletion aws/rust-runtime/aws-config/src/sso/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,9 @@ impl Builder {
/// This will panic if any of the required fields are not given.
pub async fn build(mut self) -> SsoTokenProvider {
if self.sdk_config.is_none() {
self.sdk_config = Some(crate::load_from_env().await);
self.sdk_config = Some(
crate::load_from_env_with_version(crate::BehaviorMajorVersion::latest()).await,
);
}
self.build_with(Env::real(), Fs::real())
}
Expand Down Expand Up @@ -427,6 +429,7 @@ mod tests {
.sleep_impl(SharedAsyncSleep::new(sleep_impl))
// disable retry to simplify testing
.retry_config(RetryConfig::disabled())
.behavior_major_version(crate::BehaviorMajorVersion::latest())
.build();
Self {
time_source,
Expand Down
Loading