Im trying to get some Rust CLI magic going at our company. However im having some problems since getting even basic stuff working is hard since its a large company with lots of enterprise problems. One such problem is that we use a proxy. We use AWS for all our services so a must for my CLI tool is to work with rusoto. I have come up with different variations of the following code:
use exitfailure::ExitFailure;
use rusoto_core::{Region, HttpClient};
use rusoto_sts::{StsClient, StsAssumeRoleSessionCredentialsProvider};
use rusoto_ssm::{SsmClient, GetParametersRequest, Ssm};
use rusoto_credential::EnvironmentProvider;
use std::env;
use hyper_proxy::{Proxy, ProxyConnector, Intercept};
use hyper_tls::HttpsConnector;
pub fn run_aws(role_arn: &String) -> Result<(), ExitFailure> {
let region = Region::EuWest1;
let sts = match env::var("HTTPS_PROXY") {
Ok(proxy_uri) => {
let proxy = Proxy::new(Intercept::All, proxy_uri.parse()?);
let proxy_connector = ProxyConnector::from_proxy(HttpsConnector::new(4), proxy)?;
let http = HttpClient::from_connector(proxy_connector);
StsClient::new_with(http, EnvironmentProvider::default(), region.to_owned())
},
Err(_) => StsClient::new(region.to_owned()),
};
// let sts = StsClient::new(Region::EuWest1);
let provider = StsAssumeRoleSessionCredentialsProvider::new(sts, role_arn.to_owned(), "default".to_owned(), None, None, None, None);
let auto_refreshing_provider = rusoto_credential::AutoRefreshingProvider::new(provider).unwrap();
let client = SsmClient::new_with(HttpClient::new().unwrap(), auto_refreshing_provider, region.to_owned());
let get_parameters: GetParametersRequest = Default::default();
match client.get_parameters(get_parameters).sync() {
Ok(output) => {
match output.parameters {
Some(parameters) => {
println!("Parameters in ssm");
for parameter in parameters {
println!("{}", parameter.name.unwrap());
}
},
None => println!("Error no parameters found"),
}
},
Err(error) => {
println!("Error: {:?}", error);
},
}
Ok(())
}
First it produced:
Error: HttpDispatch(HttpDispatchError { message: "error trying to connect: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to
respond. (os error 10060)" })
Then I tried to change the HttpConnector
to a HttpsConnector
since the debug log says im doing the following request:
[2019-11-05T06:40:24Z DEBUG rusoto_core::request] Full request:
method: POST
final_uri: https://ssm.eu-west-1.amazonaws.com/
payload: {"Names":[]}
Headers:
Now the code does not even type check and im not sure what to do next.
Any help with getting this setup working would be much appreciated.
Below is the rest of the code:
[package]
name = "some"
version = "0.1.0"
authors = ["xxx"]
edition = "2018"
[dependencies]
structopt = "0.3"
failure = "0.1.5"
exitfailure = "0.5.1"
log = "0.4.8"
env_logger = "0.7.1"
rusoto_core = "0.41.0"
rusoto_sts = "0.41.0"
rusoto_ssm = "0.41.0"
rusoto_credential = "0.41.0"
hyper = "0.12.35"
hyper-proxy = "0.5.1"
hyper-tls = "0.3.2"
[dev-dependencies]
assert_cmd = "0.10"
predicates = "1"
use structopt::StructOpt;
use exitfailure::ExitFailure;
/// Administer the DPAP service
#[derive(StructOpt)]
struct Cli {
/// The role arn to assume
#[structopt(short="r", long="role_arn")]
role_arn: String,
}
fn main() -> Result<(), ExitFailure> {
env_logger::init();
let args = Cli::from_args();
mylib::run_aws(&args.role_arn)?;
Ok(())
}