diff options
Diffstat (limited to 'src/route53.rs')
| -rw-r--r-- | src/route53.rs | 47 |
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 + } +} |
