use std::collections::HashSet; use std::fmt::Debug; use anyhow::Result; use aws_sdk_route53::types::ResourceRecordSet; use futures::try_join; use trust_dns_proto::rr::Name; use crate::autoscaling::{propose_asg_recordsets, AutoScaling}; use crate::ec2::Ec2; use crate::hashable::Hashable; use crate::route53::{host_recordsets, zone_for_domain, Route53}; #[derive(Debug)] pub struct Changes { pub zone_id: String, pub remove: T, pub insert: T, } pub async fn named_asg_changes( aws_context: &C, asg_name: &str, dns_name: &Name, dns_ttl: i64, ) -> Result + Debug>> where C: AutoScaling + Ec2 + Route53, { let zone = zone_for_domain(aws_context, dns_name).await?; let (proposed, actual) = try_join!( propose_asg_recordsets(aws_context, asg_name, dns_name, dns_ttl), host_recordsets(aws_context, &zone.id, dns_name), )?; let changes = changes_for_records(&zone.id, &proposed, &actual); Ok(changes) } fn changes_for_records( zone_id: &str, intended: &HashSet>, actual: &HashSet>, ) -> Changes + Debug> where Hashable: Eq + std::hash::Hash, T: Clone + Debug, { let remove: Vec<_> = actual .difference(intended) .map(Hashable::as_ref) .cloned() .collect(); let insert: Vec<_> = intended .difference(actual) .map(Hashable::as_ref) .cloned() .collect(); Changes { zone_id: zone_id.into(), remove, insert, } }