dns-update-lite 0.5.9

Dynamic DNS update (RFC 2136 and cloud) library for Rust. Lightweight fork of dns-update
Documentation
#[cfg(any(feature = "ring", feature = "aws-lc-rs"))]
use crate::providers::ovh::{OvhEndpoint, OvhProvider};

#[cfg(feature = "test_provider")]
use crate::providers::in_memory::InMemoryProvider;

#[cfg(feature = "test_provider")]
use crate::NamedDnsRecord;

#[cfg(feature = "test_provider")]
use std::sync::{Arc, Mutex};

/// Dispatch an `DnsProvider` method call across every [`DnsUpdater`] variant.
///
/// Each arm forwards the given arguments to the variant's inner provider. The
/// macro keeps the four delegating methods in `update.rs` from duplicating the
/// same match over every provider.
macro_rules! dispatch_provider {
    ($self:expr, $method:ident ( $($arg:expr),* $(,)? ) ) => {
        match $self {
            DnsUpdater::Rfc2136(provider) => provider.$method($($arg),*).await,
            DnsUpdater::Cloudflare(provider) => provider.$method($($arg),*).await,
            DnsUpdater::DigitalOcean(provider) => provider.$method($($arg),*).await,
            DnsUpdater::Desec(provider) => provider.$method($($arg),*).await,
            #[cfg(any(feature = "ring", feature = "aws-lc-rs"))]
            DnsUpdater::Ovh(provider) => provider.$method($($arg),*).await,
            DnsUpdater::Bunny(provider) => provider.$method($($arg),*).await,
            DnsUpdater::Porkbun(provider) => provider.$method($($arg),*).await,
            DnsUpdater::Spaceship(provider) => provider.$method($($arg),*).await,
            DnsUpdater::DNSimple(provider) => provider.$method($($arg),*).await,
            DnsUpdater::GoogleCloudDns(provider) => provider.$method($($arg),*).await,
            DnsUpdater::Route53(provider) => provider.$method($($arg),*).await,
            #[cfg(feature = "test_provider")]
            DnsUpdater::InMemory(provider) => provider.$method($($arg),*).await,
        }
    };
}

use crate::{
    DnsRecord, DnsRecordType, DnsUpdater, IntoFqdn, TsigAlgorithm,
    providers::{
        bunny::BunnyProvider,
        cloudflare::CloudflareProvider,
        desec::DesecProvider,
        digitalocean::DigitalOceanProvider,
        dnsimple::DNSimpleProvider,
        google_cloud_dns::GoogleCloudDnsProvider,
        porkbun::PorkBunProvider,
        rfc2136::{DnsAddress, Rfc2136Provider},
        route53::Route53Provider,
        spaceship::SpaceshipProvider,
    },
};
use std::time::Duration;

