use std::convert::TryFrom; use std::fmt::Debug; use anyhow::{anyhow, Result}; use aws_sdk_autoscaling::types::{AutoScalingGroup, Instance, LifecycleState}; use trust_dns_proto::rr::Name; #[derive(Debug)] pub struct AutoScalingGroupConfig { pub name: String, pub live_instance_ids: Vec, } impl AutoScalingGroupConfig { fn live_instance_ids<'a>(instances: impl IntoIterator) -> Vec { instances .into_iter() .filter(|instance| match instance.lifecycle_state() { // See // // Include pending instances so that they can obtain certs, etc. Some(LifecycleState::Pending) => true, Some(LifecycleState::PendingWait) => true, Some(LifecycleState::PendingProceed) => true, Some(LifecycleState::InService) => true, _ => false, }) .flat_map(|instance| instance.instance_id()) .map(ToOwned::to_owned) .collect() } } impl TryFrom<&AutoScalingGroup> for AutoScalingGroupConfig { type Error = anyhow::Error; fn try_from(autoscaling_group: &AutoScalingGroup) -> Result { let name = autoscaling_group .auto_scaling_group_name() .ok_or(anyhow!("Autoscaling group returned from AWS with no name"))? .to_owned(); let instances = autoscaling_group.instances().unwrap_or(&[]); let live_instance_ids = Self::live_instance_ids(instances); Ok(Self { name, live_instance_ids, }) } } pub fn suffixes(mut name: Name) -> Vec { let mut names = Vec::new(); loop { names.push(name.clone()); if name.is_root() { break; } else { name = name.base_name(); } } names } pub fn absolute(name: Name) -> Result { let root = &Name::root(); let absolute = name.append_name(root)?; Ok(absolute) }