use std::collections::HashSet; use std::fmt::Debug; use anyhow::Result; use aws_sdk_route53::types::ResourceRecordSet; use futures::try_join; use crate::autoscaling::{propose_asg_recordsets, AutoScaling}; use crate::ec2::Ec2; use crate::hashable::Hashable; use crate::route53::{zone_actual_recordsets, zone_for_name, Route53, Target}; #[derive(Debug)] pub struct Changes { pub zone_id: String, pub remove: T, pub insert: T, } pub async fn named_asg_changes( aws_context: &C, target: &Target, asg_name: &str, ) -> Result + Debug>> where C: AutoScaling + Ec2 + Route53, { let zone = zone_for_name(aws_context, target.name()).await?; let (proposed, actual) = try_join!( propose_asg_recordsets(aws_context, target, asg_name), zone_actual_recordsets(aws_context, &zone.id, target.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, } }