impl DnsUpdater {
    /// Create a new DNS updater using the RFC 2136 protocol and TSIG authentication.
    pub fn new_rfc2136_tsig(
        addr: impl TryInto<DnsAddress>,
        key_name: impl AsRef<str>,
        key: impl Into<Vec<u8>>,
        algorithm: TsigAlgorithm,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::Rfc2136(Rfc2136Provider::new_tsig(
            addr,
            key_name,
            key,
            algorithm.into(),
        )?))
    }

    /// Create a new DNS updater using the Cloudflare API.
    pub fn new_cloudflare(
        secret: impl AsRef<str>,
        timeout: Option<Duration>,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::Cloudflare(CloudflareProvider::new(
            secret, timeout,
        )?))
    }

    /// Create a new DNS updater using the DigitalOcean API.
    pub fn new_digitalocean(
        auth_token: impl AsRef<str>,
        timeout: Option<Duration>,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::DigitalOcean(DigitalOceanProvider::new(
            auth_token, timeout,
        )))
    }

    /// Create a new DNS updater using the Desec.io API.
    pub fn new_desec(
        auth_token: impl AsRef<str>,
        timeout: Option<Duration>,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::Desec(DesecProvider::new(auth_token, timeout)))
    }

    /// Create a new DNS updater using the OVH API.
    #[cfg(any(feature = "ring", feature = "aws-lc-rs"))]
    pub fn new_ovh(
        application_key: impl AsRef<str>,
        application_secret: impl AsRef<str>,
        consumer_key: impl AsRef<str>,
        endpoint: OvhEndpoint,
        timeout: Option<Duration>,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::Ovh(OvhProvider::new(
            application_key,
            application_secret,
            consumer_key,
            endpoint,
            timeout,
        )?))
    }

    /// Create a new DNS updater using the Bunny API.
    pub fn new_bunny(api_key: impl AsRef<str>, timeout: Option<Duration>) -> crate::Result<Self> {
        Ok(DnsUpdater::Bunny(BunnyProvider::new(api_key, timeout)?))
    }

    /// Create a new DNS updater using the Porkbun API.
    pub fn new_porkbun(
        api_key: impl AsRef<str>,
        secret_api_key: impl AsRef<str>,
        timeout: Option<Duration>,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::Porkbun(PorkBunProvider::new(
            api_key,
            secret_api_key,
            timeout,
        )))
    }

    /// Create a new DNS updater using the Spaceship API.
    pub fn new_spaceship(
        api_key: impl AsRef<str>,
        api_secret: impl AsRef<str>,
        timeout: Option<Duration>,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::Spaceship(SpaceshipProvider::new(
            api_key, api_secret, timeout,
        )))
    }

    /// Create a new DNS updater using the DNSimple API.
    pub fn new_dnsimple(
        auth_token: impl AsRef<str>,
        account_id: impl AsRef<str>,
        timeout: Option<Duration>,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::DNSimple(DNSimpleProvider::new(
            auth_token, account_id, timeout,
        )))
    }

    /// Create a new DNS updater using the Google Cloud DNS API.
    pub fn new_google_cloud_dns(
        config: crate::providers::google_cloud_dns::GoogleCloudDnsConfig,
    ) -> crate::Result<Self> {
        Ok(DnsUpdater::GoogleCloudDns(GoogleCloudDnsProvider::new(
            config,
        )?))
    }

    /// Create a new DNS updater using the Route53 API.
    pub fn new_route53(config: crate::providers::route53::Route53Config) -> crate::Result<Self> {
        Ok(DnsUpdater::Route53(Route53Provider::new(config)))
    }

    /// Create a new DNS updater backed by an in-memory record store.
    #[cfg(feature = "test_provider")]
    pub fn new_in_memory(records: Arc<Mutex<Vec<NamedDnsRecord>>>) -> Self {
        DnsUpdater::InMemory(InMemoryProvider::new(records))
    }

    /// Atomically replace the RRSet at (name, type). An empty `records` Vec deletes the RRSet.
    pub async fn set_rrset(
        &self,
        name: impl IntoFqdn<'_>,
        record_type: DnsRecordType,
        ttl: u32,
        records: Vec<DnsRecord>,
        origin: impl IntoFqdn<'_>,
    ) -> crate::Result<()> {
        dispatch_provider!(self, set_rrset(name, record_type, ttl, records, origin))
    }

    /// Add records to the RRSet at (name, type). Idempotent: values already present are skipped.
    pub async fn add_to_rrset(
        &self,
        name: impl IntoFqdn<'_>,
        record_type: DnsRecordType,
        ttl: u32,
        records: Vec<DnsRecord>,
        origin: impl IntoFqdn<'_>,
    ) -> crate::Result<()> {
        dispatch_provider!(self, add_to_rrset(name, record_type, ttl, records, origin))
    }

    /// Remove the listed records from the RRSet at (name, type). Idempotent: values not present are skipped.
    pub async fn remove_from_rrset(
        &self,
        name: impl IntoFqdn<'_>,
        record_type: DnsRecordType,
        records: Vec<DnsRecord>,
        origin: impl IntoFqdn<'_>,
    ) -> crate::Result<()> {
        dispatch_provider!(self, remove_from_rrset(name, record_type, records, origin))
    }

    /// List the records of the RRSet at (name, type). Returns an empty Vec when the RRSet does not exist.
    pub async fn list_rrset(
        &self,
        name: impl IntoFqdn<'_>,
        record_type: DnsRecordType,
        origin: impl IntoFqdn<'_>,
    ) -> crate::Result<Vec<DnsRecord>> {
        dispatch_provider!(self, list_rrset(name, record_type, origin))
    }
}