mod backend;
mod ec2_instance;
mod ec2_instance_definition;
mod ssh;
use std::net::IpAddr;
pub use backend::{Aws, InstanceType, PlacementStrategy};
pub use ec2_instance::{Ec2Instance, NetworkInterface};
pub use ec2_instance_definition::{Ec2InstanceDefinition, InstanceOs};
const USER_TAG_NAME: &str = "aws-throwaway-23c2d22c-d929-43fc-b2a4-c1c72f0b733f:user";
const APP_TAG_NAME: &str = "aws-throwaway-23c2d22c-d929-43fc-b2a4-c1c72f0b733f:app";
pub struct AwsBuilder {
cleanup: CleanupResources,
use_public_addresses: bool,
ingress_restriction: IngressRestriction,
vpc_id: Option<String>,
az_name: Option<String>,
subnet_id: Option<String>,
placement_strategy: PlacementStrategy,
security_group_id: Option<String>,
expose_ports_to_internet: Vec<u16>,
}
impl AwsBuilder {
fn new(cleanup: CleanupResources) -> Self {
AwsBuilder {
cleanup,
use_public_addresses: true,
ingress_restriction: IngressRestriction::NoRestrictions,
vpc_id: None,
az_name: None,
subnet_id: None,
placement_strategy: PlacementStrategy::Spread,
security_group_id: None,
expose_ports_to_internet: vec![],
}
}
pub fn use_public_addresses(mut self, use_public_addresses: bool) -> Self {
self.use_public_addresses = use_public_addresses;
self
}
pub fn use_ingress_restriction(mut self, ingress_restriction: IngressRestriction) -> Self {
self.ingress_restriction = ingress_restriction;
self
}
pub fn use_vpc_id(mut self, vpc_id: Option<String>) -> Self {
self.vpc_id = vpc_id;
self
}
pub fn use_az(mut self, az_name: Option<String>) -> Self {
self.az_name = az_name;
self
}
pub fn use_subnet_id(mut self, subnet_id: Option<String>) -> Self {
self.subnet_id = subnet_id;
self
}
pub fn use_placement_strategy(mut self, placement_strategy: PlacementStrategy) -> Self {
self.placement_strategy = placement_strategy;
self
}
pub fn use_security_group_id(mut self, security_group_id: Option<String>) -> Self {
self.security_group_id = security_group_id;
self
}
pub fn expose_ports_to_internet(mut self, ports: Vec<u16>) -> Self {
self.expose_ports_to_internet = ports;
self
}
pub async fn build(self) -> Aws {
if !self.expose_ports_to_internet.is_empty() && self.security_group_id.is_some() {
panic!(
"Both `use_security_group_id` and `expose_ports_to_internet` are set. Ensure only one of these options is set."
)
}
Aws::new(self).await
}
}
pub enum CleanupResources {
WithAppTag(String),
AllResources,
}
#[non_exhaustive]
pub enum IngressRestriction {
NoRestrictions,
LocalPublicAddress,
}
impl IngressRestriction {
async fn cidr_ip(&self) -> String {
match self {
IngressRestriction::NoRestrictions => "0.0.0.0/0".to_owned(),
IngressRestriction::LocalPublicAddress => {
let api = "https://api.ipify.org";
let ip = reqwest::get(api).await.unwrap().text().await.unwrap();
let ip: IpAddr = ip.parse().unwrap();
format!("{ip}/32")
}
}
}
}