1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use hyper::Uri;
use std::env::var as env_var;
use std::time::Duration as StdDuration;
use tokio_core::reactor::Core;
use {AwsCredentials, CredentialsError, ProvideAwsCredentials, ProvideTimeoutableAwsCredentials,
make_request, parse_credentials_from_aws_service};
const AWS_CREDENTIALS_PROVIDER_IP: &'static str = "169.254.170.2";
#[derive(Debug)]
pub struct ContainerProvider;
impl ProvideAwsCredentials for ContainerProvider {
fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {
credentials_from_container(None)
}
}
impl ProvideTimeoutableAwsCredentials for ContainerProvider {
fn credentials_with_timeout(
&self,
timeout: StdDuration,
) -> Result<AwsCredentials, CredentialsError> {
credentials_from_container(Some(timeout))
}
}
fn credentials_from_container(
timeout: Option<StdDuration>,
) -> Result<AwsCredentials, CredentialsError> {
let aws_container_credentials_relative_uri =
match env_var("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") {
Ok(v) => v,
Err(_) => {
return Err(CredentialsError::new(
"No AWS_CONTAINER_CREDENTIALS_RELATIVE_URI in environment",
))
}
};
let address: String = format!(
"http://{}{}/",
AWS_CREDENTIALS_PROVIDER_IP,
aws_container_credentials_relative_uri
);
let core = try!(Core::new());
let uri = try!(address.parse::<Uri>());
match make_request(core, uri, timeout) {
Ok(resp) => parse_credentials_from_aws_service(&resp),
Err(err) => {
return Err(CredentialsError::new(
format!("Couldn't connect to credentials provider: {}", err),
))
}
}
}