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

feat: support compiling to webassembly #2254

Merged
merged 48 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
ffa9923
feat(aws-config): define default feature for sso
eduardomourar Jan 25, 2023
91a8dcc
chore(aws): disable unused features
eduardomourar Jan 25, 2023
1fbd97b
chore(rust-runtime): disable unused features
eduardomourar Jan 25, 2023
06a62b7
chore: add missing tokio fs feature
eduardomourar Jan 26, 2023
a725e0c
chore: disable spawn blocking on wasm
eduardomourar Jan 26, 2023
cae60ef
chore: fix sso feature
eduardomourar Jan 26, 2023
ef00e01
chore: allow unused variables when not sso
eduardomourar Jan 26, 2023
497c4b9
chore: remove unnecessary dependency filter for wasm
eduardomourar Jan 26, 2023
59791df
chore: add integration test for wasm
eduardomourar Jan 26, 2023
7478507
chore: ensure test-util feature is applied to dev dependencies
eduardomourar Jan 26, 2023
56b7b33
chore: disable retry config
eduardomourar Jan 26, 2023
d8fcf49
chore: simplify features as suggested
eduardomourar Jan 26, 2023
86a5689
chore: no default features for aws types
eduardomourar Jan 26, 2023
c0d61ed
chore: rename credentials-sso feature
eduardomourar Jan 26, 2023
a5b6316
Revert "chore: simplify features as suggested"
eduardomourar Jan 27, 2023
f2d47b5
chore: set right name in default features
eduardomourar Jan 27, 2023
df4ab9e
chore: create smithy client test util in runtime types
eduardomourar Jan 27, 2023
154342f
Update aws/rust-runtime/aws-types/Cargo.toml
eduardomourar Jan 27, 2023
937022c
Update aws/rust-runtime/aws-inlineable/Cargo.toml
eduardomourar Jan 27, 2023
08df0df
Update aws/rust-runtime/aws-config/src/profile/credentials/exec.rs
eduardomourar Jan 27, 2023
98d336e
Update aws/rust-runtime/aws-config/src/profile/credentials/exec.rs
eduardomourar Jan 27, 2023
45cae40
Update aws/rust-runtime/aws-config/src/profile/credentials/exec.rs
eduardomourar Jan 27, 2023
1687bbc
Update aws/rust-runtime/aws-config/src/lib.rs
eduardomourar Jan 27, 2023
14e23fb
chore: use hardcoded credentials feature
eduardomourar Jan 30, 2023
be22904
chore: make wasm example for s3 instead
eduardomourar Jan 30, 2023
6a578ec
chore: fix formatting
eduardomourar Jan 30, 2023
1406d42
Merge remote-tracking branch 'origin/main' into feat/support-wasm
eduardomourar Jan 30, 2023
25c8fd3
chore: fix kotlin formatting
eduardomourar Jan 30, 2023
4791b46
chore: fix kotlin unit tests
eduardomourar Jan 30, 2023
40136bd
chore: use timeout config from smithy types
eduardomourar Jan 30, 2023
00234f2
Merge branch 'main' into feat/support-wasm
eduardomourar Feb 1, 2023
40da289
Merge branch 'main' into feat/support-wasm
eduardomourar Mar 15, 2023
2755357
chore: move tests into main file
eduardomourar Mar 16, 2023
5fc3dfd
chore: add vscode setttings to target wasi by default
eduardomourar Mar 16, 2023
0506f75
chore: fix test-util feature for smithy client
eduardomourar Mar 16, 2023
bc4f686
chore: separate adapter into own module
eduardomourar Mar 22, 2023
d353ac3
Merge branch 'main' into feat/support-wasm
eduardomourar Mar 22, 2023
0beea87
chore: fix test with no default features
eduardomourar Mar 22, 2023
0d52a87
Merge branch 'main' into feat/support-wasm
eduardomourar Mar 24, 2023
ffe83ea
Fix typo
jdisanti Mar 24, 2023
0ec8283
Update changelog
jdisanti Mar 24, 2023
01f106c
Check compilation of `aws-config` against `wasm32` in CI
jdisanti Mar 24, 2023
bc2fe6c
Merge remote-tracking branch 'origin/main' into support-wasm
jdisanti Mar 24, 2023
ba00b09
Fix Dockerfile issue and use correct cargo-wasi command
jdisanti Mar 24, 2023
04c7094
Small Dockerfile fix
jdisanti Mar 24, 2023
7e90fb3
Add missing `tar` binary to Docker image
jdisanti Mar 24, 2023
4bfd4e4
Merge branch 'main' into feat/support-wasm
jdisanti Mar 24, 2023
5e63eec
Merge branch 'main' into feat/support-wasm
rcoh Mar 29, 2023
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
14 changes: 13 additions & 1 deletion CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,16 @@
# message = "Fix typos in module documentation for generated crates"
# references = ["smithy-rs#920"]
# meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client | server | all"}
# author = "rcoh"
# author = "rcoh"

