dns-update-lite 0.5.9

Dynamic DNS update (RFC 2136 and cloud) library for Rust. Lightweight fork of dns-update
Documentation
# dns-update-lite

[![crates.io](https://img.shields.io/crates/v/dns-update-lite)](https://crates.io/crates/dns-update-lite)
[![docs.rs](https://img.shields.io/docsrs/dns-update-lite)](https://docs.rs/dns-update-lite)
[![crates.io](https://img.shields.io/crates/l/dns-update-lite)](http://www.apache.org/licenses/LICENSE-2.0)

_dns-update-lite_ is an **Dynamic DNS update library** for Rust that supports updating DNS records using the [RFC 2136](https://datatracker.ietf.org/doc/html/rfc2136) protocol
and few cloud, registrar, and self-hosted DNS provider APIs. It was designed to be simple and easy to use, while providing a high level of flexibility and performance.

Based on [dns-update](https://github.com/stalwartlabs/dns-update), being trimmed down.

## Supported providers

| Provider                                                             | Constructor            | Notes                 |
| -------------------------------------------------------------------- | ---------------------- | --------------------- |
| [RFC 2136]https://datatracker.ietf.org/doc/html/rfc2136            | `new_rfc2136_tsig`     | TSIG authentication   |
| [Bunny DNS]https://bunny.net/dns/                                  | `new_bunny`            |                       |
| [Cloudflare]https://www.cloudflare.com/                            | `new_cloudflare`       | API token or X-Auth-* |
| [deSEC]https://desec.io/                                           | `new_desec`            |                       |
| [DigitalOcean]https://www.digitalocean.com/products/networking/dns | `new_digitalocean`     |                       |
| [DNSimple]https://dnsimple.com/                                    | `new_dnsimple`         |                       |
| [Google Cloud DNS]https://cloud.google.com/dns                     | `new_google_cloud_dns` | Service account JWT   |
| [OVH]https://www.ovh.com/                                          | `new_ovh`              |                       |
| [Porkbun]https://porkbun.com/                                      | `new_porkbun`          |                       |
| [AWS Route 53]https://aws.amazon.com/route53/                      | `new_route53`          | AWS Sigv4             |
| [Spaceship]https://www.spaceship.com/                              | `new_spaceship`        |                       |

## API

Every provider exposes three RRSet-oriented methods on `DnsUpdater`. All three operate on the full RRSet at `(name, type)` and are idempotent.

```rust,ignore
async fn set_rrset(name, type, ttl, records: Vec<DnsRecord>, origin) -> Result<()>
async fn add_to_rrset(name, type, ttl, records: Vec<DnsRecord>, origin) -> Result<()>
async fn remove_from_rrset(name, type, records: Vec<DnsRecord>, origin) -> Result<()>
```

- `set_rrset` replaces the RRSet at `(name, type)` with exactly `records`.
  An empty `Vec` deletes the RRSet. Other types at the same owner are
  never touched.
- `add_to_rrset` ensures `records` are present at the owner without
  removing anything else.
- `remove_from_rrset` removes only the listed values; other values at the
  same owner are preserved.

## Usage Example

Publishing a TXT record using RFC 2136 over TSIG:

```rust,ignore
let client = DnsUpdater::new_rfc2136_tsig(
    "tcp://127.0.0.1:53",
    "<KEY_NAME>",
    STANDARD.decode("<TSIG_KEY>").unwrap(),
    TsigAlgorithm::HmacSha512,
)
.unwrap();

// Publish the entire RRSet at this owner in one atomic operation. Empty
// Vec deletes the RRSet. Rerunning with the same input is a no-op.
client
    .set_rrset(
        "test._domainkey.example.org",
        DnsRecordType::TXT,
        300,
        vec![DnsRecord::TXT("v=DKIM1; k=rsa; h=sha256; p=test".to_string())],
        "example.org",
    )
    .await
    .unwrap();

// Delete the RRSet.
client
    .set_rrset(
        "test._domainkey.example.org",
        DnsRecordType::TXT,
        0,
        vec![],
        "example.org",
    )
    .await
    .unwrap();
```

`add_to_rrset` is for "publish this value alongside whatever else is there"
(e.g. an ACME challenge token that should coexist with the user's DKIM/SPF
TXTs at the same owner):

```rust,ignore
client
    .add_to_rrset(
        "_acme-challenge.example.org",
        DnsRecordType::TXT,
        60,
        vec![DnsRecord::TXT("challenge-token".to_string())],
        "example.org",
    )
    .await
    .unwrap();

client
    .remove_from_rrset(
        "_acme-challenge.example.org",
        DnsRecordType::TXT,
        vec![DnsRecord::TXT("challenge-token".to_string())],
        "example.org",
    )
    .await
    .unwrap();
```

## License

Licensed under either of

- Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

## Copyright

Copyright (C) 2020, Stalwart Labs LLC
Copyright (C) 2026, Ferron