summaryrefslogtreecommitdiff
path: root/src/route53.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/route53.rs')
-rw-r--r--src/route53.rs47
1 files changed, 42 insertions, 5 deletions
diff --git a/src/route53.rs b/src/route53.rs
index e63ce4c..74938bf 100644
--- a/src/route53.rs
+++ b/src/route53.rs
@@ -3,13 +3,12 @@ use std::str::FromStr;
use anyhow::{anyhow, Result};
use aws_sdk_route53 as route53;
-use aws_sdk_route53::types::{HostedZone, ResourceRecord, ResourceRecordSet, RrType};
+use aws_sdk_route53::types::{HostedZone, ResourceRecord, RrType};
// Needed until try_collect is stable, see <https://github.com/rust-lang/rust/issues/94047>
use itertools::Itertools;
use trust_dns_proto::rr::Name;
use crate::dns;
-use crate::hashable::Hashable;
pub trait Route53 {
fn route53(&self) -> &route53::Client;
@@ -55,7 +54,7 @@ pub async fn zone_actual_recordsets<C>(
aws_context: &C,
zone_id: &str,
dns_name: &Name,
-) -> Result<HashSet<Hashable<ResourceRecordSet>>>
+) -> Result<HashSet<ResourceRecordSet>>
where
C: Route53,
{
@@ -130,14 +129,52 @@ impl Target {
.map(|address| ResourceRecord::builder().value(address).build())
.try_collect()?;
- let record_set = ResourceRecordSet::builder()
+ let record_set = route53::types::ResourceRecordSet::builder()
.name(self.name().to_ascii())
.r#type(rr_type)
.ttl(self.ttl)
.set_resource_records(Some(records))
- .build()?;
+ .build()?
+ .into();
Ok(Some(record_set))
}
}
}
+
+// ResourceRecordSet isn't hashable (reasonably enough), but we're going to do set difference on them
+// later to identify which records to remove, and which to keep. This wrapper type adds a trivial - but
+// probably correct - implementation of Hash and Eq so that ResourceRecordSet instances can be stored
+// in hash sets.
+#[derive(Clone, Debug, PartialEq)]
+pub struct ResourceRecordSet(route53::types::ResourceRecordSet);
+
+// Equality is based on the observation that ResourceRecordSet already implements partialeq by derive,
+// and that none of its fields have any actual partially-equal results. As a result, any two
+// ResourceRecordSet instances that are fieldwise-equal are themselves equal under PartialEq. Promote
+// this result to Eq.
+impl Eq for ResourceRecordSet {}
+
+// Hash ResourceRecordSet instances by name and address(es).
+impl std::hash::Hash for ResourceRecordSet {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ self.0.name().hash(state);
+ self.0
+ .resource_records()
+ .iter()
+ .map(ResourceRecord::value)
+ .for_each(|val| val.hash(state));
+ }
+}
+
+impl From<route53::types::ResourceRecordSet> for ResourceRecordSet {
+ fn from(recordset: route53::types::ResourceRecordSet) -> Self {
+ Self(recordset)
+ }
+}
+
+impl From<ResourceRecordSet> for route53::types::ResourceRecordSet {
+ fn from(recordset: ResourceRecordSet) -> Self {
+ recordset.0
+ }
+}