Crate bindcar

Crate bindcar 

Source
Expand description

bindcar - HTTP REST API for managing BIND9 zones via RNDC

A lightweight library that provides programmatic control over BIND9 DNS zones using the RNDC (Remote Name Daemon Control) protocol.

§Features

  • Create, delete, and manage BIND9 zones dynamically
  • Execute RNDC commands asynchronously
  • Zone file generation and management
  • Shared request/response types for API operations
  • Authentication support (Bearer tokens and Kubernetes ServiceAccounts)
  • Prometheus metrics integration

§Usage

This crate can be used as both a library and a standalone binary:

§As a Library

§Using RNDC Executor

use bindcar::RndcExecutor;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let executor = RndcExecutor::new(
        "127.0.0.1:953".to_string(),
        "sha256".to_string(),
        "dGVzdC1zZWNyZXQtaGVyZQ==".to_string(), // base64 encoded secret
    )?;

    // Execute RNDC commands
    let status = executor.status().await?;
    println!("BIND9 Status: {}", status);

    Ok(())
}

§Using Shared Types (for API clients)

use bindcar::{CreateZoneRequest, ZoneConfig, SoaRecord, DnsRecord};
use std::collections::HashMap;

// Create nameserver glue records
let mut ns_ips = HashMap::new();
ns_ips.insert("ns1.example.com.".to_string(), "192.0.2.10".to_string());

// Create a zone creation request
let request = CreateZoneRequest {
    zone_name: "example.com".to_string(),
    zone_type: "primary".to_string(),
    zone_config: ZoneConfig {
        ttl: 3600,
        soa: SoaRecord {
            primary_ns: "ns1.example.com.".to_string(),
            admin_email: "admin.example.com.".to_string(),
            serial: 2025010101,
            refresh: 3600,
            retry: 600,
            expire: 604800,
            negative_ttl: 86400,
        },
        name_servers: vec!["ns1.example.com.".to_string()],
        name_server_ips: ns_ips,
        records: vec![
            DnsRecord {
                name: "@".to_string(),
                record_type: "A".to_string(),
                value: "192.0.2.1".to_string(),
                ttl: None,
                priority: None,
            },
        ],
        also_notify: None,
        allow_transfer: None,
        primaries: None,
        dnssec_policy: None,
        inline_signing: None,
    },
    update_key_name: None,
};

// Serialize to JSON for API requests
let json = serde_json::to_string(&request).unwrap();

§As a Binary

cargo install bindcar
bindcar

§Zone File Generation

The serial field in SoaRecord will auto-generate in YYYYMMDD01 format if omitted from JSON.

use bindcar::{ZoneConfig, SoaRecord, DnsRecord};
use std::collections::HashMap;

// Example JSON can omit serial for auto-generation:
let json = r#"{
  "ttl": 3600,
  "soa": {
    "primaryNs": "ns1.example.com.",
    "adminEmail": "admin.example.com."
  },
  "nameServers": ["ns1.example.com."],
  "nameServerIps": {
    "ns1.example.com.": "192.0.2.10"
  },
  "records": []
}"#;

let zone_config: ZoneConfig = serde_json::from_str(json).unwrap();
let zone_file_content = zone_config.to_zone_file();
println!("{}", zone_file_content);

§Integration with Other Projects

This library is designed to be used by other projects (like bindy) that need to interact with the bindcar API. By importing this crate, you get:

  • Type-safe request/response structures
  • Automatic JSON serialization/deserialization
  • OpenAPI schema compatibility
  • No need to maintain duplicate type definitions

Re-exports§

pub use rndc::RndcExecutor;
pub use nsupdate::NsupdateExecutor;
pub use types::ApiError;
pub use types::AppState;
pub use types::ErrorResponse;
pub use zones::DnsRecord;
pub use zones::SoaRecord;
pub use zones::ZoneConfig;
pub use zones::CreateZoneRequest;
pub use zones::ServerStatusResponse;
pub use zones::ZoneInfo;
pub use zones::ZoneListResponse;
pub use zones::ZoneResponse;
pub use zones::ZONE_TYPE_PRIMARY;
pub use zones::ZONE_TYPE_SECONDARY;
pub use records::AddRecordRequest;
pub use records::RecordResponse;
pub use records::RemoveRecordRequest;
pub use records::UpdateRecordRequest;
pub use rndc::parse_rndc_conf;
pub use rndc::RndcConfig;
pub use rndc_conf_parser::parse_rndc_conf_file;
pub use rndc_conf_parser::parse_rndc_conf_str;
pub use rndc_conf_types::KeyBlock;
pub use rndc_conf_types::OptionsBlock;
pub use rndc_conf_types::RndcConfFile;
pub use rndc_conf_types::ServerAddress;
pub use rndc_conf_types::ServerBlock;

Modules§

auth
Authentication middleware for Kubernetes ServiceAccount tokens
metrics
Prometheus metrics for bindcar
middleware
Middleware for metrics collection
nsupdate
nsupdate command executor for dynamic DNS updates
rate_limit
Rate limiting middleware for HTTP requests
records
DNS record management API handlers
rndc
RNDC command execution using native RNDC protocol
rndc_conf_parser
RNDC configuration file parser
rndc_conf_types
RNDC configuration data types
rndc_parser
RNDC output parser
rndc_types
RNDC data types for parsing BIND9 output
types
Common types and errors used throughout the bindcar library
zones
Zone management API handlers