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
|
use std::fmt::Debug;
use anyhow::Result;
use clap::Parser;
use trust_dns_proto::rr::Name;
use crate::apply::ApplyMode;
use crate::aws_context::AwsContext;
use crate::converge::propose_transaction;
use crate::route53::Target;
/// Synchronize a DNS entry with an autoscaling group's running instances.
///
/// The given DNS name's A and AAAA records in Route53 will be rewritten to exactly
/// match the list of pending and in-service EC2 instances in the specified
/// autoscaling group. Records of other types (including CNAMEs) will not be
/// modified, so this can be used alongside DNS ACME verification, SPF, and other
/// DNS applications.
#[derive(Parser, Debug)]
pub struct Args {
/// The name of the autoscaling group to synchronize.
#[arg(long)]
autoscaling_group: String,
/// The DNS domain name to synchronize. The most specific Route53 zone that
/// contains this name will be modified.
#[arg(long)]
dns_name: Name,
/// The TTL (in seconds) for newly-created records.
#[arg(long, default_value_t = 60)]
dns_ttl: i64,
/// Print the affected zone ID and pending changes, without applying them (default).
#[arg(long, conflicts_with = "apply")]
dry_run: bool,
/// Apply the changes to Route53.
#[arg(long)]
apply: bool,
}
impl Args {
pub async fn run(self) -> Result<()> {
let args = Args::parse();
let aws_context = AwsContext::from_env().await;
let target = self.target()?;
let transaction =
propose_transaction(&aws_context, &target, &args.autoscaling_group).await?;
self.apply_mode().apply(&aws_context, transaction).await?;
Ok(())
}
fn apply_mode(&self) -> ApplyMode {
use ApplyMode::*;
match (self.dry_run, self.apply) {
(true, false) => DryRun,
(false, true) => Apply,
(false, false) => DryRun,
(true, true) => unreachable!("Cannot set --apply and --dry-run together"),
}
}
fn target(&self) -> Result<Target> {
let target = Target::new(&self.dns_name, self.dns_ttl)?;
Ok(target)
}
}
|