summaryrefslogtreecommitdiff
path: root/src/converge.rs
blob: 29c48780a5f5933b21c63020aa2649a52e7d223e (plain)
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
use std::collections::HashSet;
use std::fmt::Debug;

use anyhow::Result;
use futures::try_join;

use crate::autoscaling::{propose_asg_recordsets, AutoScaling};
use crate::ec2::Ec2;
use crate::route53::{zone_actual_recordsets, zone_for_name, ResourceRecordSet, Route53, Target};

#[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,
    target: &Target,
    asg_name: &str,
) -> Result<Changes<impl IntoIterator<Item = ResourceRecordSet> + 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<T>(
    zone_id: &str,
    intended: &HashSet<T>,
    actual: &HashSet<T>,
) -> Changes<impl IntoIterator<Item = T> + Debug>
where
    T: std::hash::Hash + Eq + Clone + Debug,
{
    let remove: Vec<_> = actual.difference(intended).cloned().collect();
    let insert: Vec<_> = intended.difference(actual).cloned().collect();

    Changes {
        zone_id: zone_id.into(),
        remove,
        insert,
    }
}