summaryrefslogtreecommitdiff
path: root/src/dns.rs
blob: 224d56ec7587a367edd7f2bd0b011d7f8de57dad (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
use std::convert::TryFrom;
use std::fmt::Debug;

use anyhow::{anyhow, Result};
use aws_sdk_autoscaling::types::{AutoScalingGroup, Instance, LifecycleState};
use trust_dns_proto::rr::Name;

#[derive(Debug)]
pub struct AutoScalingGroupConfig {
    pub name: String,
    pub live_instance_ids: Vec<String>,
}

impl AutoScalingGroupConfig {
    fn live_instance_ids<'a>(instances: impl IntoIterator<Item = &'a Instance>) -> Vec<String> {
        instances
            .into_iter()
            .filter(|instance| match instance.lifecycle_state() {
                // See <https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroupLifecycle.html>
                //
                // Include pending instances so that they can obtain certs, etc.
                Some(LifecycleState::Pending) => true,
                Some(LifecycleState::PendingWait) => true,
                Some(LifecycleState::PendingProceed) => true,
                Some(LifecycleState::InService) => true,
                _ => false,
            })
            .flat_map(|instance| instance.instance_id())
            .map(ToOwned::to_owned)
            .collect()
    }
}

impl TryFrom<&AutoScalingGroup> for AutoScalingGroupConfig {
    type Error = anyhow::Error;

    fn try_from(autoscaling_group: &AutoScalingGroup) -> Result<Self> {
        let name = autoscaling_group
            .auto_scaling_group_name()
            .ok_or(anyhow!("Autoscaling group returned from AWS with no name"))?
            .to_owned();

        let instances = autoscaling_group.instances();

        let live_instance_ids = Self::live_instance_ids(instances);

        Ok(Self {
            name,
            live_instance_ids,
        })
    }
}

pub fn suffixes(mut name: Name) -> Vec<Name> {
    let mut names = Vec::new();

    loop {
        names.push(name.clone());
        if name.is_root() {
            break;
        } else {
            name = name.base_name();
        }
    }

    names
}

pub fn absolute(name: Name) -> Result<Name> {
    let root = &Name::root();
    let absolute = name.append_name(root)?;
    Ok(absolute)
}