如果未找到环境变量,我如何回退到文件中的凭据?
How can I fallback to credentials from a file if no environment variables are found?
如果未找到环境变量,我如何回退使用已解析文件 (config.yml
) 中的凭据?为了测试,我使用 this example:
extern crate rusoto_core;
extern crate rusoto_s3;
use rusoto_core::credential::ChainProvider;
use rusoto_core::request::HttpClient;
use rusoto_core::Region;
use rusoto_s3::{S3, S3Client};
use std::time::{Duration, Instant};
fn main() {
let mut chain = ChainProvider::new();
chain.set_timeout(Duration::from_millis(200));
let s3client = S3Client::new_with(
HttpClient::new().expect("failed to create request dispatcher"),
chain,
Region::UsEast1,
);
let start = Instant::now();
println!("Starting up at {:?}", start);
match s3client.list_buckets().sync() {
Err(e) => println!("Error listing buckets: {}", e),
Ok(buckets) => println!("Buckets found: {:?}", buckets),
};
println!("Took {:?}", Instant::now().duration_since(start));
}
它可以工作,但需要环境变量 AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
。我想扩展它,以便如果没有定义的环境变量,我可以使用在解析文件中找到的键:
// parse config file
let file = std::fs::File::open("config.yml").expect("Unable to open file");
let yml: Config = match serde_yaml::from_reader(file) {
Err(err) => {
println!("Error: {}", err);
return;
}
Ok(yml) => yml,
};
例如 config.yml
可能是这样的:
---
endpoint: s3.provider
access_key: ACCESS_KEY_ID
secret_key: SECRET_ACCESS_KEY
我可以向 chain
添加什么以使用在 config.yml
中找到的凭据,可能类似于:
let config_provider = StaticProvider::new_minimal(yml.access_key, yml.secret_key);
如何优先选择环境,如果找不到则使用 StaticProvider
?
提供的凭据
ChainProvider
实际上有 four sources 来检查 AWS 凭据。第三个是位于用户主目录中的 AWS 配置文件。但它的格式是预先确定的。
如果您坚持使用自己的 YAML 文件,您可以像这样将 EnvironmentProvider
和 StaticProvider
链接在一起:
//# futures01 = { package = "futures", version = "0.1.28" }
//# rusoto_core = "0.41.0"
//# rusoto_s3 = "0.41.0"
//# rusoto_credential = "0.41.1"
use futures01::future::Future;
use rusoto_core::request::HttpClient;
use rusoto_core::Region;
use rusoto_credential::{
AwsCredentials,
CredentialsError,
EnvironmentProvider,
ProvideAwsCredentials,
StaticProvider,
};
use rusoto_s3::{S3, S3Client};
use std::time::Instant;
struct MyChainProvider<'a> {
access_key: &'a str,
secret_key: &'a str,
}
impl<'a> ProvideAwsCredentials for MyChainProvider<'a> {
type Future = Box<dyn Future<Item=AwsCredentials, Error=CredentialsError> + Send>;
fn credentials(&self) -> Self::Future {
let future = EnvironmentProvider::default().credentials()
.or_else({
let access_key = self.access_key.to_string();
let secret_key = self.secret_key.to_string();
move |_| -> Self::Future {
Box::new(StaticProvider::new_minimal(access_key, secret_key).credentials())
}
});
Box::new(future)
}
}
fn main() {
let chain = MyChainProvider {
access_key: ...,
secret_key: ...,
};
...
}
如果未找到环境变量,我如何回退使用已解析文件 (config.yml
) 中的凭据?为了测试,我使用 this example:
extern crate rusoto_core;
extern crate rusoto_s3;
use rusoto_core::credential::ChainProvider;
use rusoto_core::request::HttpClient;
use rusoto_core::Region;
use rusoto_s3::{S3, S3Client};
use std::time::{Duration, Instant};
fn main() {
let mut chain = ChainProvider::new();
chain.set_timeout(Duration::from_millis(200));
let s3client = S3Client::new_with(
HttpClient::new().expect("failed to create request dispatcher"),
chain,
Region::UsEast1,
);
let start = Instant::now();
println!("Starting up at {:?}", start);
match s3client.list_buckets().sync() {
Err(e) => println!("Error listing buckets: {}", e),
Ok(buckets) => println!("Buckets found: {:?}", buckets),
};
println!("Took {:?}", Instant::now().duration_since(start));
}
它可以工作,但需要环境变量 AWS_ACCESS_KEY_ID
和 AWS_SECRET_ACCESS_KEY
。我想扩展它,以便如果没有定义的环境变量,我可以使用在解析文件中找到的键:
// parse config file
let file = std::fs::File::open("config.yml").expect("Unable to open file");
let yml: Config = match serde_yaml::from_reader(file) {
Err(err) => {
println!("Error: {}", err);
return;
}
Ok(yml) => yml,
};
例如 config.yml
可能是这样的:
---
endpoint: s3.provider
access_key: ACCESS_KEY_ID
secret_key: SECRET_ACCESS_KEY
我可以向 chain
添加什么以使用在 config.yml
中找到的凭据,可能类似于:
let config_provider = StaticProvider::new_minimal(yml.access_key, yml.secret_key);
如何优先选择环境,如果找不到则使用 StaticProvider
?
ChainProvider
实际上有 four sources 来检查 AWS 凭据。第三个是位于用户主目录中的 AWS 配置文件。但它的格式是预先确定的。
如果您坚持使用自己的 YAML 文件,您可以像这样将 EnvironmentProvider
和 StaticProvider
链接在一起:
//# futures01 = { package = "futures", version = "0.1.28" }
//# rusoto_core = "0.41.0"
//# rusoto_s3 = "0.41.0"
//# rusoto_credential = "0.41.1"
use futures01::future::Future;
use rusoto_core::request::HttpClient;
use rusoto_core::Region;
use rusoto_credential::{
AwsCredentials,
CredentialsError,
EnvironmentProvider,
ProvideAwsCredentials,
StaticProvider,
};
use rusoto_s3::{S3, S3Client};
use std::time::Instant;
struct MyChainProvider<'a> {
access_key: &'a str,
secret_key: &'a str,
}
impl<'a> ProvideAwsCredentials for MyChainProvider<'a> {
type Future = Box<dyn Future<Item=AwsCredentials, Error=CredentialsError> + Send>;
fn credentials(&self) -> Self::Future {
let future = EnvironmentProvider::default().credentials()
.or_else({
let access_key = self.access_key.to_string();
let secret_key = self.secret_key.to_string();
move |_| -> Self::Future {
Box::new(StaticProvider::new_minimal(access_key, secret_key).credentials())
}
});
Box::new(future)
}
}
fn main() {
let chain = MyChainProvider {
access_key: ...,
secret_key: ...,
};
...
}