use std::env; use std::net::SocketAddrV4; use igd::aio::search_gateway; use igd::PortMappingProtocol; use std::collections::HashMap; struct DiplonatConfig { private_ip: String, consul_node_name: String, refresh_time: u32, expiration_time: u32 } fn fetch_configuration() -> Result { let env_private_ip = "DIPLONAT_PRIVATE_IP"; let private_ip = match env::var(env_private_ip) { Ok(val) => val, Err(e) => return Err(format!("unable to fetch environment variable {}: {}", env_private_ip, e)), }; let env_refresh_time = "DIPLONAT_REFRESH_TIME"; let refresh_time: u32 = match env::var(env_refresh_time) { Ok(val) => val.parse().unwrap(), Err(e) => return Err(format!("unable to fetch environment variable {}: {}", env_refresh_time,e)) }; let env_expiration_time = "DIPLONAT_EXPIRATION_TIME"; let expiration_time: u32 = match env::var(env_expiration_time) { Ok(val) => val.parse().unwrap(), Err(e) => return Err(format!("unable to fetch environment variable {}: {}", env_expiration_time,e)) }; let env_consul_node_name = "DIPLONAT_CONSUL_NODE_NAME"; let consul_node_name = match env::var(env_consul_node_name) { Ok(val) => val, Err(e) => return Err(format!("unable to fetch environment variable {}: {}", env_consul_node_name,e)) }; if refresh_time * 2 > expiration_time { return Err(format!("Expiration time (currently: {}s) must be twice bigger than refresh time (currently: {}s)", expiration_time, refresh_time)) } let config = DiplonatConfig { private_ip: private_ip, refresh_time: refresh_time, expiration_time: expiration_time, consul_node_name: consul_node_name }; println!("\tConsul node name: {}", config.consul_node_name); println!("\tPrivate IP address: {}", config.private_ip); println!("\tRefresh time: {} seconds", config.refresh_time); println!("\tExpiration time: {} seconds", config.expiration_time); return Ok(config); } #[tokio::main] async fn main() { let config = match fetch_configuration() { Ok(val) => val, Err(e) => return println!("unable to build configuration: {}", e), }; let url = format!("http://127.0.0.1:8500/v1/catalog/node/{}", config.consul_node_name); let resp = reqwest::get(&url) .await .unwrap(); //.json::>() //.await.unwrap(); println!("{:#?}", resp); let gateway = match search_gateway(Default::default()).await { Ok(g) => g, Err(err) => return println!("Faild to find IGD: {}", err), }; let service = format!("{}:{}", config.private_ip, 1234); let service: SocketAddrV4 = service.parse().expect("Invalid socket address"); match gateway.add_port(PortMappingProtocol::TCP, 1234, service, config.expiration_time, "diplonat").await { Ok(_) => (), Err(e) => return println!("Unable to insert port 1234: {}", e), }; }