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

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

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

pub async fn propose_transaction<C>(
    aws_context: &C,
    target: &Target,
    asg_name: &str,
) -> Result<Transaction<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 = propose_changes(&proposed, &actual);
    let transaction = Transaction {
        zone_id: zone.id().into(),
        changes,
    };
    Ok(transaction)
}

fn propose_changes<T>(
    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 { remove, insert }
}