[[aws-sdk-rust]]
message = "The AWS SDK now compiles for the `wasm32-unknown-unknown` and `wasm32-wasi` targets when no default features are enabled. WebAssembly is not officially supported yet, but this is a great first step towards it!"
references = ["smithy-rs#2254"]
meta = { "breaking" = false, "tada" = true, "bug" = false }
author = "eduardomourar"

[[smithy-rs]]
message = "Clients now compile for the `wasm32-unknown-unknown` and `wasm32-wasi` targets when no default features are enabled. WebAssembly is not officially supported yet, but this is a great first step towards it!"
references = ["smithy-rs#2254"]
meta = { "breaking" = false, "tada" = true, "bug" = false, "target" = "client"}
author = "eduardomourar"
15 changes: 8 additions & 7 deletions aws/rust-runtime/aws-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ client-hyper = ["aws-smithy-client/client-hyper"]
rustls = ["aws-smithy-client/rustls"]
native-tls = ["aws-smithy-client/native-tls"]
rt-tokio = ["aws-smithy-async/rt-tokio", "tokio/rt"]
credentials-sso = ["dep:aws-sdk-sso", "dep:ring", "dep:hex", "dep:zeroize"]

default = ["client-hyper", "rustls", "rt-tokio"]
default = ["client-hyper", "rustls", "rt-tokio", "credentials-sso"]

[dependencies]
aws-credential-types = { path = "../../sdk/build/aws-sdk/sdk/aws-credential-types" }
aws-http = { path = "../../sdk/build/aws-sdk/sdk/aws-http" }
aws-sdk-sso = { path = "../../sdk/build/aws-sdk/sdk/sso", default-features = false }
aws-sdk-sts = { path = "../../sdk/build/aws-sdk/sdk/sts", default-features = false }
aws-smithy-async = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-async" }
aws-smithy-client = { path = "../../sdk/build/aws-sdk/sdk/aws-smithy-client", default-features = false }
Expand All @@ -33,18 +33,19 @@ time = { version = "0.3.4", features = ["parsing"] }
tokio = { version = "1.13.1", features = ["sync"] }
tracing = { version = "0.1" }

# implementation detail of SSO credential caching
ring = "0.16"
hex = "0.4.3"
zeroize = "1"

# implementation detail of IMDS credentials provider
fastrand = "1"

bytes = "1.1.0"
http = "0.2.4"
tower = { version = "0.4.8" }

# implementation detail of SSO credential caching
aws-sdk-sso = { path = "../../sdk/build/aws-sdk/sdk/sso", default-features = false, optional = true }
ring = { version = "0.16", optional = true }
hex = { version = "0.4.3", optional = true }
zeroize = { version = "1", optional = true }

[dev-dependencies]
futures-util = { version = "0.3.16", default-features = false }
tracing-test = "0.2.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@ mod test {
make_test!(ecs_credentials);
make_test!(ecs_credentials_invalid_profile);

#[cfg(feature = "credentials-sso")]
make_test!(sso_assume_role);
#[cfg(feature = "credentials-sso")]
make_test!(sso_no_token_file);

#[tokio::test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

use crate::provider_config::ProviderConfig;
use aws_sdk_sso::config::timeout::TimeoutConfig;
use aws_smithy_types::timeout::TimeoutConfig;
use std::time::Duration;

const SDK_DEFAULT_CONNECT_TIMEOUT: Duration = Duration::from_millis(3100);
Expand Down
4 changes: 2 additions & 2 deletions aws/rust-runtime/aws-config/src/ecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,15 +418,15 @@ async fn validate_full_uri(
}
}

