diff options
Diffstat (limited to 'src/autoscaling.rs')
| -rw-r--r-- | src/autoscaling.rs | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/src/autoscaling.rs b/src/autoscaling.rs index ea76dc0..ac60613 100644 --- a/src/autoscaling.rs +++ b/src/autoscaling.rs @@ -1,12 +1,39 @@ -use anyhow::{bail, Result}; +use std::collections::HashSet; + +use anyhow::{anyhow, bail, Result}; use aws_sdk_autoscaling as autoscaling; -use aws_sdk_autoscaling::types::AutoScalingGroup; +use aws_sdk_autoscaling::types::{AutoScalingGroup, Instance, LifecycleState}; +use aws_sdk_route53::types::ResourceRecordSet; +use trust_dns_proto::rr::Name; + +use crate::ec2::{instance_recordsets, Ec2}; +use crate::hashable::Hashable; pub trait AutoScaling { fn autoscaling(&self) -> &autoscaling::Client; } -pub async fn asg_by_name<C>(aws_context: &C, name: &str) -> Result<AutoScalingGroup> +pub async fn propose_asg_recordsets<C>( + aws_context: &C, + asg_name: &str, + dns_name: &Name, + dns_ttl: i64, +) -> Result<HashSet<Hashable<ResourceRecordSet>>> +where + C: AutoScaling + Ec2, +{ + let asg = asg_by_name(aws_context, asg_name).await?; + let asg_name = asg + .auto_scaling_group_name() + .ok_or(anyhow!("Autoscaling group returned from AWS with no name"))?; + let live_instance_ids = live_instance_ids(asg.instances()); + let proposed = + instance_recordsets(aws_context, asg_name, dns_name, dns_ttl, &live_instance_ids).await?; + + Ok(proposed) +} + +async fn asg_by_name<C>(aws_context: &C, name: &str) -> Result<AutoScalingGroup> where C: AutoScaling, { @@ -26,3 +53,22 @@ where Ok(group.to_owned()) } + +fn live_instance_ids<'a>(instances: impl IntoIterator<Item = &'a Instance>) -> Vec<String> { + use LifecycleState::*; + 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(Pending) => true, + Some(PendingWait) => true, + Some(PendingProceed) => true, + Some(InService) => true, + _ => false, + }) + .flat_map(|instance| instance.instance_id()) + .map(ToOwned::to_owned) + .collect() +} |
