Skip to main content

Pydantic-based BIND9 configuration management library

Project description

bindantic

PyPI version Python versions License Coverage

bindantic - a library for managing BIND9 DNS server configuration via Pydantic models.

Instead of manually editing named.conf , you describe the configuration in Python, and the library generates correct BIND9 syntax and (optionally) places files into the required directories.

Features

  • Full support for all named.conf blocks:
    • acl, controls, dnssec-policy, http, key, key-store, logging, options, remote-servers, server, statistics-channels, tls, trust-anchors, view, zone.
  • All common resource record types:
    • A, AAAA, CAA, CERT, CNAME, DNAME, DNSKEY, DS, HINFO, LOC, MX, NAPTR, NSEC, NS, PTR, RP, RRSIG, SOA, SPF, SRV, SSHFP, TLSA, TXT.
  • Built-in validation - pass strings, numbers, IP addresses, durations – the library will format them correctly for BIND.
  • Syntax generation in one line
    • model.model_bind_syntax() - for any block or the whole named.conf,
    • zone.model_bind_syntax_zone_file() - for a ready-to-use zone file.
  • Generate files without writing / write to disk
    • config.generate_files() - returns a list of generated files
    • config.write_files("./my_config") - creates named.conf, zones, keys, DNSSEC policies and organises them into subdirectories.
  • Python - 3.10+, static typing, 96% test coverage.
  • No extra dependencies - only Pydantic

Installation

pip install bindantic

⚠️ NOTE:

The named-checkconf utility from the bind-utils package may be older than your BIND server and may not recognise new directives.

bindantic generates syntax according to the latest stable BIND 9.20.x version. If you check the configuration with an older utility you may get errors. Always use the same version of named-checkconf as your server, if possible.

Quick Start

Example of a minimal configuration

from bindantic import (
    ARecord,
    NamedConfig,
    NSRecord,
    OptionsBlock,
    SOARecord,
    ZoneBlock,
    ZoneTypeEnum,
)

config = NamedConfig(
    options_block=OptionsBlock(
        directory="/etc/bind",
        recursion=True,
        allow_recursion=["localhost", "localnets"],
        listen_on=["any"],
        listen_on_v6=["any"],
    ),
    zone_blocks=[
        ZoneBlock(
            comment="optional comment",
            name="example.com",
            zone_type=ZoneTypeEnum.PRIMARY,
            file="zones/example.com.zone",
            resource_records=[
                SOARecord(
                    mname="ns1.example.com",
                    rname="admin.example.com",
                    serial=2026010101,
                    refresh=10800,
                    retry=3600,
                    expire=604800,
                    minimum=3600,
                    origin="example.com",
                    ttl=3600,
                ),
                NSRecord(nsdname="ns1.example.com", comment="optional comment"),
                ARecord(name="@", address="192.168.1.1"),
            ],
        )
    ],
)
Output of `config.model_bind_syntax()`
options {
    allow-recursion {
        localhost;
        localnets;
    };
    directory "/etc/bind";
    listen-on {
        any;
    };
    listen-on-v6 {
        any;
    };
    recursion yes;
};

# optional comment
zone example.com. {
    type primary;
    file "zones/example.com.zone";
};
Output of `config.zone_blocks[0].model_bind_syntax_zone_file()`
$TTL 3600
$ORIGIN example.com.
@                    IN   SOA ns1.example.com. admin.example.com. (
                                     2026010101 ; Serial number (YYYYMMDDNN)
                                     10800      ; Refresh time
                                     3600       ; Retry time
                                     604800     ; Expire time
                                     3600       ; Minimum TTL
                     )
@                    IN   NS         ns1.example.com. ; optional comment
@                    IN   A          192.168.1.1
Output of `config.generate_files()`
[
    GeneratedFile(
        path=PosixPath("/etc/bind/zones/example.com.zone"),
        content="<CONTENT>",
        type="zone",
    ),
    GeneratedFile(
        path=PosixPath("/etc/bind/named.conf"),
        content="<CONTENT>",
        type="config",
    ),
]
Output of `config.write_files(base_dir="./examples/example")`
example_bind/
├── named.conf
└── zones/
    └── example.com.zone
# Automatically generated by bindantic - please adjust!

options {
    allow-recursion {
        localhost;
        localnets;
    };
    directory "examples/example";
    listen-on {
        any;
    };
    listen-on-v6 {
        any;
    };
    recursion yes;
};

# optional comment
zone example.com. {
    type primary;
    file "zones/example.com.zone";
};
$TTL 3600
$ORIGIN example.com.
@                    IN   SOA ns1.example.com. admin.example.com. (
                                     2026010101 ; Serial number (YYYYMMDDNN)
                                     10800      ; Refresh time
                                     3600       ; Retry time
                                     604800     ; Expire time
                                     3600       ; Minimum TTL
                     )
@                    IN   NS         ns1.example.com. ; optional comment
@                    IN   A          192.168.1.1


The file ./examples/manual_example.py contains usage examples for all supported models.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bindantic-0.9.0.tar.gz (53.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bindantic-0.9.0-py3-none-any.whl (62.2 kB view details)

Uploaded Python 3

File details

Details for the file bindantic-0.9.0.tar.gz.

File metadata

  • Download URL: bindantic-0.9.0.tar.gz
  • Upload date:
  • Size: 53.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for bindantic-0.9.0.tar.gz
Algorithm Hash digest
SHA256 3ec2a4322a5007d9e08c2ca559fa7f1565116a4301a0cf98370fb0a07647f62e
MD5 a241c3a9c8ad2a7b82a34f0a6fa9042c
BLAKE2b-256 1a509f05d8f7b07f160cc35a043e426c1cf5943122b0923073d886f9adff026e

See more details on using hashes here.

File details

Details for the file bindantic-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: bindantic-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 62.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for bindantic-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 50cad0a7a443d354113d497dd726e5e66d9b46ad41444363b642e15b0f4dc49c
MD5 cc2c2d4345770139dc29570c4ea06d86
BLAKE2b-256 dbded53390f803a3377adbbaedf6c07f5f63003eede9949749b9c748bcad7d39

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page