#[cfg(not(feature = "rt-tokio"))]
#[cfg(any(not(feature = "rt-tokio"), target_family = "wasm"))]
fn tokio_dns() -> Option<DnsService> {
None
}

/// DNS resolver that uses tokio::spawn_blocking
///
/// DNS resolution is required to validate that provided URIs point to the loopback interface
#[cfg(feature = "rt-tokio")]
#[cfg(all(feature = "rt-tokio", not(target_family = "wasm")))]
fn tokio_dns() -> Option<DnsService> {
use aws_smithy_client::erase::boxclone::BoxFuture;
use std::io::ErrorKind;
Expand Down
2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-config/src/imds/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use crate::imds::client::token::TokenMiddleware;
use crate::provider_config::ProviderConfig;
use crate::PKG_VERSION;
use aws_http::user_agent::{ApiMetadata, AwsUserAgent, UserAgentStage};
use aws_sdk_sso::config::timeout::TimeoutConfig;
use aws_smithy_client::http_connector::ConnectorSettings;
use aws_smithy_client::{erase::DynConnector, SdkSuccess};
use aws_smithy_client::{retry, SdkError};
Expand All @@ -28,6 +27,7 @@ use aws_smithy_http_tower::map_request::{
};
use aws_smithy_types::error::display::DisplayErrorContext;
use aws_smithy_types::retry::{ErrorKind, RetryKind};
use aws_smithy_types::timeout::TimeoutConfig;
use aws_types::os_shim_internal::Env;
use bytes::Bytes;
use http::{Response, Uri};
Expand Down
2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-config/src/imds/client/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use crate::imds::client::ImdsResponseRetryClassifier;
use aws_credential_types::cache::ExpiringCache;
use aws_credential_types::time_source::TimeSource;
use aws_http::user_agent::UserAgentStage;
use aws_sdk_sso::config::timeout::TimeoutConfig;
use aws_smithy_async::rt::sleep::AsyncSleep;
use aws_smithy_client::erase::DynConnector;
use aws_smithy_client::retry;
Expand All @@ -31,6 +30,7 @@ use aws_smithy_http::operation::Operation;
use aws_smithy_http::operation::{Metadata, Request};
use aws_smithy_http::response::ParseStrictResponse;
use aws_smithy_http_tower::map_request::MapRequestLayer;
use aws_smithy_types::timeout::TimeoutConfig;
use http::{HeaderValue, Uri};
use std::fmt::{Debug, Formatter};
use std::future::Future;
Expand Down
2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-config/src/imds/credentials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ mod test {
#[tokio::test]
#[cfg(any(feature = "rustls", feature = "native-tls"))]
async fn external_timeout_during_credentials_refresh_should_yield_last_retrieved_credentials() {
use aws_sdk_sso::config::AsyncSleep;
use aws_smithy_async::rt::sleep::AsyncSleep;
let client = crate::imds::Client::builder()
// 240.* can never be resolved
.endpoint(http::Uri::from_static("http://240.0.0.0"))
Expand Down
1 change: 1 addition & 0 deletions aws/rust-runtime/aws-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ pub mod meta;
pub mod profile;
pub mod provider_config;
pub mod retry;
#[cfg(feature = "credentials-sso")]
pub mod sso;
pub(crate) mod standard_property;
pub mod sts;
Expand Down
25 changes: 18 additions & 7 deletions aws/rust-runtime/aws-config/src/profile/credentials/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use super::repr::{self, BaseProvider};
use crate::credential_process::CredentialProcessProvider;
use crate::profile::credentials::ProfileFileError;
use crate::provider_config::ProviderConfig;
#[cfg(feature = "credentials-sso")]
use crate::sso::{SsoConfig, SsoCredentialsProvider};
use crate::sts;
use crate::web_identity_token::{StaticConfiguration, WebIdentityTokenCredentialsProvider};
Expand Down Expand Up @@ -117,19 +118,29 @@ impl ProviderChain {
.build();
Arc::new(provider)
}
#[allow(unused_variables)]
BaseProvider::Sso {
sso_account_id,
sso_region,
sso_role_name,
sso_start_url,
} => {
let sso_config = SsoConfig {
account_id: sso_account_id.to_string(),
role_name: sso_role_name.to_string(),
start_url: sso_start_url.to_string(),
region: Region::new(sso_region.to_string()),
};
Arc::new(SsoCredentialsProvider::new(provider_config, sso_config))
#[cfg(feature = "credentials-sso")]
{
let sso_config = SsoConfig {
account_id: sso_account_id.to_string(),
role_name: sso_role_name.to_string(),
start_url: sso_start_url.to_string(),
region: Region::new(sso_region.to_string()),
};
Arc::new(SsoCredentialsProvider::new(provider_config, sso_config))
}
#[cfg(not(feature = "credentials-sso"))]
{
Err(ProfileFileError::UnknownProvider {
name: "sso".to_string(),
})?
}
}
};
tracing::info!(base = ?repr.base(), "first credentials will be loaded from {:?}", repr.base());
Expand Down
2 changes: 1 addition & 1 deletion aws/rust-runtime/aws-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repository = "https://github.com/awslabs/smithy-rs"

[features]
# This feature is to be used only for doc comments
examples = ["aws-smithy-client/client-hyper", "aws-smithy-client/rustls", "hyper-rustls"]
examples = ["dep:hyper-rustls", "aws-smithy-client/client-hyper", "aws-smithy-client/rustls"]

[dependencies]
aws-credential-types = { path = "../aws-credential-types" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ class EndpointsCredentialsTest {
assert!(auth_header.contains("/us-west-2/foobaz/aws4_request"), "{}", auth_header);
""",
"capture_request" to RuntimeType.captureRequest(context.runtimeConfig),
"Credentials" to AwsCargoDependency.awsCredentialTypes(context.runtimeConfig)
.withFeature("test-util").toType().resolve("Credentials"),
"Credentials" to AwsRuntimeType.awsCredentialTypesTestUtil(context.runtimeConfig)
.resolve("Credentials"),
"Region" to AwsRuntimeType.awsTypes(context.runtimeConfig).resolve("region::Region"),
)
}
Expand All @@ -120,8 +120,8 @@ class EndpointsCredentialsTest {
assert!(auth_header.contains("/region-custom-auth/name-custom-auth/aws4_request"), "{}", auth_header);
""",
"capture_request" to RuntimeType.captureRequest(context.runtimeConfig),
"Credentials" to AwsCargoDependency.awsCredentialTypes(context.runtimeConfig)
.withFeature("test-util").toType().resolve("Credentials"),
"Credentials" to AwsRuntimeType.awsCredentialTypesTestUtil(context.runtimeConfig)
.resolve("Credentials"),
"Region" to AwsRuntimeType.awsTypes(context.runtimeConfig).resolve("region::Region"),
)
}
Expand Down
1 change: 1 addition & 0 deletions aws/sdk/integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ members = [
"sts",
"transcribestreaming",
"using-native-tls-instead-of-rustls",
"webassembly",
Copy link
Collaborator

Choose a reason for hiding this comment

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

We have some prerequisite work to do before this will run in CI. I'll see if I can get around to that today.

Copy link
Contributor Author

@eduardomourar eduardomourar Jan 26, 2023

Choose a reason for hiding this comment

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

Our best option is to install cargo-wasi then run cargo wasi test -- --nocapture

Copy link
Collaborator

Choose a reason for hiding this comment

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

That aspect of it didn't even cross my mind yet 😅

I did the prerequisite work to actually include the tests in the first place in #2255.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in the tokio crate, they have a nice a setup for testing against the different webassembly targets: https://github.com/tokio-rs/tokio/blob/06f1a601bb05b1aba9f95020a7fa7572899c588f/.github/workflows/ci.yml#L529-L590

]
5 changes: 5 additions & 0 deletions aws/sdk/integration-tests/webassembly/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build]
target = "wasm32-wasi"

[target.wasm32-wasi]
rustflags = ["-C", "opt-level=1"]
3 changes: 3 additions & 0 deletions aws/sdk/integration-tests/webassembly/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"rust-analyzer.cargo.target": "wasm32-wasi"
}
30 changes: 30 additions & 0 deletions aws/sdk/integration-tests/webassembly/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This Cargo.toml is unused in generated code. It exists solely to enable these tests to compile in-situ
[package]
name = "webassembly"
version = "0.1.0"
authors = ["Eduardo Rodrigues <16357187+eduardomourar@users.noreply.github.com>"]
description = """
These tests ensure that things will fail (or not fail) as expected
when target is set to wasm32-wasi for all SDK and runtime crates.
"""
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/awslabs/smithy-rs"
publish = false

