summaryrefslogtreecommitdiff
path: root/src/apply.rs
blob: 86e92b4ff23ed21693ad33a7fa73730d402c4e4f (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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use aws_sdk_route53::types::{Change, ChangeAction, ChangeBatch, ResourceRecordSet};

use crate::result::Result;
use crate::route53::Route53;

pub enum ApplyMode {
    DryRun,
    Apply,
}

impl ApplyMode {
    pub async fn apply<C, R, I>(
        &self,
        aws_context: &C,
        zone_id: &str,
        remove_records: R,
        insert_records: I,
    ) -> Result<()>
    where
        C: Route53,
        R: IntoIterator<Item = ResourceRecordSet>,
        I: IntoIterator<Item = ResourceRecordSet>,
    {
        match self {
            ApplyMode::DryRun => dry_run(zone_id, remove_records, insert_records).await,
            ApplyMode::Apply => apply(aws_context, zone_id, remove_records, insert_records).await,
        }
    }
}

async fn dry_run<R, I>(zone_id: &str, remove_records: R, insert_records: I) -> Result<()>
where
    R: IntoIterator<Item = ResourceRecordSet>,
    I: IntoIterator<Item = ResourceRecordSet>,
{
    let remove_records: Vec<_> = remove_records.into_iter().collect();
    let insert_records: Vec<_> = insert_records.into_iter().collect();

    println!("ZONE: {}", zone_id);
    println!("REMOVE: {:#?}", remove_records);
    println!("INSERT: {:#?}", insert_records);

    Ok(())
}

async fn apply<C, R, I>(
    aws_context: &C,
    zone_id: &str,
    remove_records: R,
    insert_records: I,
) -> Result<()>
where
    C: Route53,
    R: IntoIterator<Item = ResourceRecordSet>,
    I: IntoIterator<Item = ResourceRecordSet>,
{
    let mut change_batch = ChangeBatch::builder();
    for remove_record in remove_records {
        let change = Change::builder()
            .action(ChangeAction::Delete)
            .resource_record_set(remove_record)
            .build();
        change_batch = change_batch.changes(change);
    }
    for insert_record in insert_records {
        let change = Change::builder()
            .action(ChangeAction::Create)
            .resource_record_set(insert_record)
            .build();
        change_batch = change_batch.changes(change);
    }
    let change_batch = change_batch.build();

    if let Some(changes) = change_batch.changes() {
        if !changes.is_empty() {
            aws_context
                .route53()
                .change_resource_record_sets()
                .hosted_zone_id(zone_id)
                .change_batch(change_batch)
                .send()
                .await?;
        }
    }

    Ok(())
}