-
Notifications
You must be signed in to change notification settings - Fork 15
add wstd-aws crate, for integration with aws-sdk #102
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
Merged
Merged
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
686f5e6
wstd::http::client: derive Clone
pchickey fe8b12b
add wstd-aws crate, for using the aws sdk on top of wstd
pchickey fb836a7
wstd-sdk: add s3 bucket listing and fetch as an example
pchickey 6423a8e
ci: assume wstd-aws-ci-role
pchickey e961c41
test runs aws s3 example
pchickey a8949cc
add wstd-aws to publish
pchickey dcda5d0
ci: id-token write
pchickey 8827ead
typo
pchickey 4360d16
runner: forward session token as well
pchickey f9d0ac1
example: bugfix, clean up output
pchickey fb75995
need to debug ci
pchickey 2b6e97a
does action put them into the env properly??
pchickey 8bf30bd
remove debugging, add comments, ci can skip aws if auth fails
pchickey 00066be
readmes
pchickey f200456
typo
pchickey 9d98c4d
comments runner capabilities
pchickey File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,5 @@ | ||
| [target.wasm32-wasip2] | ||
| runner = "wasmtime -Shttp" | ||
| # wasmtime is given: | ||
| # * AWS auth environment variables, for running the wstd-aws integration tests. | ||
| # * . directory is available at . | ||
| runner = "wasmtime run -Shttp --env AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY --env AWS_SESSION_TOKEN --dir .::." | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| .environment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| [package] | ||
| name = "wstd-aws" | ||
| description = "" | ||
| version.workspace = true | ||
| edition.workspace = true | ||
| license.workspace = true | ||
| repository.workspace = true | ||
| keywords.workspace = true | ||
| categories.workspace = true | ||
| rust-version.workspace = true | ||
| authors.workspace = true | ||
|
|
||
| [dependencies] | ||
| anyhow.workspace = true | ||
| aws-smithy-async = { workspace = true } | ||
| aws-smithy-types = { workspace = true, features = ["http-body-1-x"] } | ||
| aws-smithy-runtime-api = { workspace = true, features = ["client", "http-1x"] } | ||
| http-body-util.workspace = true | ||
| sync_wrapper = { workspace = true, features = ["futures"] } | ||
| wstd.workspace = true | ||
|
|
||
| [dev-dependencies] | ||
| aws-config.workspace = true | ||
| aws-sdk-s3.workspace = true | ||
| clap.workspace = true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
|
|
||
| # wstd-aws: wstd support for the AWS Rust SDK | ||
|
|
||
| This crate provides support for using the AWS Rust SDK for the `wasm32-wasip2` | ||
| target using the [`wstd`] crate. | ||
|
|
||
| In many wasi settings, its necessary or desirable to use the wasi-http | ||
| interface to make http requests. Wasi-http interfaces provide an http | ||
| implementation, including the sockets layer and TLS, outside of the user's | ||
| component. `wstd` provides user-friendly async Rust interfaces to all of the | ||
| standardized wasi interfaces, including wasi-http. | ||
|
|
||
| The AWS Rust SDK, by default, depends on `tokio`, `hyper`, and either `rustls` | ||
| or `s2n_tls`, and makes http requests over sockets (which can be provided as | ||
| wasi-sockets). Those dependencies may not work correctly under `wasm32-wasip2`, | ||
| and if they do, they will not use the wasi-http interfaces. To avoid using | ||
| http over sockets, make sure to set the `default-features = false` setting | ||
| when depending on any `aws-*` crates in your project. | ||
|
|
||
| To configure `wstd`'s wasi-http client for the AWS Rust SDK, provide | ||
| `wstd_aws::sleep_impl()` and `wstd_aws::http_client()` to your | ||
| [`aws_config::ConfigLoader`]: | ||
|
|
||
| ``` | ||
| let config = aws_config::defaults(BehaviorVersion::latest()) | ||
| .sleep_impl(wstd_aws::sleep_impl()) | ||
| .http_client(wstd_aws::http_client()) | ||
| ...; | ||
| ``` | ||
|
|
||
| [`wstd`]: https://docs.rs/wstd/latest/wstd | ||
| [`aws_config::ConfigLoader`]: https://docs.rs/aws-config/1.8.8/aws_config/struct.ConfigLoader.html | ||
|
|
||
| ## Example | ||
|
|
||
| An example s3 client is provided as a wasi cli command. It accepts command | ||
| line arguments with the subcommand `list` to list a bucket's contents, and | ||
| `get <key>` to get an object from a bucket and write it to the filesystem. | ||
|
|
||
| This example *must be compiled in release mode* - in debug mode, the aws | ||
| sdk's generated code will overflow the maximum permitted wasm locals in | ||
| a single function. | ||
|
|
||
| Compile it with: | ||
|
|
||
| ```sh | ||
| cargo build -p wstd-aws --target wasm32-wasip2 --release --examples | ||
| ``` | ||
|
|
||
| When running this example, you will need AWS credentials provided in environment | ||
| variables. | ||
|
|
||
| Run it with: | ||
| ```sh | ||
| wasmtime run -Shttp \ | ||
| --env AWS_ACCESS_KEY_ID \ | ||
| --env AWS_SECRET_ACCESS_KEY \ | ||
| --env AWS_SESSION_TOKEN \ | ||
| --dir .::. \ | ||
| target/wasm32-wasip2/release/examples/s3.wasm | ||
| ``` | ||
|
|
||
| or alternatively run it with: | ||
| ```sh | ||
| cargo run --target wasm32-wasip2 -p wstd-aws --example s3 | ||
| ``` | ||
|
|
||
| which uses the wasmtime cli, as above, via configiration found in this | ||
| workspace's `.cargo/config`. | ||
|
|
||
| By default, this script accesses the `wstd-example-bucket` in `us-west-2`. | ||
| To change the bucket or region, use the `--bucket` and `--region` cli | ||
| flags before the subcommand. | ||
|
|
||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| //! Example s3 client running on `wstd` via `wstd_aws` | ||
| //! | ||
| //! This example is a wasi cli command. It accepts command line arguments | ||
| //! with the subcommand `list` to list a bucket's contents, and `get <key>` | ||
| //! to get an object from a bucket and write it to the filesystem. | ||
| //! | ||
| //! This example *must be compiled in release mode* - in debug mode, the aws | ||
| //! sdk's generated code will overflow the maximum permitted wasm locals in | ||
| //! a single function. | ||
| //! | ||
| //! Compile it with: | ||
| //! | ||
| //! ```sh | ||
| //! cargo build -p wstd-aws --target wasm32-wasip2 --release --examples | ||
| //! ``` | ||
| //! | ||
| //! When running this example, you will need AWS credentials provided in environment | ||
| //! variables. | ||
| //! | ||
| //! Run it with: | ||
| //! ```sh | ||
| //! wasmtime run -Shttp \ | ||
| //! --env AWS_ACCESS_KEY_ID \ | ||
| //! --env AWS_SECRET_ACCESS_KEY \ | ||
| //! --env AWS_SESSION_TOKEN \ | ||
| //! --dir .::. \ | ||
| //! target/wasm22-wasip2/release/examples/s3.wasm | ||
| //! ``` | ||
| //! | ||
| //! or alternatively run it with: | ||
| //! ```sh | ||
| //! cargo run --target wasm32-wasip2 -p wstd-aws --example s3 | ||
| //! ``` | ||
| //! | ||
| //! which uses the wasmtime cli, as above, via configiration found in this | ||
| //! workspace's `.cargo/config`. | ||
| //! | ||
| //! By default, this script accesses the `wstd-example-bucket` in `us-west-2`. | ||
| //! To change the bucket or region, use the `--bucket` and `--region` cli | ||
| //! flags before the subcommand. | ||
|
|
||
| use anyhow::Result; | ||
| use clap::{Parser, Subcommand}; | ||
|
|
||
| use aws_config::{BehaviorVersion, Region}; | ||
| use aws_sdk_s3::Client; | ||
|
|
||
| #[derive(Debug, Parser)] | ||
| #[command(version, about, long_about = None)] | ||
| struct Opts { | ||
| /// The AWS Region. Defaults to us-west-2 if not provided. | ||
| #[arg(short, long)] | ||
| region: Option<String>, | ||
| /// The name of the bucket. Defaults to wstd-example-bucket if not | ||
| /// provided. | ||
| #[arg(short, long)] | ||
| bucket: Option<String>, | ||
|
|
||
| #[command(subcommand)] | ||
| command: Option<Command>, | ||
| } | ||
|
|
||
| #[derive(Subcommand, Debug)] | ||
| enum Command { | ||
| List, | ||
| Get { | ||
| key: String, | ||
| #[arg(short, long)] | ||
| out: Option<String>, | ||
| }, | ||
| } | ||
|
|
||
| #[wstd::main] | ||
| async fn main() -> Result<()> { | ||
| let opts = Opts::parse(); | ||
| let region = opts | ||
| .region | ||
| .clone() | ||
| .unwrap_or_else(|| "us-west-2".to_owned()); | ||
| let bucket = opts | ||
| .bucket | ||
| .clone() | ||
| .unwrap_or_else(|| "wstd-example-bucket".to_owned()); | ||
|
|
||
| let config = aws_config::defaults(BehaviorVersion::latest()) | ||
| .region(Region::new(region)) | ||
| .sleep_impl(wstd_aws::sleep_impl()) | ||
| .http_client(wstd_aws::http_client()) | ||
| .load() | ||
| .await; | ||
|
|
||
| let client = Client::new(&config); | ||
|
|
||
| match opts.command.as_ref().unwrap_or(&Command::List) { | ||
| Command::List => { | ||
| let output = list(&bucket, &client).await?; | ||
| print!("{}", output); | ||
| } | ||
| Command::Get { key, out } => { | ||
| let contents = get(&bucket, &client, key).await?; | ||
| let output: &str = if let Some(out) = out { | ||
| out.as_str() | ||
| } else { | ||
| key.as_str() | ||
| }; | ||
| std::fs::write(output, contents)?; | ||
| } | ||
| } | ||
| Ok(()) | ||
| } | ||
|
|
||
| async fn list(bucket: &str, client: &Client) -> Result<String> { | ||
| let mut listing = client | ||
| .list_objects_v2() | ||
| .bucket(bucket.to_owned()) | ||
| .into_paginator() | ||
| .send(); | ||
|
|
||
| let mut output = String::new(); | ||
| output += "key\tetag\tlast_modified\tstorage_class\n"; | ||
| while let Some(res) = listing.next().await { | ||
| let object = res?; | ||
| for item in object.contents() { | ||
| output += &format!( | ||
| "{}\t{}\t{}\t{}\n", | ||
| item.key().unwrap_or_default(), | ||
| item.e_tag().unwrap_or_default(), | ||
| item.last_modified() | ||
| .map(|lm| format!("{lm}")) | ||
| .unwrap_or_default(), | ||
| item.storage_class() | ||
| .map(|sc| format!("{sc}")) | ||
| .unwrap_or_default(), | ||
| ); | ||
| } | ||
| } | ||
| Ok(output) | ||
| } | ||
|
|
||
| async fn get(bucket: &str, client: &Client, key: &str) -> Result<Vec<u8>> { | ||
| let object = client | ||
| .get_object() | ||
| .bucket(bucket.to_owned()) | ||
| .key(key) | ||
| .send() | ||
| .await?; | ||
| let data = object.body.collect().await?; | ||
| Ok(data.to_vec()) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.