[lib]
crate-type = ["cdylib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
aws-config = { path = "../../build/aws-sdk/sdk/aws-config", default-features = false, features = ["rt-tokio"]}
aws-credential-types = { path = "../../build/aws-sdk/sdk/aws-credential-types", features = ["hardcoded-credentials"] }
aws-sdk-s3 = { path = "../../build/aws-sdk/sdk/s3", default-features = false }
aws-smithy-client = { path = "../../build/aws-sdk/sdk/aws-smithy-client", default-features = false }
aws-smithy-http = { path = "../../build/aws-sdk/sdk/aws-smithy-http" }
aws-smithy-types = { path = "../../build/aws-sdk/sdk/aws-smithy-types" }
aws-types = { path = "../../build/aws-sdk/sdk/aws-types" }
http = "0.2.8"
tokio = { version = "1.24.2", features = ["macros", "rt"] }
tower = "0.4.13"
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

use aws_smithy_http::body::SdkBody;

pub(crate) fn make_request(_req: http::Request<SdkBody>) -> Result<http::Response<SdkBody>, ()> {
// Consumers here would pass the HTTP request to
// the Wasm host in order to get the response back
let body = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<ListAllMyBucketsResult>
<Buckets>
<Bucket>
<CreationDate>2023-01-23T11:59:03.575496Z</CreationDate>
<Name>doc-example-bucket</Name>
</Bucket>
<Bucket>
<CreationDate>2023-01-23T23:32:13.125238Z</CreationDate>
<Name>doc-example-bucket2</Name>
</Bucket>
</Buckets>
<Owner>
<DisplayName>account-name</DisplayName>
<ID>a3a42310-42d0-46d1-9745-0cee9f4fb851</ID>
</Owner>
</ListAllMyBucketsResult>";
Ok(http::Response::new(SdkBody::from(body)))
}
44 changes: 44 additions & 0 deletions aws/sdk/integration-tests/webassembly/src/adapter/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

mod http_client;

use aws_smithy_client::erase::DynConnector;
use aws_smithy_client::http_connector::HttpConnector;
use aws_smithy_http::body::SdkBody;
use aws_smithy_http::result::ConnectorError;
use std::task::{Context, Poll};
use tower::Service;

#[derive(Default, Debug, Clone)]
pub(crate) struct Adapter {}

impl Adapter {
pub fn to_http_connector() -> impl Into<HttpConnector> {
DynConnector::new(Adapter::default())
}
}

impl Service<http::Request<SdkBody>> for Adapter {
type Response = http::Response<SdkBody>;

type Error = ConnectorError;

#[allow(clippy::type_complexity)]
type Future = std::pin::Pin<
Box<dyn std::future::Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>,
>;

fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}

fn call(&mut self, req: http::Request<SdkBody>) -> Self::Future {
println!("Adapter: sending request...");
let res = http_client::make_request(req).unwrap();
println!("{:?}", res);
Box::pin(async move { Ok(res) })
}
}
33 changes: 33 additions & 0 deletions aws/sdk/integration-tests/webassembly/src/default_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

use aws_config::retry::RetryConfig;
use aws_credential_types::Credentials;
use aws_smithy_types::timeout::TimeoutConfig;
use aws_types::region::Region;
use std::future::Future;

use crate::adapter::Adapter;

pub(crate) fn get_default_config() -> impl Future<Output = aws_config::SdkConfig> {
aws_config::from_env()
.region(Region::from_static("us-west-2"))
.credentials_provider(Credentials::from_keys(
"access_key",
"secret_key",
Some("session_token".to_string()),
))
.timeout_config(TimeoutConfig::disabled())
.retry_config(RetryConfig::disabled())
.http_connector(Adapter::to_http_connector())
.load()
}

#[tokio::test]
pub async fn test_default_config() {
let shared_config = get_default_config().await;
let client = aws_sdk_s3::Client::new(&shared_config);
assert_eq!(client.conf().region().unwrap().to_string(), "us-west-2")
}
13 changes: 13 additions & 0 deletions aws/sdk/integration-tests/webassembly/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

mod adapter;
mod default_config;
mod list_buckets;

#[tokio::main(flavor = "current_thread")]
pub async fn main() {
crate::list_buckets::s3_list_buckets().await
}
Loading