summaryrefslogtreecommitdiff
path: root/src/autoscaling.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/autoscaling.rs')
-rw-r--r--src/autoscaling.rs52
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()
+}