Expand description
§Zone Update
A minimal Rust library providing CRUD-like operations on DNS records with various DNS providers.
§Overview
Zone Update is a lightweight library that provides a simple interface for programmatically managing DNS zone records through provider APIs. The library is both blocking and async, and supports multiple async runtimes (see below).
§Supported DNS providers
Currently, Zone Update supports the following DNS providers:
- Bunny
- Cloudflare
- deSEC
- DigitalOcean
- Dnsimple
- DnsMadeEasy
- Gandi
- Linode
- Porkbun
See the DNS providers matrix for more details.
§Supported platforms
zone-update supports both blocking and async APIs. For async the library
attempts to be as provider-agnostic; it is known (tested) to work with the
following runtimes:
zone-update is tested against Linux, Mac & Windows.
§Feature flags
Each DNS provider is gated behind their name, however all provider are enabled
by default. To limit the providers you can add zone-update to your
Cargo.toml in the following format:
zone-update = { version = "*", default-features = false, features = ["digitalocean", "desec"] }The other notable flag is async, which is not enabled by default.
§Usage
§Basic Example
use zone_update::{gandi, DnsProvider, errors::Result};
use std::net::Ipv4Addr;
fn update_gandi_record() -> Result<()> {
let config = zone_update::Config {
domain: "example.com".to_string(),
dry_run: false,
};
let auth = gandi::Auth::ApiKey("your-api-key".to_string());
let client = gandi::Gandi::new(config, auth);
let host = "www";
let new_ip = Ipv4Addr::new(192, 0, 2, 1);
// Update the A record for www.example.com
client.update_a_record(host, &new_ip)?;
Ok(())
}§Provider lookup from configuration file
The Provider enum supports deserialisation with serde, which allows runtime
lookup of DNS providers from a configuration file:
use serde::Deserialize;
use zone_update::{Provider, errors::Result};
use std::net::Ipv4Addr;
const CONFIG_TOML: &str = r#"
domain = "example.com"
dry_run = true
[provider]
name = "porkbun"
key = "my_key"
secret = "my_secret"
"#;
#[derive(Deserialize)]
pub struct MyConfig {
domain: String,
dry_run: bool,
provider: Provider,
}
fn update_website_record() -> Result<()> {
let config: MyConfig = toml::from_str(CONFIG_TOML).unwrap();
let zu_config = zone_update::Config {
domain: config.domain,
dry_run: config.dry_run,
};
let client = config.provider
.blocking_impl(zu_config);
let host = "www";
let new_ip = Ipv4Addr::new(192, 0, 2, 1);
// Update the A record for www.example.com
client.update_a_record(host, &new_ip)?;
Ok(())
}See the examples directory for other use-cases.
§Contributing
At this point the most useful contributions would be to add additional DNS provider APIs. However other contributions are welcome.
§Steps for adding a new provider
This needs to be expanded, and the existing implementations are currently your best reference, but is a basic checklist:
- Create a new module directory under
srcand addmod.rsand (recommended)types.rs. Create the appropriate features flags inCargo.toml. - Add the necessary type structures with serde annotations; you will need to
consult the API documentation and/or experiment with
curl. - Create a structure for the provider implementation (usually just wrapping
Auth&Config. - Implement the core CRUD operations in the
DnsProvidertrait for this struct. This tends to be provider-specific, but most follow on of several patterns. The existing implementations can be consulted as a reference. - Use the
generate_helpersmacro to fill out the rest of the trait. - Create a test module and use the
generate_testsmacro to create the standard tests. - Run the tests against a sandbox or working account (Do Not Skip This Step).
- Once the blocking API implemented the async implementation is generated by macros. See an existing provider impl.
- Add you provider to the
Providerenum and its impl. - Raise a PR.
§AI Contribution Policy
This reason this project will not accept runtime code generated by AI. Generation of draft documentation and test code is acceptable, but should be reviewed by the submitter before raising a PR.
§License
This project is licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Modules§
Macros§
- generate_
helpers - A macro to generate default helper implementations for provider impls.
Structs§
- Config
- Configuration for DNS operations.
Enums§
- Provider
- DNS provider selection used by this crate.
- Record
Type
Traits§
- DnsProvider
- A trait for a DNS provider.