Skip to content

Commit

Permalink
Add ECR, ecr example, and chain region provider (#557)
Browse files Browse the repository at this point in the history
  • Loading branch information
rcoh authored Jun 29, 2021
1 parent c3de314 commit 082d05f
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
50 changes: 50 additions & 0 deletions aws/rust-runtime/aws-types/src/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,56 @@ impl Region {
}
}

pub struct ChainProvider {
providers: Vec<Box<dyn ProvideRegion>>,
}

/// Implement a region provider based on a series of region providers
///
/// # Example
/// ```rust
/// use aws_types::region::{ChainProvider, Region};
/// use std::env;
/// // region provider that first checks the `CUSTOM_REGION` environment variable,
/// // then checks the default provider chain, then falls back to us-east-2
/// let provider = ChainProvider::first_try(env::var("CUSTOM_REGION").ok().map(Region::new))
/// .or_default_provider()
/// .or_else(Region::new("us-east-2"));
/// ```
impl ChainProvider {
pub fn first_try(provider: impl ProvideRegion + 'static) -> Self {
ChainProvider {
providers: vec![Box::new(provider)],
}
}
pub fn or_else(mut self, fallback: impl ProvideRegion + 'static) -> Self {
self.providers.push(Box::new(fallback));
self
}

pub fn or_default_provider(mut self) -> Self {
self.providers.push(Box::new(default_provider()));
self
}
}

impl ProvideRegion for Option<Region> {
fn region(&self) -> Option<Region> {
self.clone()
}
}

impl ProvideRegion for ChainProvider {
fn region(&self) -> Option<Region> {
for provider in &self.providers {
if let Some(region) = provider.region() {
return Some(region);
}
}
None
}
}

/// Provide a [`Region`](Region) to use with AWS requests
///
/// For most cases [`default_provider`](default_provider) will be the best option, implementing
Expand Down
1 change: 1 addition & 0 deletions aws/sdk/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ val tier1Services = setOf(
"sqs",
"ssm",
"sts",
"ecr",
"eks"
)

Expand Down
12 changes: 12 additions & 0 deletions aws/sdk/examples/ecr/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "ecr-examples"
version = "0.1.0"
authors = ["Russell Cohen <rcoh@amazon.com>"]
edition = "2018"

[dependencies]
aws-sdk-ecr = { path = "../../build/aws-sdk/ecr" }
tokio = { version = "1", features = ["full"]}
structopt = { version = "0.3", default-features = false }
tracing-subscriber = { version = "0.2.16", features = ["fmt"] }
aws-types = { path = "../../build/aws-sdk/aws-types" }
46 changes: 46 additions & 0 deletions aws/sdk/examples/ecr/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use aws_sdk_ecr::{Config, Region};
use aws_types::region;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
/// The region
#[structopt(short, long)]
region: Option<String>,

#[structopt(long)]
repository: String,

#[structopt(short, long)]
verbose: bool,
}
#[tokio::main]
async fn main() -> Result<(), aws_sdk_ecr::Error> {
let Opt {
region,
repository,
verbose,
} = Opt::from_args();
if verbose {
tracing_subscriber::fmt::init();
}
let provider = region::ChainProvider::first_try(region.map(Region::new))
.or_default_provider()
.or_else(Region::new("us-east-2"));
let client = aws_sdk_ecr::Client::from_conf(Config::builder().region(provider).build());
let rsp = client
.list_images()
.repository_name(&repository)
.send()
.await?;
let images = rsp.image_ids.unwrap_or_default();
println!("found {} images", images.len());
for image in images {
println!(
"image: {}:{}",
image.image_tag.unwrap(),
image.image_digest.unwrap()
);
}
Ok(())
}

0 comments on commit 082d05f

Please sign in to comment.