1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
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::{zone_actual_recordsets, zone_for_domain, Route53};
#[derive(Debug)]
pub struct Changes<T> {
pub zone_id: String,
pub remove: T,
pub insert: T,
}
pub async fn named_asg_changes<C>(
aws_context: &C,
asg_name: &str,
dns_name: &Name,
dns_ttl: i64,
) -> Result<Changes<impl IntoIterator<Item = ResourceRecordSet> + 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),
zone_actual_recordsets(aws_context, &zone.id, dns_name),
)?;
let changes = changes_for_records(&zone.id, &proposed, &actual);
Ok(changes)
}
fn changes_for_records<T>(
zone_id: &str,
intended: &HashSet<Hashable<T>>,
actual: &HashSet<Hashable<T>>,
) -> Changes<impl IntoIterator<Item = T> + Debug>
where
Hashable<T>: 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,
}
}
|