6 Commits

Author SHA1 Message Date
Daniel Akulenok
a73968c585 docs: Update author and company contact information 2026-01-27 23:18:56 +01:00
Daniel Akulenok
79f57b3d65 test: Configure Molecule testing framework
- Add Ansible collections configuration
- Update converge and prepare playbooks
- Restructure molecule.yml for improved testing
2026-01-27 23:18:56 +01:00
Daniel Akulenok
2abcf4bbb3 fix: Add explicit boolean comparison for Ansible 2.12+ compatibility 2026-01-27 23:18:56 +01:00
Daniel Akulenok
385ee32c22 refactor: Rename leaf config to site config
feat: Add argument specs and atomic validation
2026-01-27 23:18:56 +01:00
Daniel Akulenok
6820362610 refactor: Implement dynamic ordering in BIND templates
- Simplify options and zone templates
- Add deprecation warnings for legacy configurations
- Reduce template complexity and improve maintainability
2026-01-27 23:18:56 +01:00
Daniel Akulenok
6ab14c4021 feat: Add remote-servers configuration for BIND 9.20
- Create new remote-servers template
- Integrate into configuration generator
2026-01-27 23:18:56 +01:00
62 changed files with 291 additions and 8750 deletions

View File

@@ -1,43 +0,0 @@
# BIND9 9.18 LTS Support Branch
Branch: 9.18
Purpose: Long-term support for BIND9 9.18.x (ISC LTS release)
Status: Active
Support Level: Full
## Version Information
- **BIND9 Version**: 9.18.x (LTS)
- **Supported Until**: Aligned with ISC BIND9 9.18 LTS support timeline
- **Branch Base**: BIND9 9.18.44 (as of February 2026)
## Supported Platforms
- Debian 11 (Bullseye)
- Debian 12 (Bookworm)
- Debian 13 (Trixie)
- Ubuntu 20.04 LTS
- Ubuntu 22.04 LTS
- Ubuntu 24.04 LTS
## Policies
### Backporting
- ✅ Security fixes: Always backported
- ✅ Bug fixes: Backported if compatible
- ❌ New features: Case-by-case (no breaking changes)
- ❌ Breaking changes: Never
### Release Numbering
Uses MAJOR.MINOR.PATCH (e.g., v1.2.3)
## Key Documentation
- [Version Support Policy](docs/VERSION_SUPPORT.md)
- [Configuration Grammar](CONFIGURATION_GRAMMAR.md)
- [Changelog](CHANGELOG.md)
- [README](README.md)
## Next Major Version
For BIND9 9.20+ support, see the `main` branch which will eventually have version-specific releases.

View File

@@ -1,63 +0,0 @@
---
name: Test
on: # noqa: yaml[truthy]
push:
branches:
- main
- feature/**
pull_request:
branches:
- main
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install tools
run: |
pip install --no-cache-dir yamllint ansible-lint
- name: Run yamllint
run: yamllint -d relaxed .
- name: Run ansible-lint
run: ansible-lint --strict --profile=production
test:
name: Test
runs-on: ubuntu-latest
needs: lint
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install podman
run: |
sudo apt-get update
sudo apt-get install -y podman
- name: Install dependencies
run: |
pip install --no-cache-dir \
ansible \
molecule[podman] \
podman-compose \
pyyaml \
jinja2
- name: Run Molecule tests
run: molecule test

View File

@@ -1,6 +0,0 @@
<!--# cspell: ignore SSOT CMDB -->
# AGENTS.md
Ensure that all practices and instructions described by
https://raw.githubusercontent.com/ansible/ansible-creator/refs/heads/main/docs/agents.md
are followed.

View File

@@ -1,114 +0,0 @@
# Changelog
All notable changes to the ansible-bind9-role will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Version support policy documentation in `docs/VERSION_SUPPORT.md`
- Branching strategy for supporting multiple BIND9 versions
- Grammar comparison tooling (`scripts/compare_bind_versions.py`)
- Grammar fetcher for upstream BIND9 sources (`scripts/fetch_bind_grammar.py`)
- Automated version difference tracking
- Operating system support matrix
### Changed
- Established formal release management process
- Defined backporting policy for security, bugs, and features
### Planned
- BIND9 9.20+ support in separate `9.20` branch
- Multi-platform molecule test matrix
- Automated BIND9 version detection in tasks
- Version-specific template conditional logic
- Enhanced CI/CD pipeline with version matrix testing
## [1.0.0] - TBD
### Initial Release
- Full support for BIND9 9.18.x (LTS)
- Configuration grammar based on BIND9 9.18.44
- Comprehensive template system for all BIND9 statement types:
- `acl`
- `controls`
- `dlz`
- `dnssec-policy`
- `dyndb`
- `http`
- `key`
- `logging`
- `options`
- `parental-agents`
- `primaries` (masters)
- `server`
- `statistics-channels`
- `tls`
- `trust-anchors`
- `view`
- `zone` (all types: primary, secondary, forward, hint, stub, static-stub, mirror, redirect, in-view, delegation-only)
- Support for Debian 11, 12, 13
- Support for Ubuntu 20.04, 22.04, 24.04
- Molecule testing framework
- Configuration validation with `named-checkconf`
- Automatic configuration backup and rollback on errors
- Detailed configuration grammar documentation
- GPL-3.0-or-later license
---
## Version History (Pre-Changelog)
Prior to this changelog, the role was developed without formal version tracking.
This changelog starts with the establishment of the version support policy.
---
## Versioning Schema
- **MAJOR**: Incompatible changes to role variables or behavior
- **MINOR**: New features in a backwards compatible manner
- **PATCH**: Backwards compatible bug fixes
### Branch-Specific Versioning
- `main` branch: `vX.Y.Z` (BIND9 9.18 LTS)
- `9.20` branch: `v9.20.X[-suffix]` (BIND9 9.20+)
- Suffixes: `-alpha`, `-beta`, `-rc` for pre-releases
## Release Types
### Security Releases
Critical security fixes are released as patch versions and backported to all supported branches.
### Feature Releases
New features are added in minor version increments. Breaking changes require major version increments.
### Bug Fix Releases
Bug fixes are released as patch versions when they accumulate or for critical issues.
## Upgrade Notes
### From Pre-Versioned to v1.0.0
The first official release establishes baseline compatibility. Users of pre-release versions should:
1. Review all role variables for any changes
2. Test in non-production environment
3. Review generated configuration with `named-checkconf`
4. Check `docs/VERSION_SUPPORT.md` for supported platforms
### Future Upgrades
Check individual version sections above for specific upgrade notes and breaking changes.
## Contributing
See `docs/VERSION_SUPPORT.md` for contribution guidelines and release processes.
## Links
- [Version Support Policy](docs/VERSION_SUPPORT.md)
- [Configuration Grammar](CONFIGURATION_GRAMMAR.md)
- [Issue Tracker](https://git.valid.dk/daniel/ansible-bind9-role/issues)
- [Repository](https://git.valid.dk/daniel/ansible-bind9-role)

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,7 @@
bind9 bind9
===== =====
A feature-complete ansible role for installing and configuring bind9. The purpose of this role is to fully template out the entire official bind9 configuration file format. A feature-complete ansible role for installing and configuring bind9. The purpose of this role is to fully template out the entire official bind9 configuration file format.
## Version Compatibility
| BIND9 Version | Role Branch | Status | Supported Platforms |
|---------------|-------------|--------|---------------------|
| 9.18.x (LTS) | `main` | ✅ Supported | Debian 11-13, Ubuntu 20.04-24.04 |
| 9.20.x+ | `9.20` | 🚧 Planned | Debian 12-13, Ubuntu 22.04-24.04 |
For detailed version support policy, branching strategy, and migration guidance, see [docs/VERSION_SUPPORT.md](docs/VERSION_SUPPORT.md).
**Minimum Requirements:**
- Ansible: 2.13+
- Python: 3.8+
What the role does: What the role does:
- Fully configures named.conf - Fully configures named.conf
@@ -139,43 +126,38 @@ Simple options are defined just as that.
``` ```
Some options have several optional parameters. For those, a somewhat flexible Some options have several optional parameters. For those, a somewhat flexible
configuration format has been created. Common patterns include: configuration format has been created
- **Address with Port/DSCP**: Used by options like `primaries`, `parental_agents` (e.g., `address [ port <port> ] [ dscp <dscp> ]`)
- **Address with Port/TLS**: Used by options like `forwarders` (e.g., `address [ port <port> ] [ tls <tls> ]`)
``` ```
ADDRESS_PORT_TLS_OPTION: # Example: forwarders option IP_PORT_DSCP_OPTION: # Any option that is defined as one of:
# <option> [ port <port> ] [ tls <tls> ] { <address> [ port <port> ] [ tls <tls> ]; ... } # <option> [ port <port> ] [ dscp <dscp> ] { <address> [ port <port> ] [ dscp <dscp> ]; ... }
# <option> [ port <port> ] [ dscp <dscp> ] { <address> [ port <port> ] [ key <key> ] [ tls <tls> ]; ... }
# has a few optional syntaxes # has a few optional syntaxes
# Example 1: Simple address list # Example 1: Simple address list
- ADDRESS1 - ADDRESS1
- ADDRESS2 - ADDRESS2
# Example 2: To define global port/tls, use 'addresses' sub-element # Example 2: To define source port/dscp, use 'addresses' sub-element
[ port: PORT ] [ port: PORT ]
[ tls: TLS_NAME ] [ dscp: DSCP ]
addresses: addresses:
- ADDRESS1 - ADDRESS1
- ADDRESS2 - ADDRESS2
- 127.0.0.1 - 127.0.0.1
# Example 3: To define per-address port/tls, use 'addresses' as a list of dicts # Example 3: To define target port/dscp, use 'addresses' as a list of dicts
addresses: addresses:
- address: ADDRESS - address: ADDRESS
[ port: PORT ] [ port: PORT ]
[ tls: TLS_NAME ] [ dscp: DSCP ]
- address: 127.0.0.1 - address: 127.0.0.1
port: 53 port: 53
- address: 127.0.0.1 - address: 127.0.0.1
port: 853 dscp: 42
tls: dot-tls - address: 127.0.0.1
- address: 8.8.8.8 port: 5353
port: 853 dscp: 42
tls: google-tls
# Example 4: The various formats can be mixed and matched within the main element # Example 4: The various formats can be mixed and matched within the main element
- ADDRESS1 - ADDRESS1
- address: ADDRESS2 - address: ADDRESS2
port: PORT port: PORT
tls: TLS_NAME
``` ```
@@ -208,30 +190,10 @@ Simple sample config of a recursive BIND server that allows your localnetwork to
allow-recursion: allow-recursion:
- mylan - mylan
## Documentation
- **[Configuration Grammar Reference](CONFIGURATION_GRAMMAR.md)**: Comprehensive guide to all BIND9 configuration options
- **[Version Support Policy](docs/VERSION_SUPPORT.md)**: Supported versions, branching strategy, and release management
- **[Changelog](CHANGELOG.md)**: Version history and upgrade notes
## Contributing
Contributions are welcome! Please see [docs/VERSION_SUPPORT.md](docs/VERSION_SUPPORT.md) for:
- Branching strategy
- Testing requirements
- Backporting policies
- Release procedures
## Links
- **Repository**: https://git.valid.dk/daniel/ansible-bind9-role
- **Issues**: https://git.valid.dk/daniel/ansible-bind9-role/issues
- **BIND9 Documentation**: https://bind9.readthedocs.io/
License License
------- -------
GPL-3.0-or-later BSD
Author Information Author Information
------------------ ------------------

View File

@@ -1,19 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "forward"
},
"forward": {
"_grammar": "( first | only )"
},
"forwarders": {
"_grammar": "[ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... }"
},
"template": {
"_grammar": "<string>"
}
}
}
}

View File

@@ -1,19 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "hint"
},
"check-names": {
"_grammar": "( fail | warn | ignore )"
},
"file": {
"_grammar": "<quoted_string>"
},
"template": {
"_grammar": "<string>"
}
}
}
}

View File

@@ -1,10 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"in-view": {
"_grammar": "<string>"
}
}
}
}

View File

@@ -1,171 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "mirror"
},
"allow-notify": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query-on": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-transfer": {
"_grammar": "[ port <integer> ] [ transport <string> ] { <address_match_element>; ... }"
},
"allow-update-forwarding": {
"_grammar": "{ <address_match_element>; ... }"
},
"also-notify": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"check-names": {
"_grammar": "( fail | warn | ignore )"
},
"database": {
"_grammar": "<string>"
},
"file": {
"_grammar": "<quoted_string>"
},
"ixfr-from-differences": {
"_grammar": "<boolean>"
},
"journal": {
"_grammar": "<quoted_string>"
},
"masterfile-format": {
"_grammar": "( raw | text )"
},
"masterfile-style": {
"_grammar": "( full | relative )"
},
"max-ixfr-ratio": {
"_grammar": "( unlimited | <percentage> )"
},
"max-journal-size": {
"_grammar": "( default | unlimited | <sizeval> )"
},
"max-records": {
"_grammar": "<integer>"
},
"max-records-per-type": {
"_grammar": "<integer>"
},
"max-refresh-time": {
"_grammar": "<integer>"
},
"max-retry-time": {
"_grammar": "<integer>"
},
"max-transfer-idle-in": {
"_grammar": "<integer>"
},
"max-transfer-idle-out": {
"_grammar": "<integer>"
},
"max-transfer-time-in": {
"_grammar": "<integer>"
},
"max-transfer-time-out": {
"_grammar": "<integer>"
},
"max-types-per-name": {
"_grammar": "<integer>"
},
"min-refresh-time": {
"_grammar": "<integer>"
},
"min-retry-time": {
"_grammar": "<integer>"
},
"min-transfer-rate-in": {
"_grammar": "<integer> <integer>"
},
"multi-master": {
"_grammar": "<boolean>"
},
"notify": {
"_grammar": "( explicit | master-only | primary-only | <boolean> )"
},
"notify-cfg": {
"_flags": [
"may occur multiple times"
],
"_id": "<string>",
"_mapbody": {
"notify": {
"_grammar": "<boolean>"
},
"notify-defer": {
"_grammar": "<integer>"
},
"notify-delay": {
"_grammar": "<integer>"
},
"notify-source": {
"_grammar": "( <ipv4_address> | * )"
},
"notify-source-v6": {
"_grammar": "( <ipv6_address> | * )"
}
}
},
"notify-defer": {
"_grammar": "<integer>"
},
"notify-delay": {
"_grammar": "<integer>"
},
"notify-source": {
"_grammar": "( <ipv4_address> | * )"
},
"notify-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"plugin": {
"_flags": [
"may occur multiple times"
],
"_grammar": "( query ) <string> [ { <unspecified-text> } ]"
},
"primaries": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"provide-zoneversion": {
"_grammar": "<boolean>"
},
"request-expire": {
"_grammar": "<boolean>"
},
"request-ixfr": {
"_grammar": "<boolean>"
},
"request-ixfr-max-diffs": {
"_grammar": "<integer>"
},
"template": {
"_grammar": "<string>"
},
"transfer-source": {
"_grammar": "( <ipv4_address> | * )"
},
"transfer-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"try-tcp-refresh": {
"_grammar": "<boolean>"
},
"zero-no-soa-ttl": {
"_grammar": "<boolean>"
},
"zone-statistics": {
"_grammar": "( full | terse | none | <boolean> )"
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,258 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "primary"
},
"allow-query": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query-on": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-transfer": {
"_grammar": "[ port <integer> ] [ transport <string> ] { <address_match_element>; ... }"
},
"allow-update": {
"_grammar": "{ <address_match_element>; ... }"
},
"also-notify": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"check-dup-records": {
"_grammar": "( fail | warn | ignore )"
},
"check-integrity": {
"_grammar": "<boolean>"
},
"check-mx": {
"_grammar": "( fail | warn | ignore )"
},
"check-mx-cname": {
"_grammar": "( fail | warn | ignore )"
},
"check-names": {
"_grammar": "( fail | warn | ignore )"
},
"check-sibling": {
"_grammar": "<boolean>"
},
"check-spf": {
"_grammar": "( warn | ignore )"
},
"check-srv-cname": {
"_grammar": "( fail | warn | ignore )"
},
"check-svcb": {
"_grammar": "<boolean>"
},
"check-wildcard": {
"_grammar": "<boolean>"
},
"checkds": {
"_grammar": "( explicit | <boolean> )"
},
"database": {
"_grammar": "<string>"
},
"dlz": {
"_grammar": "<string>"
},
"dnskey-sig-validity": {
"_flags": [
"obsolete"
],
"_grammar": "<integer>"
},
"dnssec-dnskey-kskonly": {
"_flags": [
"obsolete"
],
"_grammar": "<boolean>"
},
"dnssec-loadkeys-interval": {
"_grammar": "<integer>"
},
"dnssec-policy": {
"_grammar": "<string>"
},
"dnssec-secure-to-insecure": {
"_flags": [
"obsolete"
],
"_grammar": "<boolean>"
},
"dnssec-update-mode": {
"_flags": [
"obsolete"
],
"_grammar": "( maintain | no-resign )"
},
"file": {
"_grammar": "<quoted_string>"
},
"forward": {
"_grammar": "( first | only )"
},
"forwarders": {
"_grammar": "[ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... }"
},
"initial-file": {
"_grammar": "<quoted_string>"
},
"inline-signing": {
"_grammar": "<boolean>"
},
"ixfr-from-differences": {
"_grammar": "<boolean>"
},
"journal": {
"_grammar": "<quoted_string>"
},
"key-directory": {
"_grammar": "<quoted_string>"
},
"log-report-channel": {
"_grammar": "<boolean>"
},
"masterfile-format": {
"_grammar": "( raw | text )"
},
"masterfile-style": {
"_grammar": "( full | relative )"
},
"max-ixfr-ratio": {
"_grammar": "( unlimited | <percentage> )"
},
"max-journal-size": {
"_grammar": "( default | unlimited | <sizeval> )"
},
"max-records": {
"_grammar": "<integer>"
},
"max-records-per-type": {
"_grammar": "<integer>"
},
"max-transfer-idle-out": {
"_grammar": "<integer>"
},
"max-transfer-time-out": {
"_grammar": "<integer>"
},
"max-types-per-name": {
"_grammar": "<integer>"
},
"max-zone-ttl": {
"_flags": [
"deprecated"
],
"_grammar": "( unlimited | <duration> )"
},
"notify": {
"_grammar": "( explicit | master-only | primary-only | <boolean> )"
},
"notify-cfg": {
"_flags": [
"may occur multiple times"
],
"_id": "<string>",
"_mapbody": {
"notify": {
"_grammar": "<boolean>"
},
"notify-defer": {
"_grammar": "<integer>"
},
"notify-delay": {
"_grammar": "<integer>"
},
"notify-source": {
"_grammar": "( <ipv4_address> | * )"
},
"notify-source-v6": {
"_grammar": "( <ipv6_address> | * )"
}
}
},
"notify-defer": {
"_grammar": "<integer>"
},
"notify-delay": {
"_grammar": "<integer>"
},
"notify-source": {
"_grammar": "( <ipv4_address> | * )"
},
"notify-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"notify-to-soa": {
"_grammar": "<boolean>"
},
"nsec3-test-zone": {
"_flags": [
"test only"
],
"_grammar": "<boolean>"
},
"parental-agents": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"parental-source": {
"_grammar": "( <ipv4_address> | * )"
},
"parental-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"plugin": {
"_flags": [
"may occur multiple times"
],
"_grammar": "( query ) <string> [ { <unspecified-text> } ]"
},
"provide-zoneversion": {
"_grammar": "<boolean>"
},
"send-report-channel": {
"_grammar": "<string>"
},
"serial-update-method": {
"_grammar": "( date | increment | unixtime )"
},
"sig-signing-nodes": {
"_grammar": "<integer>"
},
"sig-signing-signatures": {
"_grammar": "<integer>"
},
"sig-signing-type": {
"_grammar": "<integer>"
},
"sig-validity-interval": {
"_flags": [
"obsolete"
],
"_grammar": "<integer> [ <integer> ]"
},
"template": {
"_grammar": "<string>"
},
"update-check-ksk": {
"_flags": [
"obsolete"
],
"_grammar": "<boolean>"
},
"update-policy": {
"_grammar": "( local | { ( deny | grant ) <string> ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | krb5-subdomain-self-rhs | ms-self | ms-selfsub | ms-subdomain | ms-subdomain-self-rhs | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... } )"
},
"zero-no-soa-ttl": {
"_grammar": "<boolean>"
},
"zone-statistics": {
"_grammar": "( full | terse | none | <boolean> )"
}
}
}
}

View File

@@ -1,58 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "redirect"
},
"allow-query": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query-on": {
"_grammar": "{ <address_match_element>; ... }"
},
"dlz": {
"_grammar": "<string>"
},
"file": {
"_grammar": "<quoted_string>"
},
"masterfile-format": {
"_grammar": "( raw | text )"
},
"masterfile-style": {
"_grammar": "( full | relative )"
},
"max-records": {
"_grammar": "<integer>"
},
"max-records-per-type": {
"_grammar": "<integer>"
},
"max-types-per-name": {
"_grammar": "<integer>"
},
"max-zone-ttl": {
"_flags": [
"deprecated"
],
"_grammar": "( unlimited | <duration> )"
},
"plugin": {
"_flags": [
"may occur multiple times"
],
"_grammar": "( query ) <string> [ { <unspecified-text> } ]"
},
"primaries": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"template": {
"_grammar": "<string>"
},
"zone-statistics": {
"_grammar": "( full | terse | none | <boolean> )"
}
}
}
}

View File

@@ -1,258 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "secondary"
},
"allow-notify": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query-on": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-transfer": {
"_grammar": "[ port <integer> ] [ transport <string> ] { <address_match_element>; ... }"
},
"allow-update-forwarding": {
"_grammar": "{ <address_match_element>; ... }"
},
"also-notify": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"check-names": {
"_grammar": "( fail | warn | ignore )"
},
"checkds": {
"_grammar": "( explicit | <boolean> )"
},
"database": {
"_grammar": "<string>"
},
"dlz": {
"_grammar": "<string>"
},
"dnskey-sig-validity": {
"_flags": [
"obsolete"
],
"_grammar": "<integer>"
},
"dnssec-dnskey-kskonly": {
"_flags": [
"obsolete"
],
"_grammar": "<boolean>"
},
"dnssec-loadkeys-interval": {
"_grammar": "<integer>"
},
"dnssec-policy": {
"_grammar": "<string>"
},
"dnssec-update-mode": {
"_flags": [
"obsolete"
],
"_grammar": "( maintain | no-resign )"
},
"file": {
"_grammar": "<quoted_string>"
},
"forward": {
"_grammar": "( first | only )"
},
"forwarders": {
"_grammar": "[ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... }"
},
"inline-signing": {
"_grammar": "<boolean>"
},
"ixfr-from-differences": {
"_grammar": "<boolean>"
},
"journal": {
"_grammar": "<quoted_string>"
},
"key-directory": {
"_grammar": "<quoted_string>"
},
"log-report-channel": {
"_grammar": "<boolean>"
},
"masterfile-format": {
"_grammar": "( raw | text )"
},
"masterfile-style": {
"_grammar": "( full | relative )"
},
"max-ixfr-ratio": {
"_grammar": "( unlimited | <percentage> )"
},
"max-journal-size": {
"_grammar": "( default | unlimited | <sizeval> )"
},
"max-records": {
"_grammar": "<integer>"
},
"max-records-per-type": {
"_grammar": "<integer>"
},
"max-refresh-time": {
"_grammar": "<integer>"
},
"max-retry-time": {
"_grammar": "<integer>"
},
"max-transfer-idle-in": {
"_grammar": "<integer>"
},
"max-transfer-idle-out": {
"_grammar": "<integer>"
},
"max-transfer-time-in": {
"_grammar": "<integer>"
},
"max-transfer-time-out": {
"_grammar": "<integer>"
},
"max-types-per-name": {
"_grammar": "<integer>"
},
"min-refresh-time": {
"_grammar": "<integer>"
},
"min-retry-time": {
"_grammar": "<integer>"
},
"min-transfer-rate-in": {
"_grammar": "<integer> <integer>"
},
"multi-master": {
"_grammar": "<boolean>"
},
"notify": {
"_grammar": "( explicit | master-only | primary-only | <boolean> )"
},
"notify-cfg": {
"_flags": [
"may occur multiple times"
],
"_id": "<string>",
"_mapbody": {
"notify": {
"_grammar": "<boolean>"
},
"notify-defer": {
"_grammar": "<integer>"
},
"notify-delay": {
"_grammar": "<integer>"
},
"notify-source": {
"_grammar": "( <ipv4_address> | * )"
},
"notify-source-v6": {
"_grammar": "( <ipv6_address> | * )"
}
}
},
"notify-defer": {
"_grammar": "<integer>"
},
"notify-delay": {
"_grammar": "<integer>"
},
"notify-source": {
"_grammar": "( <ipv4_address> | * )"
},
"notify-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"notify-to-soa": {
"_grammar": "<boolean>"
},
"nsec3-test-zone": {
"_flags": [
"test only"
],
"_grammar": "<boolean>"
},
"parental-agents": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"parental-source": {
"_grammar": "( <ipv4_address> | * )"
},
"parental-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"plugin": {
"_flags": [
"may occur multiple times"
],
"_grammar": "( query ) <string> [ { <unspecified-text> } ]"
},
"primaries": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"provide-zoneversion": {
"_grammar": "<boolean>"
},
"request-expire": {
"_grammar": "<boolean>"
},
"request-ixfr": {
"_grammar": "<boolean>"
},
"request-ixfr-max-diffs": {
"_grammar": "<integer>"
},
"send-report-channel": {
"_grammar": "<string>"
},
"sig-signing-nodes": {
"_grammar": "<integer>"
},
"sig-signing-signatures": {
"_grammar": "<integer>"
},
"sig-signing-type": {
"_grammar": "<integer>"
},
"sig-validity-interval": {
"_flags": [
"obsolete"
],
"_grammar": "<integer> [ <integer> ]"
},
"template": {
"_grammar": "<string>"
},
"transfer-source": {
"_grammar": "( <ipv4_address> | * )"
},
"transfer-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"try-tcp-refresh": {
"_grammar": "<boolean>"
},
"update-check-ksk": {
"_flags": [
"obsolete"
],
"_grammar": "<boolean>"
},
"zero-no-soa-ttl": {
"_grammar": "<boolean>"
},
"zone-statistics": {
"_grammar": "( full | terse | none | <boolean> )"
}
}
}
}

View File

@@ -1,43 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "static-stub"
},
"allow-query": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query-on": {
"_grammar": "{ <address_match_element>; ... }"
},
"forward": {
"_grammar": "( first | only )"
},
"forwarders": {
"_grammar": "[ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... }"
},
"max-records": {
"_grammar": "<integer>"
},
"max-records-per-type": {
"_grammar": "<integer>"
},
"max-types-per-name": {
"_grammar": "<integer>"
},
"server-addresses": {
"_grammar": "{ ( <ipv4_address> | <ipv6_address> ); ... }"
},
"server-names": {
"_grammar": "{ <string>; ... }"
},
"template": {
"_grammar": "<string>"
},
"zone-statistics": {
"_grammar": "( full | terse | none | <boolean> )"
}
}
}
}

View File

@@ -1,85 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "stub"
},
"allow-query": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query-on": {
"_grammar": "{ <address_match_element>; ... }"
},
"check-names": {
"_grammar": "( fail | warn | ignore )"
},
"database": {
"_grammar": "<string>"
},
"file": {
"_grammar": "<quoted_string>"
},
"forward": {
"_grammar": "( first | only )"
},
"forwarders": {
"_grammar": "[ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... }"
},
"masterfile-format": {
"_grammar": "( raw | text )"
},
"masterfile-style": {
"_grammar": "( full | relative )"
},
"max-records": {
"_grammar": "<integer>"
},
"max-records-per-type": {
"_grammar": "<integer>"
},
"max-refresh-time": {
"_grammar": "<integer>"
},
"max-retry-time": {
"_grammar": "<integer>"
},
"max-transfer-idle-in": {
"_grammar": "<integer>"
},
"max-transfer-time-in": {
"_grammar": "<integer>"
},
"max-types-per-name": {
"_grammar": "<integer>"
},
"min-refresh-time": {
"_grammar": "<integer>"
},
"min-retry-time": {
"_grammar": "<integer>"
},
"min-transfer-rate-in": {
"_grammar": "<integer> <integer>"
},
"multi-master": {
"_grammar": "<boolean>"
},
"primaries": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"template": {
"_grammar": "<string>"
},
"transfer-source": {
"_grammar": "( <ipv4_address> | * )"
},
"transfer-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"zone-statistics": {
"_grammar": "( full | terse | none | <boolean> )"
}
}
}
}

View File

@@ -1,54 +0,0 @@
# BIND9 Grammar Files - Upstream Source
This directory contains upstream BIND9 grammar files from the official BIND9 mirror for version comparison and validation.
## Files to Fetch
When grammar files are needed, fetch from:
- **Repository**: https://git.valid.dk/Mirrors/bind9
- **9.18 Tag**: v9.18.44
- **9.20 Tag**: v9.20.18
### Required Grammar Files (from doc/misc/)
- options
- forward.zoneopt
- hint.zoneopt
- in-view.zoneopt
- mirror.zoneopt
- primary.zoneopt
- redirect.zoneopt
- secondary.zoneopt
- static-stub.zoneopt
- stub.zoneopt
- delegation-only.zoneopt
- rndc.grammar
- parsegrammar.py
- checkgrammar.py
## Directory Structure
```
upstream/
├── v9.18.44/
│ ├── grammar/ (Grammar files)
│ └── metadata.json (Fetch metadata)
└── v9.20.18/
├── grammar/ (Grammar files)
└── metadata.json (Fetch metadata)
```
## Fetching
Option 1: Using git fetch
```bash
git clone --depth 1 --branch v9.18.44 https://git.valid.dk/Mirrors/bind9.git /tmp/bind9-9.18
cp /tmp/bind9-9.18/doc/misc/* bind9-grammar/upstream/v9.18.44/grammar/
```
Option 2: Using Gitea MCP tools (see scripts/fetch_bind_grammar.py)
## Scripts
- `scripts/fetch_bind_grammar.py` - MCP-based fetcher template
- `scripts/compare_bind_versions.py` - Grammar comparison tool

View File

@@ -1,3 +0,0 @@
zone <string> [ <class> ] {
type delegation-only;
};

View File

@@ -1,6 +0,0 @@
zone <string> [ <class> ] {
type forward;
delegation-only <boolean>; // deprecated
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
};

View File

@@ -1,6 +0,0 @@
zone <string> [ <class> ] {
type hint;
check-names ( fail | warn | ignore );
delegation-only <boolean>; // deprecated
file <quoted_string>;
};

View File

@@ -1,3 +0,0 @@
zone <string> [ <class> ] {
in-view <string>;
};

View File

@@ -1,45 +0,0 @@
zone <string> [ <class> ] {
type mirror;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) ; // deprecated
alt-transfer-source-v6 ( <ipv6_address> | * ) ; // deprecated
check-names ( fail | warn | ignore );
database <string>;
file <quoted_string>;
ixfr-from-differences <boolean>;
journal <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
primaries [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
try-tcp-refresh <boolean>;
use-alt-transfer-source <boolean>; // deprecated
zero-no-soa-ttl <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,604 +0,0 @@
acl <string> { <address_match_element>; ... }; // may occur multiple times
controls {
inet ( <ipv4_address> | <ipv6_address> | * ) [ port ( <integer> | * ) ] allow { <address_match_element>; ... } [ keys { <string>; ... } ] [ read-only <boolean> ]; // may occur multiple times
unix <quoted_string> perm <integer> owner <integer> group <integer> [ keys { <string>; ... } ] [ read-only <boolean> ]; // may occur multiple times
}; // may occur multiple times
dlz <string> {
database <string>;
search <boolean>;
}; // may occur multiple times
dnssec-policy <string> {
dnskey-ttl <duration>;
keys { ( csk | ksk | zsk ) [ ( key-directory ) ] lifetime <duration_or_unlimited> algorithm <string> [ <integer> ]; ... };
max-zone-ttl <duration>;
nsec3param [ iterations <integer> ] [ optout <boolean> ] [ salt-length <integer> ];
parent-ds-ttl <duration>;
parent-propagation-delay <duration>;
parent-registration-delay <duration>; // obsolete
publish-safety <duration>;
purge-keys <duration>;
retire-safety <duration>;
signatures-jitter <duration>;
signatures-refresh <duration>;
signatures-validity <duration>;
signatures-validity-dnskey <duration>;
zone-propagation-delay <duration>;
}; // may occur multiple times
dyndb <string> <quoted_string> { <unspecified-text> }; // may occur multiple times
http <string> {
endpoints { <quoted_string>; ... };
listener-clients <integer>;
streams-per-connection <integer>;
}; // may occur multiple times
key <string> {
algorithm <string>;
secret <string>;
}; // may occur multiple times
logging {
category <string> { <string>; ... }; // may occur multiple times
channel <string> {
buffered <boolean>;
file <quoted_string> [ versions ( unlimited | <integer> ) ] [ size <size> ] [ suffix ( increment | timestamp ) ];
null;
print-category <boolean>;
print-severity <boolean>;
print-time ( iso8601 | iso8601-utc | local | <boolean> );
severity <log_severity>;
stderr;
syslog [ <syslog_facility> ];
}; // may occur multiple times
};
managed-keys { <string> ( static-key | initial-key | static-ds | initial-ds ) <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times, deprecated
options {
allow-new-zones <boolean>;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-cache { <address_match_element>; ... };
allow-query-cache-on { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-recursion { <address_match_element>; ... };
allow-recursion-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) ; // deprecated
alt-transfer-source-v6 ( <ipv6_address> | * ) ; // deprecated
answer-cookie <boolean>;
attach-cache <string>;
auth-nxdomain <boolean>;
auto-dnssec ( allow | maintain | off ) ; // deprecated
automatic-interface-scan <boolean>;
avoid-v4-udp-ports { <portrange>; ... }; // deprecated
avoid-v6-udp-ports { <portrange>; ... }; // deprecated
bindkeys-file <quoted_string>;
blackhole { <address_match_element>; ... };
catalog-zones { zone <string> [ default-primaries [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... } ] [ zone-directory <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
check-names ( primary | master | secondary | slave | response ) ( fail | warn | ignore ); // may occur multiple times
check-sibling <boolean>;
check-spf ( warn | ignore );
check-srv-cname ( fail | warn | ignore );
check-wildcard <boolean>;
clients-per-query <integer>;
cookie-algorithm ( aes | siphash24 );
cookie-secret <string>; // may occur multiple times
coresize ( default | unlimited | <sizeval> ); // deprecated
datasize ( default | unlimited | <sizeval> ); // deprecated
deny-answer-addresses { <address_match_element>; ... } [ except-from { <string>; ... } ];
deny-answer-aliases { <string>; ... } [ except-from { <string>; ... } ];
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
directory <quoted_string>;
disable-algorithms <string> { <string>; ... }; // may occur multiple times
disable-ds-digests <string> { <string>; ... }; // may occur multiple times
disable-empty-zone <string>; // may occur multiple times
dns64 <netprefix> {
break-dnssec <boolean>;
clients { <address_match_element>; ... };
exclude { <address_match_element>; ... };
mapped { <address_match_element>; ... };
recursive-only <boolean>;
suffix <ipv6_address>;
}; // may occur multiple times
dns64-contact <string>;
dns64-server <string>;
dnskey-sig-validity <integer>;
dnsrps-enable <boolean>; // not configured
dnsrps-options { <unspecified-text> }; // not configured
dnssec-accept-expired <boolean>;
dnssec-dnskey-kskonly <boolean>;
dnssec-loadkeys-interval <integer>;
dnssec-must-be-secure <string> <boolean>; // may occur multiple times, deprecated
dnssec-policy <string>;
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
dnstap { ( all | auth | client | forwarder | resolver | update ) [ ( query | response ) ]; ... }; // not configured
dnstap-identity ( <quoted_string> | none | hostname ); // not configured
dnstap-output ( file | unix ) <quoted_string> [ size ( unlimited | <size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix ( increment | timestamp ) ]; // not configured
dnstap-version ( <quoted_string> | none ); // not configured
dscp <integer>; // obsolete
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port <integer> ] | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ); ... };
dump-file <quoted_string>;
edns-udp-size <integer>;
empty-contact <string>;
empty-server <string>;
empty-zones-enable <boolean>;
fetch-quota-params <integer> <fixedpoint> <fixedpoint> <fixedpoint>;
fetches-per-server <integer> [ ( drop | fail ) ];
fetches-per-zone <integer> [ ( drop | fail ) ];
files ( default | unlimited | <sizeval> ); // deprecated
flush-zones-on-shutdown <boolean>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
fstrm-set-buffer-hint <integer>; // not configured
fstrm-set-flush-timeout <integer>; // not configured
fstrm-set-input-queue-size <integer>; // not configured
fstrm-set-output-notify-threshold <integer>; // not configured
fstrm-set-output-queue-model ( mpscs | spscs ); // not configured
fstrm-set-output-queue-size <integer>; // not configured
fstrm-set-reopen-interval <duration>; // not configured
geoip-directory ( <quoted_string> | none );
glue-cache <boolean>; // deprecated
heartbeat-interval <integer>; // deprecated
hostname ( <quoted_string> | none );
http-listener-clients <integer>;
http-port <integer>;
http-streams-per-connection <integer>;
https-port <integer>;
interface-interval <duration>;
ipv4only-contact <string>;
ipv4only-enable <boolean>;
ipv4only-server <string>;
ixfr-from-differences ( primary | master | secondary | slave | <boolean> );
keep-response-order { <address_match_element>; ... };
key-directory <quoted_string>;
lame-ttl <duration>;
listen-on [ port <integer> ] [ tls <string> ] [ http <string> ] { <address_match_element>; ... }; // may occur multiple times
listen-on-v6 [ port <integer> ] [ tls <string> ] [ http <string> ] { <address_match_element>; ... }; // may occur multiple times
lmdb-mapsize <sizeval>;
lock-file ( <quoted_string> | none );
managed-keys-directory <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
match-mapped-addresses <boolean>;
max-cache-size ( default | unlimited | <sizeval> | <percentage> );
max-cache-ttl <duration>;
max-clients-per-query <integer>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-query-count <integer>;
max-query-restarts <integer>;
max-records <integer>;
max-records-per-type <integer>;
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-rsa-exponent-size <integer>;
max-stale-ttl <duration>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
max-udp-size <integer>;
maxz-zone-ttl ( unlimited | <duration> );
memstatistics <boolean>;
memstatistics-file <quoted_string>;
message-compression <boolean>;
min-cache-ttl <duration>;
min-ncache-ttl <duration>;
min-refresh-time <integer>;
min-retry-time <integer>;
minimal-any <boolean>;
minimal-responses ( no-auth | no-auth-recursive | <boolean> );
multi-master <boolean>;
new-zones-directory <quoted_string>;
no-case-compress { <address_match_element>; ... };
nocookie-udp-size <integer>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-delay <integer>;
notify-rate <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
nta-lifetime <duration>;
nta-recheck <duration>;
nxdomain-redirect <string>;
parental-source ( <ipv4_address> | * ) ;
parental-source-v6 ( <ipv6_address> | * ) ;
pid-file ( <quoted_string> | none );
port <integer>;
preferred-glue <string>;
prefetch <integer> [ <integer> ];
provide-ixfr <boolean>;
qname-minimization ( strict | relaxed | disabled | off );
query-source [ address ] ( <ipv4_address> | * );
query-source-v6 [ address ] ( <ipv6_address> | * );
querylog <boolean>;
random-device ( <quoted_string> | none ); // obsolete
rate-limit {
all-per-second <integer>;
errors-per-second <integer>;
exempt-clients { <address_match_element>; ... };
ipv4-prefix-length <integer>;
ipv6-prefix-length <integer>;
log-only <boolean>;
max-table-size <integer>;
min-table-size <integer>;
nodata-per-second <integer>;
nxdomains-per-second <integer>;
qps-scale <integer>;
referrals-per-second <integer>;
responses-per-second <integer>;
slip <integer>;
window <integer>;
};
recurse-ing-file <quoted_string>;
recursion <boolean>;
recursive-clients <integer>;
request-expire <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
require-server-cookie <boolean>;
reserved-sockets <integer>; // deprecated
resolver-nonbackoff-tries <integer>; // deprecated
resolver-query-timeout <integer>;
resolver-retry-interval <integer>; // deprecated
response-padding { <address_match_element>; ... } block-size <integer>;
response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
reuse port <boolean>;
root-delegation-only [ exclude { <string>; ... } ]; // deprecated
root-key-sentinel <boolean>;
rrset-order { [ class <string> ] [ type <string> ] [ name <quoted_string> ] <string> <string>; ... };
secroots-file <quoted_string>;
send-cookie <boolean>;
serial-query-rate <integer>;
serial-update-method ( date | increment | unixtime );
server-id ( <quoted_string> | none | hostname );
servfail-ttl <duration>;
session-keyalg <string>;
session-keyfile ( <quoted_string> | none );
session-keyname <string>;
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ];
sortlist { <address_match_element>; ... };
stacksize ( default | unlimited | <sizeval> ); // deprecated
stale-answer-client-timeout ( disabled | off | <integer> );
stale-answer-enable <boolean>;
stale-answer-ttl <duration>;
stale-cache-enable <boolean>;
stale-refresh-time <duration>;
startup-notify-rate <integer>;
statistics-file <quoted_string>;
suppress-initial-notify <boolean>; // obsolete
synth-from-dnssec <boolean>;
tcp-advertised-timeout <integer>;
tcp-clients <integer>;
tcp-idle-timeout <integer>;
tcp-initial-timeout <integer>;
tcp-keepalive-timeout <integer>;
tcp-listen-queue <integer>;
tcp-receive-buffer <integer>;
tcp-send-buffer <integer>;
tkey-dhkey <quoted_string> <integer>; // deprecated
tkey-domain <quoted_string>; // deprecated
tkey-gssapi-credential <quoted_string>; // deprecated
tkey-gssapi-keytab <quoted_string>;
tls-port <integer>;
transfer-format ( many-answers | one-answer );
transfer-message-size <integer>;
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
transfers-in <integer>;
transfers-out <integer>;
transfers-per-ns <integer>;
trust-anchor-telemetry <boolean>;
try-tcp-refresh <boolean>;
udp-receive-buffer <integer>;
udp-send-buffer <integer>;
update-check-ksk <boolean>;
update-quota <integer>;
use-alt-transfer-source <boolean>; // deprecated
use-v4-udp-ports { <portrange>; ... }; // deprecated
use-v6-udp-ports { <portrange>; ... }; // deprecated
v6-bias <integer>;
validate-except { <string>; ... };
version ( <quoted_string> | none );
zero-no-soa-ttl <boolean>;
zero-no-soa-ttl-cache <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};
parental-agents <string> [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }; // may occur multiple times
plugin ( query ) <string> [ { <unspecified-text> } ]; // may occur multiple times
primaries <string> [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }; // may occur multiple times
server <netprefix> {
bogus <boolean>;
edns <boolean>;
edns-udp-size <integer>;
edns-version <integer>;
keys <server_key>;
max-udp-size <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
padding <integer>;
provide-ixfr <boolean>;
query-source [ address ] ( <ipv4_address> | * );
query-source-v6 [ address ] ( <ipv6_address> | * );
request-expire <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
send-cookie <boolean>;
tcp-keepalive <boolean>;
tcp-only <boolean>;
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
transfers <integer>;
}; // may occur multiple times
statistics-channels {
inet ( <ipv4_address> | <ipv6_address> | * ) [ port ( <integer> | * ) ] [ allow { <address_match_element>; ... } ]; // may occur multiple times
}; // may occur multiple times
tls <string> {
ca-file <quoted_string>;
cert-file <quoted_string>;
ciphers <string>;
dhparam-file <quoted_string>;
key-file <quoted_string>;
prefer-server-ciphers <boolean>;
protocols { <string>; ... };
remote-hostname <quoted_string>;
session-tickets <boolean>;
}; // may occur multiple times
trust-anchors { <string> ( static-key | initial-key | static-ds | initial-ds ) <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times
trusted-keys { <string> <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times, deprecated
view <string> [ <class> ] {
allow-new-zones <boolean>;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-cache { <address_match_element>; ... };
allow-query-cache-on { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-recursion { <address_match_element>; ... };
allow-recursion-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) ; // deprecated
alt-transfer-source-v6 ( <ipv6_address> | * ) ; // deprecated
attach-cache <string>;
auth-nxdomain <boolean>;
auto-dnssec ( allow | maintain | off ) ; // deprecated
catalog-zones { zone <string> [ default-primaries [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... } ] [ zone-directory <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
check-names ( primary | master | secondary | slave | response ) ( fail | warn | ignore ); // may occur multiple times
check-sibling <boolean>;
check-spf ( warn | ignore );
check-srv-cname ( fail | warn | ignore );
check-wildcard <boolean>;
clients-per-query <integer>;
deny-answer-addresses { <address_match_element>; ... } [ except-from { <string>; ... } ];
deny-answer-aliases { <string>; ... } [ except-from { <string>; ... } ];
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
disable-algorithms <string> { <string>; ... }; // may occur multiple times
disable-ds-digests <string> { <string>; ... }; // may occur multiple times
disable-empty-zone <string>; // may occur multiple times
dlz <string> {
database <string>;
search <boolean>;
}; // may occur multiple times
dns64 <netprefix> {
break-dnssec <boolean>;
clients { <address_match_element>; ... };
exclude { <address_match_element>; ... };
mapped { <address_match_element>; ... };
recursive-only <boolean>;
suffix <ipv6_address>;
}; // may occur multiple times
dns64-contact <string>;
dns64-server <string>;
dnskey-sig-validity <integer>;
dnsrps-enable <boolean>; // not configured
dnsrps-options { <unspecified-text> }; // not configured
dnssec-accept-expired <boolean>;
dnssec-dnskey-kskonly <boolean>;
dnssec-loadkeys-interval <integer>;
dnssec-must-be-secure <string> <boolean>; // may occur multiple times, deprecated
dnssec-policy <string>;
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
dnstap { ( all | auth | client | forwarder | resolver | update ) [ ( query | response ) ]; ... }; // not configured
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port <integer> ] | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ); ... };
dyndb <string> <quoted_string> { <unspecified-text> }; // may occur multiple times
edns-udp-size <integer>;
empty-contact <string>;
empty-server <string>;
empty-zones-enable <boolean>;
fetch-quota-params <integer> <fixedpoint> <fixedpoint> <fixedpoint>;
fetches-per-server <integer> [ ( drop | fail ) ];
fetches-per-zone <integer> [ ( drop | fail ) ];
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
glue-cache <boolean>; // deprecated
ipv4only-contact <string>;
ipv4only-enable <boolean>;
ipv4only-server <string>;
ixfr-from-differences ( primary | master | secondary | slave | <boolean> );
key <string> {
algorithm <string>;
secret <string>;
}; // may occur multiple times
key-directory <quoted_string>;
lame-ttl <duration>;
lmdb-mapsize <sizeval>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
match-clients { <address_match_element>; ... };
match-destinations { <address_match_element>; ... };
match-recursive-only <boolean>;
max-cache-size ( default | unlimited | <sizeval> | <percentage> );
max-cache-ttl <duration>;
max-clients-per-query <integer>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-query-count <integer>;
max-query-restarts <integer>;
max-records <integer>;
max-records-per-type <integer>;
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-stale-ttl <duration>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
max-udp-size <integer>;
maxz-zone-ttl ( unlimited | <duration> );
message-compression <boolean>;
min-cache-ttl <duration>;
min-ncache-ttl <duration>;
min-refresh-time <integer>;
min-retry-time <integer>;
minimal-any <boolean>;
minimal-responses ( no-auth | no-auth-recursive | <boolean> );
multi-master <boolean>;
new-zones-directory <quoted_string>;
no-case-compress { <address_match_element>; ... };
nocookie-udp-size <integer>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
nta-lifetime <duration>;
nta-recheck <duration>;
nxdomain-redirect <string>;
parental-source ( <ipv4_address> | * ) ;
parental-source-v6 ( <ipv6_address> | * ) ;
plugin ( query ) <string> [ { <unspecified-text> } ]; // may occur multiple times
preferred-glue <string>;
prefetch <integer> [ <integer> ];
provide-ixfr <boolean>;
qname-minimization ( strict | relaxed | disabled | off );
query-source [ address ] ( <ipv4_address> | * );
query-source-v6 [ address ] ( <ipv6_address> | * );
rate-limit {
all-per-second <integer>;
errors-per-second <integer>;
exempt-clients { <address_match_element>; ... };
ipv4-prefix-length <integer>;
ipv6-prefix-length <integer>;
log-only <boolean>;
max-table-size <integer>;
min-table-size <integer>;
nodata-per-second <integer>;
nxdomains-per-second <integer>;
qps-scale <integer>;
referrals-per-second <integer>;
responses-per-second <integer>;
slip <integer>;
window <integer>;
};
recursion <boolean>;
request-expire <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
require-server-cookie <boolean>;
resolver-nonbackoff-tries <integer>; // deprecated
resolver-query-timeout <integer>;
resolver-retry-interval <integer>; // deprecated
response-padding { <address_match_element>; ... } block-size <integer>;
response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
root-delegation-only [ exclude { <string>; ... } ]; // deprecated
root-key-sentinel <boolean>;
rrset-order { [ class <string> ] [ type <string> ] [ name <quoted_string> ] <string> <string>; ... };
send-cookie <boolean>;
serial-update-method ( date | increment | unixtime );
server <netprefix> {
bogus <boolean>;
edns <boolean>;
edns-udp-size <integer>;
edns-version <integer>;
keys <server_key>;
max-udp-size <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
padding <integer>;
provide-ixfr <boolean>;
query-source [ address ] ( <ipv4_address> | * );
query-source-v6 [ address ] ( <ipv6_address> | * );
request-expire <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
send-cookie <boolean>;
tcp-keepalive <boolean>;
tcp-only <boolean>;
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
transfers <integer>;
}; // may occur multiple times
servfail-ttl <duration>;
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ];
sortlist { <address_match_element>; ... };
stale-answer-client-timeout ( disabled | off | <integer> );
stale-answer-enable <boolean>;
stale-answer-ttl <duration>;
stale-cache-enable <boolean>;
stale-refresh-time <duration>;
suppress-initial-notify <boolean>; // obsolete
synth-from-dnssec <boolean>;
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
trust-anchor-telemetry <boolean>;
trust-anchors { <string> ( static-key | initial-key | static-ds | initial-ds ) <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times
trusted-keys { <string> <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times, deprecated
try-tcp-refresh <boolean>;
update-check-ksk <boolean>;
use-alt-transfer-source <boolean>; // deprecated
v6-bias <integer>;
validate-except { <string>; ... };
zero-no-soa-ttl <boolean>;
zero-no-soa-ttl-cache <boolean>;
zone-statistics ( full | terse | none | <boolean> );
}; // may occur multiple times

View File

@@ -1,64 +0,0 @@
zone <string> [ <class> ] {
type primary;
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
also-notify [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) ; // deprecated
alt-transfer-source-v6 ( <ipv6_address> | * ) ; // deprecated
auto-dnssec ( allow | maintain | off ) ; // deprecated
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
check-names ( fail | warn | ignore );
check-sibling <boolean>;
check-spf ( warn | ignore );
check-srv-cname ( fail | warn | ignore );
check-wildcard <boolean>;
database <string>;
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
dlz <string>;
dnskey-sig-validity <integer>;
dnssec-dnskey-kskonly <boolean>;
dnssec-loadkeys-interval <integer>;
dnssec-policy <string>;
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
inline-signing <boolean>;
ixfr-from-differences <boolean>;
journal <quoted_string>;
key-directory <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
max-records-per-type <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> );
notify ( explicit | master-only | primary-only | <boolean> );
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
parental-agents [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
parental-source ( <ipv4_address> | * ) ;
parental-source-v6 ( <ipv6_address> | * ) ;
serial-update-method ( date | increment | unixtime );
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ];
update-check-ksk <boolean>;
update-policy ( local | { ( deny | grant ) <string> ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | krb5-subdomain-self-rhs | ms-self | ms-selfsub | ms-subdomain | ms-subdomain-self-rhs | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesubject ) [ <string> ] <rrtype list>; ... } );
zero-no-soa-ttl <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,15 +0,0 @@
zone <string> [ <class> ] {
type redirect;
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
dlz <string>;
file <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-records <integer>;
max-records-per-type <integer>;
max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> );
primaries [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,20 +0,0 @@
key <string> {
algorithm <string>;
secret <string>;
}; // may occur multiple times
options {
default-key <string>;
default-port <integer>;
default-server <string>;
default-source-address ( <ipv4_address> | * );
default-source-address-v6 ( <ipv6_address> | * );
};
server <string> {
addresses { ( <quoted_string> [ port <integer> ] | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ); ... };
key <string>;
port <integer>;
source-address ( <ipv4_address> | * );
source-address-v6 ( <ipv6_address> | * );
}; // may occur multiple times

View File

@@ -1,67 +0,0 @@
zone <string> [ <class> ] {
type secondary;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) ; // deprecated
alt-transfer-source-v6 ( <ipv6_address> | * ) ; // deprecated
auto-dnssec ( allow | maintain | off ) ; // deprecated
check-names ( fail | warn | ignore );
database <string>;
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
dlz <string>;
dnskey-sig-validity <integer>;
dnssec-dnskey-kskonly <boolean>;
dnssec-loadkeys-interval <integer>;
dnssec-policy <string>;
dnssec-update-mode ( maintain | no-resign );
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
inline-signing <boolean>;
ixfr-from-differences <boolean>;
journal <quoted_string>;
key-directory <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
parental-agents [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
parental-source ( <ipv4_address> | * ) ;
parental-source-v6 ( <ipv6_address> | * ) ;
primaries [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ];
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
try-tcp-refresh <boolean>;
update-check-ksk <boolean>;
use-alt-transfer-source <boolean>; // deprecated
zero-no-soa-ttl <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,13 +0,0 @@
zone <string> [ <class> ] {
type static-stub;
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
max-records <integer>;
max-records-per-type <integer>;
max-types-per-name <integer>;
server-addresses { ( <ipv4_address> | <ipv6_address> ); ... };
server-names { <string>; ... };
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,29 +0,0 @@
zone <string> [ <class> ] {
type stub;
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
check-names ( fail | warn | ignore );
database <string>;
delegation-only <boolean>; // deprecated
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-records <integer>;
max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-time-in <integer>;
max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
primaries [ port <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
use-alt-transfer-source <boolean>; // deprecated
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,5 +0,0 @@
zone <string> [ <class> ] {
type forward;
forward ( first | only );
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
};

View File

@@ -1,5 +0,0 @@
zone <string> [ <class> ] {
type hint;
check-names ( fail | warn | ignore );
file <quoted_string>;
};

View File

@@ -1,3 +0,0 @@
zone <string> [ <class> ] {
in-view <string>;
};

View File

@@ -1,44 +0,0 @@
zone <string> [ <class> ] {
type mirror;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
check-names ( fail | warn | ignore );
database <string>;
file <quoted_string>;
ixfr-from-differences <boolean>;
journal <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
try-tcp-refresh <boolean>;
zero-no-soa-ttl <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,605 +0,0 @@
acl <string> { <address_match_element>; ... }; // may occur multiple times
controls {
inet ( <ipv4_address> | <ipv6_address> | * ) [ port ( <integer> | * ) ] allow { <address_match_element>; ... } [ keys { <string>; ... } ] [ read-only <boolean> ]; // may occur multiple times
unix <quoted_string> perm <integer> owner <integer> group <integer> [ keys { <string>; ... } ] [ read-only <boolean> ]; // may occur multiple times
}; // may occur multiple times
dlz <string> {
database <string>;
search <boolean>;
}; // may occur multiple times
dnssec-policy <string> {
cdnskey <boolean>;
cds-digest-types { <string>; ... };
dnskey-ttl <duration>;
inline-signing <boolean>;
keys { ( csk | ksk | zsk ) [ key-directory | key-store <string> ] lifetime <duration_or_unlimited> algorithm <string> [ tag-range <integer> <integer> ] [ <integer> ]; ... };
manual-mode <boolean>;
max-zone-ttl <duration>;
nsec3param [ iterations <integer> ] [ optout <boolean> ] [ salt-length <integer> ];
offline-ksk <boolean>;
parent-ds-ttl <duration>;
parent-propagation-delay <duration>;
publish-safety <duration>;
purge-keys <duration>;
retire-safety <duration>;
signatures-jitter <duration>;
signatures-refresh <duration>;
signatures-validity <duration>;
signatures-validity-dnskey <duration>;
zone-propagation-delay <duration>;
}; // may occur multiple times
dyndb <string> <quoted_string> { <unspecified-text> }; // may occur multiple times
http <string> {
endpoints { <quoted_string>; ... };
listener-clients <integer>;
streams-per-connection <integer>;
}; // may occur multiple times
key <string> {
algorithm <string>;
secret <string>;
}; // may occur multiple times
key-store <string> {
directory <string>;
pkcs11-uri <quoted_string>;
}; // may occur multiple times
logging {
category <string> { <string>; ... }; // may occur multiple times
channel <string> {
buffered <boolean>;
file <quoted_string> [ versions ( unlimited | <integer> ) ] [ size <size> ] [ suffix ( increment | timestamp ) ];
null;
print-category <boolean>;
print-severity <boolean>;
print-time ( iso8601 | iso8601-utc | local | <boolean> );
severity <log_severity>;
stderr;
syslog [ <syslog_facility> ];
}; // may occur multiple times
};
managed-keys { <string> ( static-key | initial-key | static-ds | initial-ds ) <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times, deprecated
options {
allow-new-zones <boolean>;
allow-notify { <address_match_element>; ... };
allow-proxy { <address_match_element>; ... }; // experimental
allow-proxy-on { <address_match_element>; ... }; // experimental
allow-query { <address_match_element>; ... };
allow-query-cache { <address_match_element>; ... };
allow-query-cache-on { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-recursion { <address_match_element>; ... };
allow-recursion-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
answer-cookie <boolean>;
attach-cache <string>;
auth-nxdomain <boolean>;
automatic-interface-scan <boolean>;
avoid-v4-udp-ports { <portrange>; ... }; // deprecated
avoid-v6-udp-ports { <portrange>; ... }; // deprecated
bindkeys-file <quoted_string>; // test only
blackhole { <address_match_element>; ... };
catalog-zones { zone <string> [ default-primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... } ] [ zone-directory <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
check-names ( primary | master | secondary | slave | response ) ( fail | warn | ignore ); // may occur multiple times
check-sibling <boolean>;
check-spf ( warn | ignore );
check-srv-cname ( fail | warn | ignore );
check-svcb <boolean>;
check-wildcard <boolean>;
clients-per-query <integer>;
cookie-algorithm ( siphash24 );
cookie-secret <string>; // may occur multiple times
deny-answer-addresses { <address_match_element>; ... } [ except-from { <string>; ... } ];
deny-answer-aliases { <string>; ... } [ except-from { <string>; ... } ];
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
directory <quoted_string>;
disable-algorithms <string> { <string>; ... }; // may occur multiple times
disable-ds-digests <string> { <string>; ... }; // may occur multiple times
disable-empty-zone <string>; // may occur multiple times
dns64 <netprefix> {
break-dnssec <boolean>;
clients { <address_match_element>; ... };
exclude { <address_match_element>; ... };
mapped { <address_match_element>; ... };
recursive-only <boolean>;
suffix <ipv6_address>;
}; // may occur multiple times
dns64-contact <string>;
dns64-server <string>;
dnskey-sig-validity <integer>; // obsolete
dnsrps-enable <boolean>; // not configured
dnsrps-library <quoted_string>; // not configured
dnsrps-options { <unspecified-text> }; // not configured
dnssec-accept-expired <boolean>;
dnssec-dnskey-kskonly <boolean>; // obsolete
dnssec-loadkeys-interval <integer>;
dnssec-must-be-secure <string> <boolean>; // may occur multiple times, deprecated
dnssec-policy <string>;
dnssec-secure-to-insecure <boolean>; // obsolete
dnssec-update-mode ( maintain | no-resign ) ; // obsolete
dnssec-validation ( yes | no | auto );
dnstap { ( all | auth | client | forwarder | resolver | update ) [ ( query | response ) ]; ... }; // not configured
dnstap-identity ( <quoted_string> | none | hostname ); // not configured
dnstap-output ( file | unix ) <quoted_string> [ size ( unlimited | <size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix ( increment | timestamp ) ]; // not configured
dnstap-version ( <quoted_string> | none ); // not configured
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port <integer> ] | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ); ... };
dump-file <quoted_string>;
edns-udp-size <integer>;
empty-contact <string>;
empty-server <string>;
empty-zones-enable <boolean>;
fetch-quota-params <integer> <fixedpoint> <fixedpoint> <fixedpoint>;
fetches-per-server <integer> [ ( drop | fail ) ];
fetches-per-zone <integer> [ ( drop | fail ) ];
flush-zones-on-shutdown <boolean>;
forward ( first | only );
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
fstrm-set-buffer-hint <integer>; // not configured
fstrm-set-flush-timeout <integer>; // not configured
fstrm-set-input-queue-size <integer>; // not configured
fstrm-set-output-notify-threshold <integer>; // not configured
fstrm-set-output-queue-model ( mpscs | spscs ); // not configured
fstrm-set-output-queue-size <integer>; // not configured
fstrm-set-reopen-interval <duration>; // not configured
geoip-directory ( <quoted_string> | none );
hostname ( <quoted_string> | none );
http-listener-clients <integer>;
http-port <integer>;
http-streams-per-connection <integer>;
https-port <integer>;
interface-interval <duration>;
ipv4only-contact <string>;
ipv4only-enable <boolean>;
ipv4only-server <string>;
ixfr-from-differences ( primary | master | secondary | slave | <boolean> );
key-directory <quoted_string>;
lame-ttl <duration>;
listen-on [ port <integer> ] [ proxy <string> ] [ tls <string> ] [ http <string> ] { <address_match_element>; ... }; // may occur multiple times
listen-on-v6 [ port <integer> ] [ proxy <string> ] [ tls <string> ] [ http <string> ] { <address_match_element>; ... }; // may occur multiple times
lmdb-mapsize <sizeval>;
managed-keys-directory <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
match-mapped-addresses <boolean>;
max-cache-size ( default | unlimited | <sizeval> | <percentage> );
max-cache-ttl <duration>;
max-clients-per-query <integer>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-query-count <integer>;
max-query-restarts <integer>;
max-records <integer>;
max-records-per-type <integer>;
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-rsa-exponent-size <integer>;
max-stale-ttl <duration>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
max-udp-size <integer>;
max-validation-failures-per-fetch <integer>; // experimental
max-validations-per-fetch <integer>; // experimental
memstatistics <boolean>;
memstatistics-file <quoted_string>;
message-compression <boolean>;
min-cache-ttl <duration>;
min-ncache-ttl <duration>;
min-refresh-time <integer>;
min-retry-time <integer>;
min-transfer-rate-in <integer> <integer>;
minimal-any <boolean>;
minimal-responses ( no-auth | no-auth-recursive | <boolean> );
multi-master <boolean>;
new-zones-directory <quoted_string>;
no-case-compress { <address_match_element>; ... };
nocookie-udp-size <integer>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-defer <integer>;
notify-delay <integer>;
notify-rate <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
nta-lifetime <duration>;
nta-recheck <duration>;
nxdomain-redirect <string>;
parental-source ( <ipv4_address> | * ) ;
parental-source-v6 ( <ipv6_address> | * ) ;
pid-file ( <quoted_string> | none );
port <integer>;
preferred-glue <string>;
prefetch <integer> [ <integer> ];
provide-ixfr <boolean>;
qname-minimization ( strict | relaxed | disabled | off );
query-source [ address ] ( <ipv4_address> | * | none );
query-source-v6 [ address ] ( <ipv6_address> | * | none );
querylog <boolean>;
rate-limit {
all-per-second <integer>;
errors-per-second <integer>;
exempt-clients { <address_match_element>; ... };
ipv4-prefix-length <integer>;
ipv6-prefix-length <integer>;
log-only <boolean>;
max-table-size <integer>;
min-table-size <integer>;
nodata-per-second <integer>;
nxdomains-per-second <integer>;
qps-scale <integer>;
referrals-per-second <integer>;
responses-per-second <integer>;
slip <integer>;
window <integer>;
};
recursing-file <quoted_string>;
recursion <boolean>;
recursive-clients <integer>;
request-expire <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
require-server-cookie <boolean>;
resolver-query-timeout <integer>;
resolver-use-dns64 <boolean>;
response-padding { <address_match_element>; ... } block-size <integer>;
response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ servfail-until-ready <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
responselog <boolean>;
reuseport <boolean>;
root-key-sentinel <boolean>;
rrset-order { [ class <string> ] [ type <string> ] [ name <quoted_string> ] <string> <string>; ... };
secroots-file <quoted_string>;
send-cookie <boolean>;
serial-query-rate <integer>;
serial-update-method ( date | increment | unixtime );
server-id ( <quoted_string> | none | hostname );
servfail-ttl <duration>;
session-keyalg <string>;
session-keyfile ( <quoted_string> | none );
session-keyname <string>;
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ]; // obsolete
sig0-checks-quota <integer>; // experimental
sig0-checks-quota-exempt { <address_match_element>; ... }; // experimental
sig0-key-checks-limit <integer>;
sig0-message-checks-limit <integer>;
sortlist { <address_match_element>; ... }; // deprecated
stale-answer-client-timeout ( disabled | off | <integer> );
stale-answer-enable <boolean>;
stale-answer-ttl <duration>;
stale-cache-enable <boolean>;
stale-refresh-time <duration>;
startup-notify-rate <integer>;
statistics-file <quoted_string>;
synth-from-dnssec <boolean>;
tcp-advertised-timeout <integer>;
tcp-clients <integer>;
tcp-idle-timeout <integer>;
tcp-initial-timeout <integer>;
tcp-keepalive-timeout <integer>;
tcp-listen-queue <integer>;
tcp-receive-buffer <integer>;
tcp-send-buffer <integer>;
tkey-domain <quoted_string>; // obsolete
tkey-gssapi-keytab <quoted_string>;
tls-port <integer>;
transfer-format ( many-answers | one-answer );
transfer-message-size <integer>;
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
transfers-in <integer>;
transfers-out <integer>;
transfers-per-ns <integer>;
trust-anchor-telemetry <boolean>;
try-tcp-refresh <boolean>;
udp-receive-buffer <integer>;
udp-send-buffer <integer>;
update-check-ksk <boolean>; // obsolete
update-quota <integer>;
use-v4-udp-ports { <portrange>; ... }; // deprecated
use-v6-udp-ports { <portrange>; ... }; // deprecated
v6-bias <integer>;
validate-except { <string>; ... };
version ( <quoted_string> | none );
zero-no-soa-ttl <boolean>;
zero-no-soa-ttl-cache <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};
plugin ( query ) <string> [ { <unspecified-text> } ]; // may occur multiple times
remote-servers <string> [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }; // may occur multiple times
server <netprefix> {
bogus <boolean>;
edns <boolean>;
edns-udp-size <integer>;
edns-version <integer>;
keys <server_key>;
max-udp-size <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
padding <integer>;
provide-ixfr <boolean>;
query-source [ address ] ( <ipv4_address> | * );
query-source-v6 [ address ] ( <ipv6_address> | * );
request-expire <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
require-cookie <boolean>;
send-cookie <boolean>;
tcp-keepalive <boolean>;
tcp-only <boolean>;
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
transfers <integer>;
}; // may occur multiple times
statistics-channels {
inet ( <ipv4_address> | <ipv6_address> | * ) [ port ( <integer> | * ) ] [ allow { <address_match_element>; ... } ]; // may occur multiple times
}; // may occur multiple times
tls <string> {
ca-file <quoted_string>;
cert-file <quoted_string>;
cipher-suites <string>;
ciphers <string>;
dhparam-file <quoted_string>;
key-file <quoted_string>;
prefer-server-ciphers <boolean>;
protocols { <string>; ... };
remote-hostname <quoted_string>;
session-tickets <boolean>;
}; // may occur multiple times
trust-anchors { <string> ( static-key | initial-key | static-ds | initial-ds ) <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times
trusted-keys { <string> <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times, deprecated
view <string> [ <class> ] {
allow-new-zones <boolean>;
allow-notify { <address_match_element>; ... };
allow-proxy { <address_match_element>; ... }; // experimental
allow-proxy-on { <address_match_element>; ... }; // experimental
allow-query { <address_match_element>; ... };
allow-query-cache { <address_match_element>; ... };
allow-query-cache-on { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-recursion { <address_match_element>; ... };
allow-recursion-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
attach-cache <string>;
auth-nxdomain <boolean>;
catalog-zones { zone <string> [ default-primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... } ] [ zone-directory <quoted_string> ] [ in-memory <boolean> ] [ min-update-interval <duration> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
check-names ( primary | master | secondary | slave | response ) ( fail | warn | ignore ); // may occur multiple times
check-sibling <boolean>;
check-spf ( warn | ignore );
check-srv-cname ( fail | warn | ignore );
check-svcb <boolean>;
check-wildcard <boolean>;
clients-per-query <integer>;
deny-answer-addresses { <address_match_element>; ... } [ except-from { <string>; ... } ];
deny-answer-aliases { <string>; ... } [ except-from { <string>; ... } ];
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
disable-algorithms <string> { <string>; ... }; // may occur multiple times
disable-ds-digests <string> { <string>; ... }; // may occur multiple times
disable-empty-zone <string>; // may occur multiple times
dlz <string> {
database <string>;
search <boolean>;
}; // may occur multiple times
dns64 <netprefix> {
break-dnssec <boolean>;
clients { <address_match_element>; ... };
exclude { <address_match_element>; ... };
mapped { <address_match_element>; ... };
recursive-only <boolean>;
suffix <ipv6_address>;
}; // may occur multiple times
dns64-contact <string>;
dns64-server <string>;
dnskey-sig-validity <integer>; // obsolete
dnsrps-enable <boolean>; // not configured
dnsrps-options { <unspecified-text> }; // not configured
dnssec-accept-expired <boolean>;
dnssec-dnskey-kskonly <boolean>; // obsolete
dnssec-loadkeys-interval <integer>;
dnssec-must-be-secure <string> <boolean>; // may occur multiple times, deprecated
dnssec-policy <string>;
dnssec-secure-to-insecure <boolean>; // obsolete
dnssec-update-mode ( maintain | no-resign ) ; // obsolete
dnssec-validation ( yes | no | auto );
dnstap { ( all | auth | client | forwarder | resolver | update ) [ ( query | response ) ]; ... }; // not configured
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port <integer> ] | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ); ... };
dyndb <string> <quoted_string> { <unspecified-text> }; // may occur multiple times
edns-udp-size <integer>;
empty-contact <string>;
empty-server <string>;
empty-zones-enable <boolean>;
fetch-quota-params <integer> <fixedpoint> <fixedpoint> <fixedpoint>;
fetches-per-server <integer> [ ( drop | fail ) ];
fetches-per-zone <integer> [ ( drop | fail ) ];
forward ( first | only );
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
ipv4only-contact <string>;
ipv4only-enable <boolean>;
ipv4only-server <string>;
ixfr-from-differences ( primary | master | secondary | slave | <boolean> );
key <string> {
algorithm <string>;
secret <string>;
}; // may occur multiple times
key-directory <quoted_string>;
lame-ttl <duration>;
lmdb-mapsize <sizeval>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
match-clients { <address_match_element>; ... };
match-destinations { <address_match_element>; ... };
match-recursive-only <boolean>;
max-cache-size ( default | unlimited | <sizeval> | <percentage> );
max-cache-ttl <duration>;
max-clients-per-query <integer>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-query-count <integer>;
max-query-restarts <integer>;
max-records <integer>;
max-records-per-type <integer>;
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-stale-ttl <duration>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
max-udp-size <integer>;
max-validation-failures-per-fetch <integer>; // experimental
max-validations-per-fetch <integer>; // experimental
message-compression <boolean>;
min-cache-ttl <duration>;
min-ncache-ttl <duration>;
min-refresh-time <integer>;
min-retry-time <integer>;
min-transfer-rate-in <integer> <integer>;
minimal-any <boolean>;
minimal-responses ( no-auth | no-auth-recursive | <boolean> );
multi-master <boolean>;
new-zones-directory <quoted_string>;
no-case-compress { <address_match_element>; ... };
nocookie-udp-size <integer>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
nta-lifetime <duration>;
nta-recheck <duration>;
nxdomain-redirect <string>;
parental-source ( <ipv4_address> | * ) ;
parental-source-v6 ( <ipv6_address> | * ) ;
plugin ( query ) <string> [ { <unspecified-text> } ]; // may occur multiple times
preferred-glue <string>;
prefetch <integer> [ <integer> ];
provide-ixfr <boolean>;
qname-minimization ( strict | relaxed | disabled | off );
query-source [ address ] ( <ipv4_address> | * | none );
query-source-v6 [ address ] ( <ipv6_address> | * | none );
rate-limit {
all-per-second <integer>;
errors-per-second <integer>;
exempt-clients { <address_match_element>; ... };
ipv4-prefix-length <integer>;
ipv6-prefix-length <integer>;
log-only <boolean>;
max-table-size <integer>;
min-table-size <integer>;
nodata-per-second <integer>;
nxdomains-per-second <integer>;
qps-scale <integer>;
referrals-per-second <integer>;
responses-per-second <integer>;
slip <integer>;
window <integer>;
};
recursion <boolean>;
request-expire <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
require-server-cookie <boolean>;
resolver-query-timeout <integer>;
resolver-use-dns64 <boolean>;
response-padding { <address_match_element>; ... } block-size <integer>;
response-policy { zone <string> [ add-soa <boolean> ] [ log <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only <quoted_string> ) ] [ recursive-only <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ ede <string> ]; ... } [ add-soa <boolean> ] [ break-dnssec <boolean> ] [ max-policy-ttl <duration> ] [ min-update-interval <duration> ] [ min-ns-dots <integer> ] [ nsip-wait-recurse <boolean> ] [ nsdname-wait-recurse <boolean> ] [ qname-wait-recurse <boolean> ] [ recursive-only <boolean> ] [ servfail-until-ready <boolean> ] [ nsip-enable <boolean> ] [ nsdname-enable <boolean> ] [ dnsrps-enable <boolean> ] [ dnsrps-options { <unspecified-text> } ];
root-key-sentinel <boolean>;
rrset-order { [ class <string> ] [ type <string> ] [ name <quoted_string> ] <string> <string>; ... };
send-cookie <boolean>;
serial-update-method ( date | increment | unixtime );
server <netprefix> {
bogus <boolean>;
edns <boolean>;
edns-udp-size <integer>;
edns-version <integer>;
keys <server_key>;
max-udp-size <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
padding <integer>;
provide-ixfr <boolean>;
query-source [ address ] ( <ipv4_address> | * );
query-source-v6 [ address ] ( <ipv6_address> | * );
request-expire <boolean>;
request-ixfr <boolean>;
request-nsid <boolean>;
require-cookie <boolean>;
send-cookie <boolean>;
tcp-keepalive <boolean>;
tcp-only <boolean>;
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
transfers <integer>;
}; // may occur multiple times
servfail-ttl <duration>;
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ]; // obsolete
sig0-key-checks-limit <integer>;
sig0-message-checks-limit <integer>;
sortlist { <address_match_element>; ... }; // deprecated
stale-answer-client-timeout ( disabled | off | <integer> );
stale-answer-enable <boolean>;
stale-answer-ttl <duration>;
stale-cache-enable <boolean>;
stale-refresh-time <duration>;
synth-from-dnssec <boolean>;
transfer-format ( many-answers | one-answer );
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
trust-anchor-telemetry <boolean>;
trust-anchors { <string> ( static-key | initial-key | static-ds | initial-ds ) <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times
trusted-keys { <string> <integer> <integer> <integer> <quoted_string>; ... }; // may occur multiple times, deprecated
try-tcp-refresh <boolean>;
v6-bias <integer>;
validate-except { <string>; ... };
zero-no-soa-ttl <boolean>;
zero-no-soa-ttl-cache <boolean>;
zone-statistics ( full | terse | none | <boolean> );
}; // may occur multiple times

View File

@@ -1,63 +0,0 @@
zone <string> [ <class> ] {
type primary;
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update { <address_match_element>; ... };
also-notify [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
check-mx-cname ( fail | warn | ignore );
check-names ( fail | warn | ignore );
check-sibling <boolean>;
check-spf ( warn | ignore );
check-srv-cname ( fail | warn | ignore );
check-svcb <boolean>;
check-wildcard <boolean>;
checkds ( explicit | <boolean> );
database <string>;
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
dlz <string>;
dnskey-sig-validity <integer>; // obsolete
dnssec-dnskey-kskonly <boolean>; // obsolete
dnssec-loadkeys-interval <integer>;
dnssec-policy <string>;
dnssec-secure-to-insecure <boolean>; // obsolete
dnssec-update-mode ( maintain | no-resign ) ; // obsolete
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
inline-signing <boolean>;
ixfr-from-differences <boolean>;
journal <quoted_string>;
key-directory <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
max-records-per-type <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> ); // deprecated
notify ( explicit | master-only | primary-only | <boolean> );
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
parental-agents [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
parental-source ( <ipv4_address> | * ) ;
parental-source-v6 ( <ipv6_address> | * ) ;
serial-update-method ( date | increment | unixtime );
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ]; // obsolete
update-policy ( local | { ( deny | grant ) <string> ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | krb5-subdomain-self-rhs | ms-self | ms-selfsub | ms-subdomain | ms-subdomain-self-rhs | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ <string> ] <rrtype list>; ... } );
zero-no-soa-ttl <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,15 +0,0 @@
zone <string> [ <class> ] {
type redirect;
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
dlz <string>;
file <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-records <integer>;
max-records-per-type <integer>;
max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> ); // deprecated
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,20 +0,0 @@
key <string> {
algorithm <string>;
secret <string>;
}; // may occur multiple times
options {
default-key <string>;
default-port <integer>;
default-server <string>;
default-source-address ( <ipv4_address> | * );
default-source-address-v6 ( <ipv6_address> | * );
};
server <string> {
addresses { ( <quoted_string> [ port <integer> ] | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ); ... };
key <string>;
port <integer>;
source-address ( <ipv4_address> | * );
source-address-v6 ( <ipv6_address> | * );
}; // may occur multiple times

View File

@@ -1,66 +0,0 @@
zone <string> [ <class> ] {
type secondary;
allow-notify { <address_match_element>; ... };
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
allow-transfer [ port <integer> ] [ transport <string> ] { <address_match_element>; ... };
allow-update-forwarding { <address_match_element>; ... };
also-notify [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
check-names ( fail | warn | ignore );
checkds ( explicit | <boolean> );
database <string>;
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
dlz <string>;
dnskey-sig-validity <integer>; // obsolete
dnssec-dnskey-kskonly <boolean>; // obsolete
dnssec-loadkeys-interval <integer>;
dnssec-policy <string>;
dnssec-update-mode ( maintain | no-resign ) ; // obsolete
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
inline-signing <boolean>;
ixfr-from-differences <boolean>;
journal <quoted_string>;
key-directory <quoted_string>;
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
notify ( explicit | master-only | primary-only | <boolean> );
notify-defer <integer>;
notify-delay <integer>;
notify-source ( <ipv4_address> | * ) ;
notify-source-v6 ( <ipv6_address> | * ) ;
notify-to-soa <boolean>;
nsec3-test-zone <boolean>; // test only
parental-agents [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
parental-source ( <ipv4_address> | * ) ;
parental-source-v6 ( <ipv6_address> | * ) ;
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
request-expire <boolean>;
request-ixfr <boolean>;
sig-signing-nodes <integer>;
sig-signing-signatures <integer>;
sig-signing-type <integer>;
sig-validity-interval <integer> [ <integer> ]; // obsolete
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
try-tcp-refresh <boolean>;
update-check-ksk <boolean>; // obsolete
zero-no-soa-ttl <boolean>;
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,13 +0,0 @@
zone <string> [ <class> ] {
type static-stub;
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
forward ( first | only );
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
max-records <integer>;
max-records-per-type <integer>;
max-types-per-name <integer>;
server-addresses { ( <ipv4_address> | <ipv6_address> ); ... };
server-names { <string>; ... };
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,28 +0,0 @@
zone <string> [ <class> ] {
type stub;
allow-query { <address_match_element>; ... };
allow-query-on { <address_match_element>; ... };
check-names ( fail | warn | ignore );
database <string>;
dialup ( notify | notify-passive | passive | refresh | <boolean> ); // deprecated
file <quoted_string>;
forward ( first | only );
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
masterfile-format ( raw | text );
masterfile-style ( full | relative );
max-records <integer>;
max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-time-in <integer>;
max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
min-transfer-rate-in <integer> <integer>;
multi-master <boolean>;
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
transfer-source ( <ipv4_address> | * ) ;
transfer-source-v6 ( <ipv6_address> | * ) ;
zone-statistics ( full | terse | none | <boolean> );
};

View File

@@ -1,85 +0,0 @@
{
"zone": {
"_id": "<string> [ <class> ]",
"_mapbody": {
"type": {
"_grammar": "stub"
},
"allow-query": {
"_grammar": "{ <address_match_element>; ... }"
},
"allow-query-on": {
"_grammar": "{ <address_match_element>; ... }"
},
"check-names": {
"_grammar": "( fail | warn | ignore )"
},
"database": {
"_grammar": "<string>"
},
"file": {
"_grammar": "<quoted_string>"
},
"forward": {
"_grammar": "( first | only )"
},
"forwarders": {
"_grammar": "[ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... }"
},
"masterfile-format": {
"_grammar": "( raw | text )"
},
"masterfile-style": {
"_grammar": "( full | relative )"
},
"max-records": {
"_grammar": "<integer>"
},
"max-records-per-type": {
"_grammar": "<integer>"
},
"max-refresh-time": {
"_grammar": "<integer>"
},
"max-retry-time": {
"_grammar": "<integer>"
},
"max-transfer-idle-in": {
"_grammar": "<integer>"
},
"max-transfer-time-in": {
"_grammar": "<integer>"
},
"max-types-per-name": {
"_grammar": "<integer>"
},
"min-refresh-time": {
"_grammar": "<integer>"
},
"min-retry-time": {
"_grammar": "<integer>"
},
"min-transfer-rate-in": {
"_grammar": "<integer> <integer>"
},
"multi-master": {
"_grammar": "<boolean>"
},
"primaries": {
"_grammar": "[ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <server-list> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... }"
},
"template": {
"_grammar": "<string>"
},
"transfer-source": {
"_grammar": "( <ipv4_address> | * )"
},
"transfer-source-v6": {
"_grammar": "( <ipv6_address> | * )"
},
"zone-statistics": {
"_grammar": "( full | terse | none | <boolean> )"
}
}
}
}

View File

@@ -16,6 +16,7 @@ bind9_config_indent: 4
bind9_group_config: [] bind9_group_config: []
bind9_site_config: [] bind9_site_config: []
bind9_host_config: [] bind9_host_config: []
bind9_default_config: bind9_default_config:
- name: named.conf - name: named.conf
backup: false backup: false
@@ -27,11 +28,10 @@ bind9_default_config:
options: options:
directory: "{{ bind9_working_directory }}" directory: "{{ bind9_working_directory }}"
bind9_config: >- bind9_config: "{{ [bind9_default_config,
{{ bind9_group_config,
[bind9_default_config, bind9_site_config,
bind9_group_config, bind9_host_config] |
bind9_site_config, community.general.lists_mergeby('name',
bind9_host_config] | recursive=true,
community.general.lists_mergeby('name', recursive=true, list_merge='append_rp') list_merge='append_rp') }}"
}}

View File

@@ -1,370 +0,0 @@
# BIND9 Version Support Policy
**Document Version**: 1.0
**Last Updated**: 2026-02-07
**Role Version**: Current development
## Overview
This document defines the version maintenance strategy for the ansible-bind9-role, including supported BIND9 versions, OS platforms, branching strategy, and release management policies.
## Supported Versions
### BIND9 Versions
| BIND9 Version | Branch | Status | Support Level | EOL Date |
|---------------|--------|--------|---------------|----------|
| 9.18.x (LTS) | `main` | ✅ Active | Full support | TBD (following ISC LTS timeline) |
| 9.20.x+ | `9.20` | 🚧 In Development | Planned | N/A |
#### Version Selection Rationale
- **BIND9 9.18**: Long Term Support (LTS) release from ISC
- Maintained by ISC with extended support timeline
- Stable feature set suitable for production environments
- Current focus of this role
- **BIND9 9.20+**: Feature release series
- Introduces significant configuration changes
- New features and modernization
- May have shorter support windows per release
- Will be supported in separate branch to prevent breaking changes
### Operating System Support Matrix
| OS Distribution | Versions | BIND9 9.18 | BIND9 9.20+ | Notes |
|----------------|----------|------------|-------------|-------|
| Debian | 11 (Bullseye) | ✅ Supported | 🔍 Testing | Current stable |
| Debian | 12 (Bookworm) | ✅ Supported | ✅ Supported | Current testing focus |
| Debian | 13 (Trixie) | ✅ Supported | ✅ Supported | Future stable |
| Ubuntu | 20.04 LTS | ✅ Supported | 🔍 Testing | LTS until 2025 |
| Ubuntu | 22.04 LTS | ✅ Supported | ✅ Supported | LTS until 2027 |
| Ubuntu | 24.04 LTS | ✅ Supported | ✅ Supported | LTS until 2029 |
**Legend**:
- ✅ Supported: Fully tested and supported
- 🔍 Testing: In testing, use with caution
- ⚠️ Limited: Basic support only
- ❌ Unsupported: Not supported
### Minimum Requirements
- **Ansible**: 2.13 or later
- **Python**: 3.8 or later (on controller and managed nodes)
- **BIND9 Packages**: Must be available in distribution repositories or custom sources
## Branching Strategy
### Branch Structure
```
main # BIND9 9.18 LTS (stable)
├── 9.20 # BIND9 9.20+ development
├── docs # Documentation updates (merged to both)
└── feature/* # Feature branches (target appropriate base)
```
### Branch Policies
#### `main` Branch
- **Purpose**: Production-ready code for BIND9 9.18 LTS
- **Stability**: Stable, tested releases only
- **Breaking Changes**: Not allowed
- **Version Tagging**: `v1.x.x`, `v2.x.x`, etc.
#### `9.20` Branch
- **Purpose**: Development for BIND9 9.20+ support
- **Stability**: Development/testing phase
- **Breaking Changes**: Allowed (vs 9.18 configurations)
- **Version Tagging**: `v9.20.x-betaX`, `v9.20.x-rcX`, `v9.20.x`
#### Feature Branches
- **Naming**: `feature/description` or `fix/issue-number`
- **Target**: Merge to appropriate base (`main` for 9.18, `9.20` for 9.20+)
- **Lifecycle**: Delete after merge
### Backporting Policy
#### Security Fixes
- **Policy**: MUST be backported to all supported branches
- **Timeline**: Within 48 hours of fix
- **Priority**: Critical
#### Bug Fixes
- **Policy**: SHOULD be backported if:
- Affects both versions
- Low risk of introducing regressions
- Reasonable effort required
- **Timeline**: Within 1 week
- **Priority**: High
#### New Features
- **Policy**: Case-by-case evaluation
- **Criteria**:
- Feature is compatible with both BIND9 versions
- Does not introduce breaking changes
- Provides significant value
- Low implementation complexity
- **Timeline**: Best effort
- **Priority**: Medium
#### Breaking Changes
- **Policy**: NEVER backported
- **Implementation**: Only in version-specific branches
## Release Management
### Version Numbering
Following [Semantic Versioning 2.0.0](https://semver.org/):
```
MAJOR.MINOR.PATCH
MAJOR: Incompatible API changes (role variable structure changes)
MINOR: New functionality in a backwards compatible manner
PATCH: Backwards compatible bug fixes
```
#### Examples
- `v1.2.3`: Patch release for BIND9 9.18
- `v2.0.0`: Major release with breaking role variable changes
- `v9.20.0-beta1`: Beta release for BIND9 9.20 support
- `v9.20.0`: First stable release for BIND9 9.20
### Release Cadence
- **Patch Releases**: As needed for bug fixes and security updates
- **Minor Releases**: Quarterly (or when significant features accumulate)
- **Major Releases**: Annually (or when breaking changes are necessary)
### Pre-release Testing
All releases must pass:
1. **Molecule tests** across all supported platforms
2. **named-checkconf** validation for all example configurations
3. **Manual testing** on at least 2 different distributions
4. **Documentation review** and update
### Release Checklist
- [ ] Update `CHANGELOG.md` with all changes
- [ ] Update version in `meta/main.yml`
- [ ] Run full molecule test suite
- [ ] Update `README.md` if needed
- [ ] Create annotated git tag
- [ ] Push tag to trigger CI/CD
- [ ] Create GitHub/Gitea release with notes
- [ ] Announce on project channels
## Testing Strategy
### Test Matrix
#### Molecule Scenarios
| Scenario | Distribution | BIND9 Version | Purpose |
|----------|--------------|---------------|---------|
| default | Debian 13 | 9.18 | Primary development testing |
| ubuntu2204 | Ubuntu 22.04 | 9.18 | LTS testing |
| ubuntu2404 | Ubuntu 24.04 | 9.18/9.20 | Future-proofing |
| debian12 | Debian 12 | 9.18 | Stable release testing |
#### Test Coverage
- **Syntax validation**: All templates pass `named-checkconf`
- **Service management**: Start, stop, reload, restart operations
- **Configuration types**: All zone types and statement blocks
- **Edge cases**: Empty configurations, complex nested structures
- **Upgrade scenarios**: Migration from previous role versions
### Continuous Integration
```yaml
# .github/workflows/test.yml (example structure)
on: [push, pull_request]
jobs:
molecule:
strategy:
matrix:
distro: [debian12, debian13, ubuntu2204, ubuntu2404]
bind_version: ['9.18', '9.20']
exclude:
# Don't test 9.20 on older distributions
- distro: ubuntu2004
bind_version: '9.20'
```
## Grammar Tracking and Validation
### Automated Grammar Comparison
The role maintains upstream BIND9 grammar files to:
1. Detect configuration syntax changes between versions
2. Identify deprecated and removed options
3. Document breaking changes for users
#### Grammar Repository Structure
```
bind9-grammar/
├── upstream/
│ ├── v9.18.44/ # Latest 9.18 LTS grammar
│ │ ├── grammar/
│ │ │ ├── options
│ │ │ ├── *.zoneopt
│ │ │ └── parsegrammar.py
│ │ └── metadata.json
│ └── v9.20.18/ # Latest 9.20 grammar
│ ├── grammar/
│ └── metadata.json
├── 9.18/ # Current 9.18 JSON schemas
│ └── *.json
└── 9.20/ # Future 9.20 JSON schemas
└── *.json
```
### Validation Tools
#### `scripts/fetch_bind_grammar.py`
- Fetches grammar files from Gitea mirror (`Mirrors/bind9`)
- Supports version tags (e.g., `v9.18.44`, `v9.20.18`)
- Stores upstream grammar for comparison
#### `scripts/compare_bind_versions.py`
- Compares grammar files between versions
- Generates `docs/BIND_VERSION_DIFFERENCES.md`
- Identifies:
- Breaking changes (removed options)
- New features (added options)
- Modified syntax
- Deprecation notices
### Grammar Update Workflow
1. **Monitor**: Watch Gitea mirror for new BIND9 releases
2. **Fetch**: Run `fetch_bind_grammar.py` for new version
3. **Compare**: Run `compare_bind_versions.py` to identify changes
4. **Review**: Analyze breaking changes and impact
5. **Update**: Modify templates and variables as needed
6. **Test**: Run molecule tests with new version
7. **Document**: Update `BIND_VERSION_DIFFERENCES.md` and `CHANGELOG.md`
## Deprecation Policy
### Deprecation Process
1. **Announcement**: Document deprecation in `CHANGELOG.md` and `README.md`
2. **Warning Period**: Minimum 2 minor releases before removal
3. **Alternative**: Provide migration path or alternative approach
4. **Removal**: Only in major version releases
### Current Deprecations
*None at this time*
### Planned Deprecations
*To be determined based on BIND9 9.20 analysis*
## Version-Specific Features
### Version Detection
The role will detect BIND9 version at runtime:
```yaml
# tasks/main.yml (planned implementation)
- name: Detect BIND9 version
ansible.builtin.command: named -V
register: _bind9_version_output
changed_when: false
- name: Set BIND9 version facts
ansible.builtin.set_fact:
bind9_version_full: "{{ _bind9_version_output.stdout | regex_search('BIND (\\S+)', '\\1') | first }}"
bind9_version_major: "{{ _bind9_version_output.stdout | regex_search('BIND (\\d+)\\.(\\d+)', '\\1') | first }}"
bind9_version_minor: "{{ _bind9_version_output.stdout | regex_search('BIND (\\d+)\\.(\\d+)', '\\2') | first }}"
```
### Conditional Configuration
Templates will use version-aware conditionals:
```jinja2
{# templates/named.conf.options.j2 (planned) #}
{% if bind9_version_major | int >= 20 %}
{# BIND9 9.20+ specific options #}
{% else %}
{# BIND9 9.18 options #}
{% endif %}
```
## Migration Guidance
### Migrating from BIND9 9.18 to 9.20
When BIND9 9.20 support is released:
1. **Review**: Read `docs/BIND_VERSION_DIFFERENCES.md`
2. **Test**: Use `9.20` branch in test environment
3. **Update**: Modify playbook variables for deprecated/removed options
4. **Validate**: Run `named-checkconf` against generated configuration
5. **Deploy**: Upgrade BIND9 package and deploy new configuration
6. **Monitor**: Check logs for warnings or errors
### Migrating Between Role Versions
See `CHANGELOG.md` for version-specific migration notes.
## Support and Contribution
### Getting Help
- **Issues**: Report bugs and request features on Gitea
- **Documentation**: Refer to `README.md` and `CONFIGURATION_GRAMMAR.md`
- **Examples**: Check `tests/` directory for working configurations
### Contributing
- **Bug Fixes**: Target `main` branch (or `9.20` if version-specific)
- **Features**: Discuss in issue before implementation
- **Testing**: Ensure molecule tests pass
- **Documentation**: Update relevant documentation files
### Governance
- **Maintainer**: Primary maintainer approves all merges
- **Review**: All changes require review before merge
- **Testing**: CI/CD must pass before merge
## Future Considerations
### BIND9 9.21+ and Beyond
- Monitor ISC release announcements
- Evaluate need for additional branches
- Consider dropping support for EOL'd distributions
- Reassess branching strategy if maintenance burden increases
### Automation Improvements
- Automated grammar fetching in CI
- Automated breaking change detection
- Version compatibility testing matrix
- Documentation generation from grammar files
## References
- [ISC BIND9 Documentation](https://bind9.readthedocs.io/)
- [ISC BIND9 Release Schedule](https://www.isc.org/bind/)
- [Semantic Versioning](https://semver.org/)
- [Ansible Best Practices](https://docs.ansible.com/ansible/latest/tips_tricks/ansible_tips_tricks.html)
## Changelog
| Date | Version | Changes |
|------|---------|---------|
| 2026-02-07 | 1.0 | Initial version support policy |

View File

@@ -16,8 +16,10 @@
- "{{ bind9_cfgdir }}" - "{{ bind9_cfgdir }}"
- "{{ bind9_working_directory }}" - "{{ bind9_working_directory }}"
- "{{ bind9_libdir }}" - "{{ bind9_libdir }}"
dest: "{{ bind9_backup_dir + '/bind9-config-' + ansible_facts.date_time.iso8601_basic_short + '.tar.gz' }}" dest: "{{
bind9_backup_dir + '/bind9-config-' +
ansible_facts.date_time.iso8601_basic_short + '.tar.gz' }}"
owner: root owner: root
group: root group: root
mode: "0640" mode: 0640
when: bind9_backup_config is defined and bind9_backup_config when: bind9_backup_config is defined and bind9_backup_config

View File

@@ -7,7 +7,7 @@ galaxy_info:
description: Configure Bind9 description: Configure Bind9
company: Valid.dk company: Valid.dk
issue_tracker_url: https://git.valid.dk/daniel/ansible-bind9-role issue_tracker_url: https://gitlab.valid.dk/operations/ansible-bind9-role
license: GPL-3.0-or-later license: GPL-3.0-or-later

View File

@@ -4,3 +4,4 @@ collections:
- name: ansible.posix - name: ansible.posix
- name: community.crypto - name: community.crypto
- name: community.general - name: community.general

View File

@@ -2,114 +2,6 @@
- name: Converge - name: Converge
hosts: all hosts: all
tasks: tasks:
- name: Create log directory for BIND
ansible.builtin.file:
path: /var/log/named
state: directory
mode: '0755'
owner: bind
group: bind
- name: Include bind9 role - name: Include bind9 role
ansible.builtin.include_role: ansible.builtin.include_role:
name: ../../../ansible-bind9-role # noqa: role-name[path] name: ../../../ansible-bind9-role
vars:
bind9_backup_config: false
bind9_host_config:
- name: named.conf.options
options:
directory: "{{ bind9_working_directory }}"
recursion: true
allow_query:
- any
allow_recursion:
- 10.0.0.0/8
- 192.168.0.0/16
- 172.16.0.0/12
- localhost
- localnets
forwarders:
- address: 91.239.100.100
tls: censurfridns-anycast
- address: 89.233.43.71
tls: censurfridns-unicast
forward: first
dnssec_validation: auto
dnstap:
- type: auth
- type: resolver
log: query
- type: client
log: response
dnstap_output:
output_type: file
output_file: /var/log/named/dnstap.log
size: 20m
versions: 3
suffix: increment
dnstap_identity: dns-server-01
dnstap_version: 9.18
logging:
channels:
- name: default_log
file:
name: /var/log/named/default.log
severity: info
print_time: true
print_severity: true
print_category: true
- name: security_log
file:
name: /var/log/named/security.log
severity: dynamic
print_time: true
print_severity: true
print_category: true
- name: query_log
file:
name: /var/log/named/queries.log
versions: 5
size: 10m
severity: info
print_time: true
- name: dnssec_log
file:
name: /var/log/named/dnssec.log
severity: debug
print_time: true
print_severity: true
- name: rate_limit_log
syslog: daemon
severity: warning
categories:
- name: default
channels:
- default_log
- name: general
channels:
- default_log
- name: security
channels:
- security_log
- name: queries
channels:
- query_log
- name: dnssec
channels:
- dnssec_log
- name: rate-limit
channels:
- rate_limit_log
- name: named.conf.local
tls:
- name: censurfridns-anycast
remote_hostname: anycast.uncensoreddns.org
- name: censurfridns-unicast
remote_hostname: unicast.uncensoreddns.org
zones:
- name: example.internal
type: forward
forward: only
forwarders:
- 10.0.0.53
- 10.0.0.54

View File

@@ -2,6 +2,13 @@
driver: driver:
name: podman name: podman
platforms: platforms:
- name: debian-bookworm
image: docker.io/jrei/systemd-debian:12
command: /lib/systemd/systemd
privileged: true
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
- name: debian-trixie - name: debian-trixie
image: docker.io/jrei/systemd-debian:13 image: docker.io/jrei/systemd-debian:13
command: /lib/systemd/systemd command: /lib/systemd/systemd

View File

@@ -1,11 +1,6 @@
--- ---
- name: Prepare - hosts: all
hosts: all
tasks: tasks:
- name: Update apt - name: Update apt
ansible.builtin.apt: ansible.builtin.apt:
update_cache: true update_cache: true
- name: Install bind9-dnsutils package
ansible.builtin.apt:
name: bind9-dnsutils
state: present

View File

@@ -1,76 +0,0 @@
---
- name: Verify
hosts: all
gather_facts: true
tasks:
- name: Check that BIND9 is installed
ansible.builtin.package:
name: bind9
state: present
check_mode: true
register: __bind9_package_check
failed_when: __bind9_package_check is changed
- name: Check that BIND9 service is running
ansible.builtin.service:
name: named
state: started
enabled: true
check_mode: true
register: __bind9_service_check
failed_when: __bind9_service_check is changed
- name: Check that named.conf.options exists
ansible.builtin.stat:
path: /etc/bind/named.conf.options
register: __options_file
failed_when: not __options_file.stat.exists
- name: Check that named.conf.local exists
ansible.builtin.stat:
path: /etc/bind/named.conf.local
register: __local_file
failed_when: not __local_file.stat.exists
- name: Read named.conf.options content
ansible.builtin.slurp:
path: /etc/bind/named.conf.options
register: __options_content
- name: Verify forwarders are configured in options
ansible.builtin.assert:
that:
- "'forwarders' in __options_decoded"
- "'8.8.8.8' in __options_decoded"
- "'forward first' in __options_decoded"
fail_msg: Forwarders not properly configured in named.conf.options
vars:
__options_decoded: "{{ __options_content.content | b64decode }}"
- name: Read named.conf.local content
ansible.builtin.slurp:
path: /etc/bind/named.conf.local
register: __local_content
- name: Verify forward zone is configured
ansible.builtin.assert:
that:
- "'zone \"example.internal\"' in __local_decoded"
- "'type forward' in __local_decoded"
- "'forward only' in __local_decoded"
fail_msg: Forward zone not properly configured in named.conf.local
vars:
__local_decoded: "{{ __local_content.content | b64decode }}"
- name: Test DNS resolution using localhost
ansible.builtin.command:
cmd: dig @localhost google.com +short
register: __dns_query
changed_when: false
failed_when: __dns_query.rc != 0
- name: Verify DNS query returned results
ansible.builtin.assert:
that:
- __dns_query.stdout_lines | length > 0
fail_msg: DNS forwarding is not working

View File

@@ -1,390 +0,0 @@
#!/usr/bin/env python3
"""
Compare BIND9 grammar files between versions to identify breaking changes.
This script compares grammar files from two BIND9 versions and generates
a comprehensive report of:
- Removed options (breaking changes)
- Added options (new features)
- Modified option syntax
- Deprecated options
Usage:
python scripts/compare_bind_versions.py \\
--version1-dir bind9-grammar/upstream/v9.18.44 \\
--version2-dir bind9-grammar/upstream/v9.20.18 \\
--output docs/BIND_VERSION_DIFFERENCES.md
"""
import argparse
import json
import sys
from pathlib import Path
from typing import Dict, List, Set, Tuple
import re
class GrammarComparator:
"""Compare BIND9 grammar files between versions."""
def __init__(self, version1_dir: Path, version2_dir: Path):
"""
Initialize comparator with two version directories.
Args:
version1_dir: Path to first version's grammar files
version2_dir: Path to second version's grammar files
"""
self.version1_dir = version1_dir
self.version2_dir = version2_dir
self.version1_name = version1_dir.name
self.version2_name = version2_dir.name
def load_grammar_file(self, file_path: Path) -> Dict:
"""Load and parse a grammar file."""
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Parse grammar file into structured data
options = self._parse_grammar(content)
return options
except FileNotFoundError:
return {}
def _parse_grammar(self, content: str) -> Dict[str, str]:
"""
Parse grammar content into a dictionary of options.
This is a simplified parser that extracts top-level keywords
and their definitions.
"""
options = {}
lines = content.split('\n')
for line in lines:
line = line.strip()
if not line or line.startswith('#') or line.startswith('//'):
continue
# Extract keyword and its definition
# Pattern: keyword <definition>; or keyword <definition> { ... };
match = re.match(r'^([a-z0-9-]+)\s+(.+?)(?:;|$)', line)
if match:
keyword = match.group(1)
definition = match.group(2).strip()
# Extract flags from comments
flags = []
if '// may occur multiple times' in line:
flags.append('may occur multiple times')
if '// deprecated' in line:
flags.append('deprecated')
if '// obsolete' in line:
flags.append('obsolete')
if '// not configured' in line:
flags.append('not configured')
if '// test only' in line:
flags.append('test only')
if '// experimental' in line:
flags.append('experimental')
options[keyword] = {
'definition': definition,
'flags': flags,
'raw_line': line
}
return options
def compare_files(self, filename: str) -> Dict:
"""
Compare a specific grammar file between two versions.
Returns:
Dict with added, removed, modified, and deprecated options
"""
file1 = self.version1_dir / 'grammar' / filename
file2 = self.version2_dir / 'grammar' / filename
options1 = self.load_grammar_file(file1)
options2 = self.load_grammar_file(file2)
keys1 = set(options1.keys())
keys2 = set(options2.keys())
# Identify changes
added = keys2 - keys1
removed = keys1 - keys2
common = keys1 & keys2
modified = []
deprecated_new = []
for key in common:
opt1 = options1[key]
opt2 = options2[key]
# Check if definition changed
if opt1['definition'] != opt2['definition']:
modified.append({
'option': key,
'old_definition': opt1['definition'],
'new_definition': opt2['definition']
})
# Check if newly deprecated
if 'deprecated' not in opt1['flags'] and 'deprecated' in opt2['flags']:
deprecated_new.append(key)
return {
'file': filename,
'added': sorted(added),
'removed': sorted(removed),
'modified': modified,
'deprecated_new': deprecated_new,
'options1_count': len(options1),
'options2_count': len(options2)
}
def compare_all(self) -> Dict:
"""Compare all grammar files between versions."""
# List of grammar files to compare
grammar_files = [
'options',
'forward.zoneopt',
'hint.zoneopt',
'in-view.zoneopt',
'mirror.zoneopt',
'primary.zoneopt',
'redirect.zoneopt',
'secondary.zoneopt',
'static-stub.zoneopt',
'stub.zoneopt',
'delegation-only.zoneopt',
'rndc.grammar',
]
results = {}
for filename in grammar_files:
result = self.compare_files(filename)
results[filename] = result
return results
def generate_markdown_report(self, results: Dict) -> str:
"""Generate a Markdown report from comparison results."""
lines = []
lines.append(f"# BIND9 Version Differences: {self.version1_name} vs {self.version2_name}")
lines.append("")
lines.append(f"This document compares BIND9 configuration grammar between {self.version1_name} and {self.version2_name}.")
lines.append("")
lines.append("Generated automatically by `scripts/compare_bind_versions.py`.")
lines.append("")
# Summary
lines.append("## Summary")
lines.append("")
total_added = sum(len(r['added']) for r in results.values())
total_removed = sum(len(r['removed']) for r in results.values())
total_modified = sum(len(r['modified']) for r in results.values())
total_deprecated = sum(len(r['deprecated_new']) for r in results.values())
lines.append(f"- **New Options**: {total_added}")
lines.append(f"- **Removed Options**: {total_removed} ⚠️")
lines.append(f"- **Modified Options**: {total_modified}")
lines.append(f"- **Newly Deprecated**: {total_deprecated}")
lines.append("")
# Breaking Changes
if total_removed > 0:
lines.append("## ⚠️ Breaking Changes")
lines.append("")
lines.append(f"The following options were removed in {self.version2_name} and will cause configuration errors:")
lines.append("")
for filename, result in results.items():
if result['removed']:
lines.append(f"### {filename}")
lines.append("")
for option in result['removed']:
lines.append(f"- `{option}`")
lines.append("")
# New Features
if total_added > 0:
lines.append("## ✨ New Features")
lines.append("")
lines.append(f"The following options were added in {self.version2_name}:")
lines.append("")
for filename, result in results.items():
if result['added']:
lines.append(f"### {filename}")
lines.append("")
for option in result['added']:
lines.append(f"- `{option}`")
lines.append("")
# Modified Options
if total_modified > 0:
lines.append("## 🔧 Modified Options")
lines.append("")
lines.append(f"The following options have syntax changes in {self.version2_name}:")
lines.append("")
for filename, result in results.items():
if result['modified']:
lines.append(f"### {filename}")
lines.append("")
for mod in result['modified']:
lines.append(f"#### `{mod['option']}`")
lines.append("")
lines.append(f"**{self.version1_name}**:")
lines.append(f"```")
lines.append(f"{mod['old_definition']}")
lines.append(f"```")
lines.append("")
lines.append(f"**{self.version2_name}**:")
lines.append(f"```")
lines.append(f"{mod['new_definition']}")
lines.append(f"```")
lines.append("")
# Deprecated Options
if total_deprecated > 0:
lines.append("## 📋 Newly Deprecated Options")
lines.append("")
lines.append(f"The following options were marked as deprecated in {self.version2_name}:")
lines.append("")
for filename, result in results.items():
if result['deprecated_new']:
lines.append(f"### {filename}")
lines.append("")
for option in result['deprecated_new']:
lines.append(f"- `{option}`")
lines.append("")
# File-by-File Comparison
lines.append("## Detailed File-by-File Comparison")
lines.append("")
for filename, result in results.items():
lines.append(f"### {filename}")
lines.append("")
lines.append(f"- {self.version1_name}: {result['options1_count']} options")
lines.append(f"- {self.version2_name}: {result['options2_count']} options")
lines.append(f"- Added: {len(result['added'])}")
lines.append(f"- Removed: {len(result['removed'])}")
lines.append(f"- Modified: {len(result['modified'])}")
lines.append("")
# Migration Guide
if total_removed > 0 or total_deprecated > 0:
lines.append("## Migration Guide")
lines.append("")
lines.append(f"### Migrating from {self.version1_name} to {self.version2_name}")
lines.append("")
if total_removed > 0:
lines.append("1. **Remove unsupported options** from your configuration")
lines.append(" - Review the Breaking Changes section above")
lines.append(" - Check if there are replacement options")
lines.append("")
if total_deprecated > 0:
lines.append("2. **Plan for deprecated options**")
lines.append(" - These options still work but may be removed in future versions")
lines.append(" - Start planning migration to recommended alternatives")
lines.append("")
lines.append("3. **Test your configuration**")
lines.append(" - Use `named-checkconf` to validate syntax")
lines.append(" - Test in a development environment before production")
lines.append("")
return '\n'.join(lines)
def main():
"""Main entry point."""
parser = argparse.ArgumentParser(
description="Compare BIND9 grammar files between versions"
)
parser.add_argument(
"--version1-dir",
type=Path,
required=True,
help="Directory containing first version's grammar files"
)
parser.add_argument(
"--version2-dir",
type=Path,
required=True,
help="Directory containing second version's grammar files"
)
parser.add_argument(
"--output",
type=Path,
default=Path("docs/BIND_VERSION_DIFFERENCES.md"),
help="Output file for Markdown report"
)
parser.add_argument(
"--json",
type=Path,
help="Also output raw comparison as JSON"
)
args = parser.parse_args()
# Validate directories
if not args.version1_dir.exists():
print(f"Error: {args.version1_dir} does not exist", file=sys.stderr)
sys.exit(1)
if not args.version2_dir.exists():
print(f"Error: {args.version2_dir} does not exist", file=sys.stderr)
sys.exit(1)
# Perform comparison
print(f"Comparing BIND9 versions:")
print(f" Version 1: {args.version1_dir.name}")
print(f" Version 2: {args.version2_dir.name}")
comparator = GrammarComparator(args.version1_dir, args.version2_dir)
results = comparator.compare_all()
# Generate and save Markdown report
report = comparator.generate_markdown_report(results)
args.output.parent.mkdir(parents=True, exist_ok=True)
with open(args.output, 'w', encoding='utf-8') as f:
f.write(report)
print(f"✓ Markdown report saved to: {args.output}")
# Save JSON if requested
if args.json:
args.json.parent.mkdir(parents=True, exist_ok=True)
with open(args.json, 'w', encoding='utf-8') as f:
json.dump(results, f, indent=2)
print(f"✓ JSON comparison saved to: {args.json}")
# Print summary
total_added = sum(len(r['added']) for r in results.values())
total_removed = sum(len(r['removed']) for r in results.values())
total_modified = sum(len(r['modified']) for r in results.values())
print(f"\nComparison Summary:")
print(f" Added options: {total_added}")
print(f" Removed options: {total_removed}")
print(f" Modified options: {total_modified}")
if total_removed > 0:
print(f"\n⚠️ Warning: {total_removed} breaking changes detected!")
if __name__ == "__main__":
main()

View File

@@ -1,179 +0,0 @@
#!/usr/bin/env python3
"""
Fetch BIND9 grammar files from Gitea mirror repository for version comparison.
This script uses the Gitea MCP tools to fetch grammar files from the official
BIND9 mirror at git.valid.dk/Mirrors/bind9 for specified version tags.
"""
import argparse
import json
import os
import sys
from pathlib import Path
from typing import Dict, List
# Grammar files to fetch from doc/misc/
GRAMMAR_FILES = [
"options",
"forward.zoneopt",
"hint.zoneopt",
"in-view.zoneopt",
"mirror.zoneopt",
"primary.zoneopt",
"redirect.zoneopt",
"secondary.zoneopt",
"static-stub.zoneopt",
"stub.zoneopt",
"delegation-only.zoneopt",
"rndc.grammar",
]
# Support files
SUPPORT_FILES = [
"parsegrammar.py",
"checkgrammar.py",
]
def fetch_file_content(owner: str, repo: str, ref: str, file_path: str) -> str:
"""
Fetch file content from Gitea repository.
This would use mcp_gitea-mcp_get_file_content in the actual MCP environment.
For standalone usage, returns placeholder.
"""
# In MCP environment, this would call:
# mcp_gitea-mcp_get_file_content(owner=owner, repo=repo, ref=ref, filePath=file_path)
print(f"Would fetch: {owner}/{repo}@{ref}:{file_path}")
return ""
def save_grammar_file(content: str, version: str, filename: str, output_dir: Path):
"""Save fetched grammar file to local directory."""
version_dir = output_dir / version / "grammar"
version_dir.mkdir(parents=True, exist_ok=True)
file_path = version_dir / filename
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"Saved: {file_path}")
def fetch_version_grammars(owner: str, repo: str, tag: str, output_dir: Path):
"""Fetch all grammar files for a specific version tag."""
print(f"\n=== Fetching grammar files for {tag} ===")
# Create metadata
metadata = {
"version": tag,
"repository": f"{owner}/{repo}",
"files": [],
}
# Fetch grammar files
for grammar_file in GRAMMAR_FILES:
try:
file_path = f"doc/misc/{grammar_file}"
content = fetch_file_content(owner, repo, tag, file_path)
if content:
save_grammar_file(content, tag, grammar_file, output_dir)
metadata["files"].append({
"name": grammar_file,
"path": file_path,
"type": "grammar"
})
except Exception as e:
print(f"Warning: Could not fetch {grammar_file}: {e}")
# Fetch support files
for support_file in SUPPORT_FILES:
try:
file_path = f"doc/misc/{support_file}"
content = fetch_file_content(owner, repo, tag, file_path)
if content:
save_grammar_file(content, tag, support_file, output_dir)
metadata["files"].append({
"name": support_file,
"path": file_path,
"type": "support"
})
except Exception as e:
print(f"Warning: Could not fetch {support_file}: {e}")
# Save metadata
metadata_file = output_dir / tag / "metadata.json"
with open(metadata_file, 'w', encoding='utf-8') as f:
json.dump(metadata, f, indent=2)
print(f"Metadata saved: {metadata_file}")
return metadata
def main():
"""Main entry point."""
parser = argparse.ArgumentParser(
description="Fetch BIND9 grammar files from Gitea mirror"
)
parser.add_argument(
"--owner",
default="Mirrors",
help="Repository owner (default: Mirrors)"
)
parser.add_argument(
"--repo",
default="bind9",
help="Repository name (default: bind9)"
)
parser.add_argument(
"--tags",
nargs="+",
default=["v9.18.44", "v9.20.18"],
help="Version tags to fetch (default: v9.18.44 v9.20.18)"
)
parser.add_argument(
"--output-dir",
type=Path,
default=Path("bind9-grammar/upstream"),
help="Output directory for grammar files"
)
args = parser.parse_args()
print("BIND9 Grammar Fetcher")
print("=" * 60)
print(f"Repository: {args.owner}/{args.repo}")
print(f"Tags: {', '.join(args.tags)}")
print(f"Output: {args.output_dir}")
# Fetch grammars for each version
results = {}
for tag in args.tags:
try:
metadata = fetch_version_grammars(
args.owner,
args.repo,
tag,
args.output_dir
)
results[tag] = metadata
except Exception as e:
print(f"Error fetching {tag}: {e}")
sys.exit(1)
# Save overall summary
summary_file = args.output_dir / "fetch_summary.json"
with open(summary_file, 'w', encoding='utf-8') as f:
json.dump(results, f, indent=2)
print(f"\n=== Fetch complete ===")
print(f"Summary: {summary_file}")
print(f"Fetched {len(results)} versions")
if __name__ == "__main__":
main()

View File

@@ -1,163 +0,0 @@
#!/usr/bin/env python3
"""
Fetch BIND9 grammar files using Gitea MCP integration.
This script demonstrates how to use mcp_gitea-mcp tools to fetch grammar files.
Since we can't directly call MCP tools from Python, this serves as documentation
for the manual fetching process that should be done through the MCP interface.
Usage:
The actual fetching should be done through MCP tool calls:
1. List available tags:
mcp_gitea-mcp_list_tags(owner="Mirrors", repo="bind9")
2. Get directory listing:
mcp_gitea-mcp_get_dir_content(owner="Mirrors", repo="bind9",
ref="v9.18.44", filePath="doc/misc")
3. Fetch each grammar file:
mcp_gitea-mcp_get_file_content(owner="Mirrors", repo="bind9",
ref="v9.18.44",
filePath="doc/misc/options")
"""
import json
from pathlib import Path
from typing import Dict, List
# Target versions
VERSIONS = {
"9.18": "v9.18.44",
"9.20": "v9.20.18",
}
# Grammar files to fetch
GRAMMAR_FILES = [
"options",
"forward.zoneopt",
"hint.zoneopt",
"in-view.zoneopt",
"mirror.zoneopt",
"primary.zoneopt",
"redirect.zoneopt",
"secondary.zoneopt",
"static-stub.zoneopt",
"stub.zoneopt",
"delegation-only.zoneopt",
"rndc.grammar",
]
SUPPORT_FILES = [
"parsegrammar.py",
"checkgrammar.py",
]
def generate_fetch_commands() -> List[Dict]:
"""Generate MCP tool call commands for fetching grammar files."""
commands = []
for version_name, tag in VERSIONS.items():
# List directory command
commands.append({
"tool": "mcp_gitea-mcp_get_dir_content",
"params": {
"owner": "Mirrors",
"repo": "bind9",
"ref": tag,
"filePath": "doc/misc"
},
"description": f"List grammar files for {version_name} ({tag})"
})
# File fetch commands
for grammar_file in GRAMMAR_FILES + SUPPORT_FILES:
commands.append({
"tool": "mcp_gitea-mcp_get_file_content",
"params": {
"owner": "Mirrors",
"repo": "bind9",
"ref": tag,
"filePath": f"doc/misc/{grammar_file}"
},
"save_to": f"bind9-grammar/upstream/{tag}/grammar/{grammar_file}",
"description": f"Fetch {grammar_file} for {version_name}"
})
return commands
def save_file_structure() -> Dict:
"""Generate expected file structure after fetching."""
structure = {
"bind9-grammar": {
"upstream": {}
}
}
for version_name, tag in VERSIONS.items():
structure["bind9-grammar"]["upstream"][tag] = {
"grammar": {
"files": GRAMMAR_FILES + SUPPORT_FILES
},
"metadata.json": {
"version": tag,
"version_name": version_name,
"repository": "Mirrors/bind9",
"fetched_files": len(GRAMMAR_FILES) + len(SUPPORT_FILES)
}
}
return structure
def main():
"""Generate instructions and commands for grammar fetching."""
print("=" * 70)
print("BIND9 Grammar Fetcher - MCP Integration Guide")
print("=" * 70)
print("\nTarget Versions:")
for version_name, tag in VERSIONS.items():
print(f" - BIND {version_name}: {tag}")
print(f"\nFiles to fetch per version: {len(GRAMMAR_FILES)} grammar files + {len(SUPPORT_FILES)} support files")
print("\n" + "=" * 70)
print("MCP TOOL CALL SEQUENCE")
print("=" * 70)
commands = generate_fetch_commands()
for i, cmd in enumerate(commands, 1):
print(f"\n[{i}/{len(commands)}] {cmd['description']}")
print(f"Tool: {cmd['tool']}")
print(f"Parameters:")
for key, value in cmd['params'].items():
print(f" - {key}: {value}")
if 'save_to' in cmd:
print(f"Save to: {cmd['save_to']}")
print("\n" + "=" * 70)
print("EXPECTED FILE STRUCTURE")
print("=" * 70)
structure = save_file_structure()
print(json.dumps(structure, indent=2))
# Save command list
output_dir = Path("bind9-grammar/upstream")
output_dir.mkdir(parents=True, exist_ok=True)
commands_file = output_dir / "fetch_commands.json"
with open(commands_file, 'w') as f:
json.dump(commands, f, indent=2)
print(f"\nCommand list saved to: {commands_file}")
print("\nNote: These commands should be executed through the MCP interface,")
print(" not directly from this Python script.")
if __name__ == "__main__":
main()

View File

@@ -1,78 +0,0 @@
#!/usr/bin/env python3
"""
Fetch BIND9 grammar files using Gitea MCP tools.
This script must be run from an environment where MCP tools are available.
"""
import base64
import json
import sys
from pathlib import Path
# Files to fetch
GRAMMAR_FILES = [
"options",
"forward.zoneopt",
"hint.zoneopt",
"in-view.zoneopt",
"mirror.zoneopt",
"primary.zoneopt",
"redirect.zoneopt",
"secondary.zoneopt",
"static-stub.zoneopt",
"stub.zoneopt",
"delegation-only.zoneopt",
"rndc.grammar",
"parsegrammar.py",
"checkgrammar.py",
]
def save_file_from_mcp_result(result_json: dict, output_path: Path) -> bool:
"""Save a file from MCP tool result JSON."""
try:
if 'Result' in result_json and 'content' in result_json['Result']:
content_b64 = result_json['Result']['content']
content = base64.b64decode(content_b64).decode('utf-8')
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(content)
return True
return False
except Exception as e:
print(f"Error saving {output_path}: {e}", file=sys.stderr)
return False
def main():
"""Process stdin JSON from MCP tool calls."""
print("Reading MCP tool results from stdin...")
# Read all input
input_data = sys.stdin.read()
try:
result = json.loads(input_data)
# Determine output path from result metadata
if 'Result' in result and 'name' in result['Result']:
filename = result['Result']['name']
# Output path will be provided as command line argument
if len(sys.argv) > 1:
output_path = Path(sys.argv[1])
if save_file_from_mcp_result(result, output_path):
print(f"✓ Saved: {output_path}")
sys.exit(0)
else:
print(f"✗ Failed to save: {output_path}", file=sys.stderr)
sys.exit(1)
print("✗ Could not determine output path", file=sys.stderr)
sys.exit(1)
except json.JSONDecodeError as e:
print(f"✗ Invalid JSON input: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -1,37 +0,0 @@
#!/usr/bin/env python3
"""Helper script to save base64-encoded grammar file from MCP tool output."""
import base64
import json
import sys
from pathlib import Path
def main():
if len(sys.argv) != 3:
print("Usage: save_grammar_file.py <json_file> <output_path>")
sys.exit(1)
json_file = Path(sys.argv[1])
output_path = Path(sys.argv[2])
# Read JSON from MCP tool output
with open(json_file, 'r') as f:
data = json.load(f)
# Extract and decode base64 content
if 'Result' in data and 'content' in data['Result']:
content_b64 = data['Result']['content']
content = base64.b64decode(content_b64).decode('utf-8')
# Save to output path
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"✓ Saved: {output_path}")
else:
print(f"✗ Error: No content found in JSON", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -15,16 +15,10 @@
state: directory state: directory
owner: root owner: root
group: root group: root
mode: "0750" mode: 0750
when: bind9_backup_config is defined and bind9_backup_config | bool when: bind9_backup_config is defined and bind9_backup_config | bool
- name: Deploy and Validate Configuration - name: Deploy and Validate Configuration
tags:
- bind9
- template
notify:
- Backup bind config
- Restart bind
block: block:
- name: Create backup of current config - name: Create backup of current config
ansible.builtin.copy: ansible.builtin.copy:
@@ -33,9 +27,9 @@
remote_src: true remote_src: true
owner: root owner: root
group: bind group: bind
mode: "0640" mode: 0640
changed_when: false
failed_when: false # It's okay if the file doesn't exist yet failed_when: false # It's okay if the file doesn't exist yet
# We do this for every file in the loop
loop: "{{ bind9_config }}" loop: "{{ bind9_config }}"
loop_control: loop_control:
label: "{{ item.name }}" label: "{{ item.name }}"
@@ -46,11 +40,11 @@
dest: "{{ bind9_cfgdir }}/{{ item.name }}" dest: "{{ bind9_cfgdir }}/{{ item.name }}"
owner: root owner: root
group: bind group: bind
mode: "0640" mode: 0640
loop: "{{ bind9_config }}" loop: "{{ bind9_config }}"
loop_control: loop_control:
label: "{{ item.name }}" label: "{{ item.name }}"
register: bind9_template_result register: _template_result
- name: Validate configuration using named-checkconf - name: Validate configuration using named-checkconf
ansible.builtin.command: ansible.builtin.command:
@@ -65,7 +59,7 @@
remote_src: true remote_src: true
owner: root owner: root
group: bind group: bind
mode: "0640" mode: 0640
loop: "{{ bind9_config }}" loop: "{{ bind9_config }}"
loop_control: loop_control:
label: "{{ item.name }}" label: "{{ item.name }}"
@@ -73,9 +67,7 @@
- name: Fail due to invalid configuration - name: Fail due to invalid configuration
ansible.builtin.fail: ansible.builtin.fail:
msg: | msg: "Configuration validation failed. Changes have been reverted. Check the logs for named-checkconf errors."
Configuration validation failed. Changes have been reverted.
Check the logs for named-checkconf errors.
always: always:
- name: Remove backup files - name: Remove backup files
@@ -85,7 +77,14 @@
loop: "{{ bind9_config }}" loop: "{{ bind9_config }}"
loop_control: loop_control:
label: "{{ item.name }}" label: "{{ item.name }}"
when: bind9_backup_config | bool is false when: bind9_backup_config | bool is false # Keep if backup is forced, otherwise cleanup temporary atomic backup
tags:
- bind9
- template
notify:
- Backup bind config
- Restart bind
- name: Ensure the named service is started - name: Ensure the named service is started
ansible.builtin.service: ansible.builtin.service:

View File

@@ -110,36 +110,4 @@
{% else %} {% else %}
{{ name }} "{{ value }}"; {{ name }} "{{ value }}";
{% endif %} {% endif %}
{% endmacro %}
{% macro list_address_port_tls(dict, indent=bind9_config_indent) %}
{# This macro is for use for statements with grammar like #}
{# address port 00 tls str; address port 00 tls str; #}
{# it is usually called by a parent macro #}
{% filter indent(indent, true) %}
{% for item in dict %}
{% if item is not mapping %}
{{ item }};
{% else %}
{{ item.address }}
{{- (' port ' + item.port | string) if item.port is defined and item.port -}}
{{- (' tls ' + item.tls | string) if item.tls is defined and item.tls -}};
{% endif %}
{% endfor %}
{% endfilter %}
{% endmacro %}
{% macro parent_address_port_tls(name, dict) %}
{# This macro is for use for statements with grammar like #}
{# statement port 00 tls str { address port 00 tls str; address port 00 tls str; } #}
{# the list inside the statement is handled by list_address_port_tls #}
{% if dict is not mapping and dict is iterable %}
{{ name }} {
{{ list_address_port_tls(dict) }}};
{% else %}
{{ name }}
{{- (' port ' + dict.port | string) if dict.port is defined and dict.port -}}
{{- (' tls ' + dict.tls | string) if dict.tls is defined and dict.tls }} {
{{ list_address_port_tls(dict.addresses) }}};
{% endif %}
{% endmacro %} {% endmacro %}

View File

@@ -54,3 +54,6 @@
{% if item.view is defined and item.view %} {% if item.view is defined and item.view %}
{% include 'named.conf.view.j2' %} {% include 'named.conf.view.j2' %}
{% endif %} {% endif %}
{% if item.remote_servers is defined and item.remote_servers %}
{% include 'named.conf.remote-servers.j2' %}
{% endif %}

View File

@@ -1,22 +1,28 @@
{% import 'named.conf.functions.j2' as functions with context %}
options { options {
{% filter indent(bind9_config_indent,true)%} {% filter indent(bind9_config_indent,true)%}
{# Unicorn Options#} {# Iterate over keys to preserve user order (Python 3.7+ / Ansible dicts are ordered) #}
{% if item.options.rrset_order is defined and item.options.rrset_order %} {% for key, value in item.options.items() %}
{% set conf_key = key | replace('_', '-') %}
{# --- COMPLEX BLOCKS --- #}
{% if key == 'rrset_order' %}
rrset-order { rrset-order {
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
{% for rrset in item.options.rrset_order %} {% for rrset in value %}
{{ ('class ' + rrset.class | string + ' ') if rrset.class is defined and rrset.class -}} {{ ('class ' + rrset.class | string + ' ') if rrset.class is defined and rrset.class -}}
{{ ('type ' + rrset.type | string + ' ') if rrset.type is defined and rrset.type -}} {{ ('type ' + rrset.type | string + ' ') if rrset.type is defined and rrset.type -}}
{{ ('name "' + rrset.name | string + '" ') if rrset.name is defined and rrset.name -}} {{ ('name "' + rrset.name | string + '" ') if rrset.name is defined and rrset.name -}}
{{ ('order ' + rrset.order | string) -}}; {{ ('order ' + rrset.order | string) -}};
{% endfor %} {% endfor %}
{% endfilter %}}; {% endfilter %}};
{% endif %}
{% if item.options.response_policy is defined and item.options.response_policy %} {% elif key == 'response_policy' %}
response-policy { response-policy {
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
{% for zone in item.options.response_policy.zones %} {% for zone in value.zones %}
{{- ('zone ' + zone.zone | string) -}} {{- ('zone ' + zone.zone | string) -}}
{{- (' max-policy-ttl ' + zone.max_policy_ttl | string) if zone.max_policy_ttl is defined and zone.max_policy_ttl -}} {{- (' max-policy-ttl ' + zone.max_policy_ttl | string) if zone.max_policy_ttl is defined and zone.max_policy_ttl -}}
{{- (' min-update-interval ' + zone.min_update_interval | string) if zone.min_update_interval is defined and zone.min_update_interval -}} {{- (' min-update-interval ' + zone.min_update_interval | string) if zone.min_update_interval is defined and zone.min_update_interval -}}
@@ -28,108 +34,86 @@ response-policy {
{{- (' nsdname-enable ' + functions.named_boolean(zone.nsdname_enable)) if zone.nsdname_enable is defined }}; {{- (' nsdname-enable ' + functions.named_boolean(zone.nsdname_enable)) if zone.nsdname_enable is defined }};
{% endfor %} {% endfor %}
{% endfilter %}} {% endfilter %}}
{{- (' max-policy-ttl ' + item.options.response_policy.max_policy_ttl | string) if item.options.response_policy.max_policy_ttl is defined and item.options.response_policy.max_policy_ttl -}} {{- (' max-policy-ttl ' + value.max_policy_ttl | string) if value.max_policy_ttl is defined and value.max_policy_ttl -}}
{{- (' min-update-interval ' + item.options.response_policy.min_update_interval | string) if item.options.response_policy.min_update_interval is defined and item.options.response_policy.min_update_interval -}} {{- (' min-update-interval ' + value.min_update_interval | string) if value.min_update_interval is defined and value.min_update_interval -}}
{{- (' min-ns-dots ' + item.options.response_policy.min_ns_dots | string) if item.options.response_policy.min_ns_dots is defined and item.options.response_policy.min_ns_dots -}} {{- (' min-ns-dots ' + value.min_ns_dots | string) if value.min_ns_dots is defined and value.min_ns_dots -}}
{{- (' add-soa ' + functions.named_boolean(item.options.response_policy.add_soa)) if item.options.response_policy.add_soa is defined -}} {{- (' add-soa ' + functions.named_boolean(value.add_soa)) if value.add_soa is defined -}}
{{- (' break-dnssec ' + functions.named_boolean(item.options.response_policy.break_dnssec)) if item.options.response_policy.break_dnssec is defined -}} {{- (' break-dnssec ' + functions.named_boolean(value.break_dnssec)) if value.break_dnssec is defined -}}
{{- (' nsip-wait-recurse ' + functions.named_boolean(item.options.response_policy.nsip_wait_recurse)) if item.options.response_policy.nsip_wait_recurse is defined -}} {{- (' nsip-wait-recurse ' + functions.named_boolean(value.nsip_wait_recurse)) if value.nsip_wait_recurse is defined -}}
{{- (' nsdname-wait-recurse ' + functions.named_boolean(item.options.response_policy.nsdname_wait_recurse)) if item.options.response_policy.nsdname_wait_recurse is defined -}} {{- (' nsdname-wait-recurse ' + functions.named_boolean(value.nsdname_wait_recurse)) if value.nsdname_wait_recurse is defined -}}
{{- (' qname-wait-recurse ' + functions.named_boolean(item.options.response_policy.qname_wait_recurse)) if item.options.response_policy.qname_wait_recurse is defined -}} {{- (' qname-wait-recurse ' + functions.named_boolean(value.qname_wait_recurse)) if value.qname_wait_recurse is defined -}}
{{- (' recursive-only ' + functions.named_boolean(item.options.response_policy.recursive_only)) if item.options.response_policy.recursive_only is defined -}} {{- (' recursive-only ' + functions.named_boolean(value.recursive_only)) if value.recursive_only is defined -}}
{{- (' nsip-enable ' + functions.named_boolean(item.options.response_policy.nsip_enable)) if item.options.response_policy.nsip_enable is defined -}} {{- (' nsip-enable ' + functions.named_boolean(value.nsip_enable)) if value.nsip_enable is defined -}}
{{- (' nsdname-enable ' + functions.named_boolean(item.options.response_policy.nsdname_enable)) if item.options.response_policy.nsdname_enable is defined -}} {{- (' nsdname-enable ' + functions.named_boolean(value.nsdname_enable)) if value.nsdname_enable is defined -}}
{{- (' dnsrps-enable ' + functions.named_boolean(item.options.response_policy.dnsrps_enable)) if item.options.response_policy.dnsrps_enable is defined -}} {{- (' dnsrps-enable ' + functions.named_boolean(value.dnsrps_enable)) if value.dnsrps_enable is defined -}}
{{- (' dnsrps-options { ' + item.options.response_policy.dnsrps_options | join('; ') + '; }') if item.options.response_policy.dnsrps_options is defined and item.options.response_policy.dnsrps_options -}}; {{- (' dnsrps-options { ' + value.dnsrps_options | join('; ') + '; }') if value.dnsrps_options is defined and value.dnsrps_options -}};
{% endif %}
{% if item.options.response_padding is defined and item.options.response_padding %} {% elif key == 'response_padding' %}
response-padding { response-padding {
{{ functions.simple_item_list(item.options.response_padding.addresses) }}} {{ functions.simple_item_list(value.addresses) }}}
{{- (' block-size ' + item.options.response_padding.block_size | string) }}; {{- (' block-size ' + value.block_size | string) }};
{% endif %}
{% if item.options.rate_limit is defined and item.options.rate_limit %} {% elif key == 'rate_limit' %}
rate-limit { rate-limit {
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
{{ ('all-per-second ' + item.options.rate_limit.all_per_second | string + ';\n') if item.options.rate_limit.all_per_second is defined and item.options.rate_limit.all_per_second -}} {{ ('all-per-second ' + value.all_per_second | string + ';\n') if value.all_per_second is defined and value.all_per_second -}}
{{ ('errors-per-second ' + item.options.rate_limit.errors_per_second | string + ';\n') if item.options.rate_limit.errors_per_second is defined and item.options.rate_limit.errors_per_second -}} {{ ('errors-per-second ' + value.errors_per_second | string + ';\n') if value.errors_per_second is defined and value.errors_per_second -}}
{{ ('responses-per-second ' + item.options.rate_limit.responses_per_second | string + ';\n') if item.options.rate_limit.responses_per_second is defined and item.options.rate_limit.responses_per_second -}} {{ ('responses-per-second ' + value.responses_per_second | string + ';\n') if value.responses_per_second is defined and value.responses_per_second -}}
{{ ('referrals-per-second ' + item.options.rate_limit.referrals_per_second | string + ';\n') if item.options.rate_limit.referrals_per_second is defined and item.options.rate_limit.referrals_per_second -}} {{ ('referrals-per-second ' + value.referrals_per_second | string + ';\n') if value.referrals_per_second is defined and value.referrals_per_second -}}
{{ ('nodata-per-second ' + item.options.rate_limit.nodata_per_second | string + ';\n') if item.options.rate_limit.nodata_per_second is defined and item.options.rate_limit.nodata_per_second -}} {{ ('nodata-per-second ' + value.nodata_per_second | string + ';\n') if value.nodata_per_second is defined and value.nodata_per_second -}}
{{ ('nxdomains-per-second ' + item.options.rate_limit.nxdomains_per_second | string + ';\n') if item.options.rate_limit.nxdomains_per_second is defined and item.options.rate_limit.nxdomains_per_second -}} {{ ('nxdomains-per-second ' + value.nxdomains_per_second | string + ';\n') if value.nxdomains_per_second is defined and value.nxdomains_per_second -}}
{{ ('ipv4-prefix-length ' + item.options.rate_limit.ipv4_prefix_length | string + ';\n') if item.options.rate_limit.ipv4_prefix_length is defined and item.options.rate_limit.ipv4_prefix_length -}} {{ ('ipv4-prefix-length ' + value.ipv4_prefix_length | string + ';\n') if value.ipv4_prefix_length is defined and value.ipv4_prefix_length -}}
{{ ('ipv6-prefix-length ' + item.options.rate_limit.ipv6_prefix_length | string + ';\n') if item.options.rate_limit.ipv6_prefix_length is defined and item.options.rate_limit.ipv6_prefix_length -}} {{ ('ipv6-prefix-length ' + value.ipv6_prefix_length | string + ';\n') if value.ipv6_prefix_length is defined and value.ipv6_prefix_length -}}
{{ ('max-table-size ' + item.options.rate_limit.max_table_size | string + ';\n') if item.options.rate_limit.max_table_size is defined and item.options.rate_limit.max_table_size -}} {{ ('max-table-size ' + value.max_table_size | string + ';\n') if value.max_table_size is defined and value.max_table_size -}}
{{ ('min-table-size ' + item.options.rate_limit.min_table_size | string + ';\n') if item.options.rate_limit.min_table_size is defined and item.options.rate_limit.min_table_size -}} {{ ('min-table-size ' + value.min_table_size | string + ';\n') if value.min_table_size is defined and value.min_table_size -}}
{{ ('qps-scale ' + item.options.rate_limit.qps_scale | string + ';\n') if item.options.rate_limit.qps_scale is defined and item.options.rate_limit.qps_scale -}} {{ ('qps-scale ' + value.qps_scale | string + ';\n') if value.qps_scale is defined and value.qps_scale -}}
{{ ('window ' + item.options.rate_limit.window | string + ';\n') if item.options.rate_limit.window is defined and item.options.rate_limit.window -}} {{ ('window ' + value.window | string + ';\n') if value.window is defined and value.window -}}
{{ ('slip ' + item.options.rate_limit.slip | string + ';\n') if item.options.rate_limit.slip is defined and item.options.rate_limit.slip -}} {{ ('slip ' + value.slip | string + ';\n') if value.slip is defined and value.slip -}}
{{ ('log-only ' + functions.named_boolean(item.options.rate_limit.log_only) + ';\n') if item.options.rate_limit.log_only is defined -}} {{ ('log-only ' + functions.named_boolean(value.log_only) + ';\n') if value.log_only is defined -}}
{{ ('exempt-clients {\n' + functions.simple_item_list(item.options.rate_limit.exempt_clients) + '};\n') if item.options.rate_limit.exempt_clients is defined and item.options.rate_limit.exempt_clients -}} {{ ('exempt-clients {\n' + functions.simple_item_list(value.exempt_clients) + '};\n') if value.exempt_clients is defined and value.exempt_clients -}}
{% endfilter %}}; {% endfilter %}};
{% endif %}
{% if item.options.listen_on_v6 is defined and item.options.listen_on_v6 %} {% elif key == 'listen_on_v6' or key == 'listen_on' %}
{% for listen in item.options.listen_on_v6 if item.options.listen_on_v6 is not mapping %} {% for listen in (value if value is not mapping else [value]) %}
listen-on-v6 {{ conf_key }}
{{- (' port ' + listen.port | string) if listen.port is defined and listen.port -}} {{- (' port ' + listen.port | string) if listen.port is defined and listen.port -}}
{{- (' dscp ' + listen.dscp | string) if listen.dscp is defined and listen.dscp -}} {{- (' dscp ' + listen.dscp | string) if listen.dscp is defined and listen.dscp -}}
{{- (' tls ' + listen.tls | string) if listen.tls is defined and listen.tls -}} {{- (' tls ' + listen.tls | string) if listen.tls is defined and listen.tls -}}
{{- (' http ' + listen.http | string) if listen.http is defined and listen.http }} { {{- (' http ' + listen.http | string) if listen.http is defined and listen.http }} {
{{ functions.simple_item_list(listen.addresses) }}}; {{ functions.simple_item_list(listen.addresses) }}};
{% else %}
listen-on-v6
{{- (' port ' + item.options.listen_on_v6.port | string) if item.options.listen_on_v6.port is defined and item.options.listen_on_v6.port -}}
{{- (' dscp ' + item.options.listen_on_v6.dscp | string) if item.options.listen_on_v6.dscp is defined and item.options.listen_on_v6.dscp -}}
{{- (' tls ' + item.options.listen_on_v6.tls | string) if item.options.listen_on_v6.tls is defined and item.options.listen_on_v6.tls -}}
{{- (' http ' + item.options.listen_on_v6.http | string) if item.options.listen_on_v6.http is defined and item.options.listen_on_v6.http }} {
{{ functions.simple_item_list(item.options.listen_on_v6.addresses) }}};
{% endfor %} {% endfor %}
{% endif %}
{% if item.options.listen_on is defined and item.options.listen_on %} {% elif key == 'forwarders' %}
{% for listen in item.options.listen_on if item.options.listen_on is not mapping %} {{ functions.parent_address_port_dscp("forwarders", value) -}}
listen-on
{{- (' port ' + listen.port | string) if listen.port is defined and listen.port -}} {% elif key == 'dual_stack_servers' %}
{{- (' dscp ' + listen.dscp | string) if listen.dscp is defined and listen.dscp -}}
{{- (' tls ' + listen.tls | string) if listen.tls is defined and listen.tls -}}
{{- (' http ' + listen.http | string) if listen.http is defined and listen.http }} {
{{ functions.simple_item_list(listen.addresses) }}};
{% else %}
listen-on
{{- (' port ' + item.options.listen_on.port | string) if item.options.listen_on.port is defined and item.options.listen_on.port -}}
{{- (' dscp ' + item.options.listen_on.dscp | string) if item.options.listen_on.dscp is defined and item.options.listen_on.dscp -}}
{{- (' tls ' + item.options.listen_on.tls | string) if item.options.listen_on.tls is defined and item.options.listen_on.tls -}}
{{- (' http ' + item.options.listen_on.http | string) if item.options.listen_on.http is defined and item.options.listen_on.http }} {
{{ functions.simple_item_list(item.options.listen_on.addresses) }}};
{% endfor %}
{% endif %}
{{ functions.parent_address_port_tls("forwarders", item.options.forwarders) if item.options.forwarders is defined and item.options.forwarders -}}
{% if item.options.dual_stack_servers is defined and item.options.dual_stack_servers %}
dual-stack-servers dual-stack-servers
{{ (' port ' + item.options.dual_stack_servers.port | string) if item.options.dual_stack_servers.port is defined and item.options.dual_stack_servers }} { {{ (' port ' + value.port | string) if value.port is defined and value }} {
{% for host in item.options.dual_stack_servers.addresses %} {% for host in value.addresses %}
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
{{ host.address | ansible.utils.ipaddr | ternary(host.address, '"' + host.address + '"') }} {{ host.address | ansible.utils.ipaddr | ternary(host.address, '"' + host.address + '"') }}
{{- (' port ' + host.port | string) if host.port is defined and host.port -}} {{- (' port ' + host.port | string) if host.port is defined and host.port -}}
{{- (' dscp ' + host.dscp | string) if host.dscp is defined and host.dscp -}}; {{- (' dscp ' + host.dscp | string) if host.dscp is defined and host.dscp -}};
{% endfilter %} {% endfilter %}
{% endfor %}}; {% endfor %}};
{% endif %}
{% if item.options.dnstap_output is defined and item.options.dnstap_output %} {% elif key == 'dnstap_output' %}
dnstap-output {{ item.options.dnstap_output.output_type -}} dnstap-output {{ value.output_type -}}
{{- ' "' + item.options.dnstap_output.output_file + '"' -}} {{- ' "' + value.output_file + '"' -}}
{{- (' size ' + item.options.dnstap_output.size | string) if item.options.dnstap_output.size is defined and item.options.dnstap_output.size -}} {{- (' size ' + value.size | string) if value.size is defined and value.size -}}
{{- (' versions ' + item.options.dnstap_output.versions | string) if item.options.dnstap_output.versions is defined and item.options.dnstap_output.versions -}} {{- (' versions ' + value.versions | string) if value.versions is defined and value.versions -}}
{{- (' suffix ' + item.options.dnstap_output.suffix | string) if item.options.dnstap_output.suffix is defined and item.options.dnstap_output.suffix -}}; {{- (' suffix ' + value.suffix | string) if value.suffix is defined and value.suffix -}};
{% endif %}
{% if item.options.dnstap is defined and item.options.dnstap %} {% elif key == 'dnstap' %}
dnstap { dnstap {
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
{% for dnstap in item.options.dnstap %} {% for dnstap in value %}
{{ dnstap.type }}{{ ' ' + dnstap.log if dnstap.log is defined and dnstap.log }}; {{ dnstap.type }}{{ ' ' + dnstap.log if dnstap.log is defined and dnstap.log }};
{% endfor %} {% endfor %}
{% endfilter %}}; {% endfilter %}};
{% endif %}
{% if item.options.dns64 is defined and item.options.dns64 %} {% elif key == 'dns64' %}
{% for dns64 in item.options.dns64 if item.options.dns64 is sequence %} {% for dns64 in (value if value is sequence else [value]) %}
dns64 {{ dns64.netprefix }} { dns64 {{ dns64.netprefix }} {
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
{{ ('break-dnssec ' + functions.named_boolean(dns64.break_dnssec) + ';\n') if dns64.break_dnssec is defined and dns64.break_dnssec is boolean -}} {{ ('break-dnssec ' + functions.named_boolean(dns64.break_dnssec) + ';\n') if dns64.break_dnssec is defined and dns64.break_dnssec is boolean -}}
@@ -140,31 +124,31 @@ dns64 {{ dns64.netprefix }} {
{{ ("mapped {\n" + functions.simple_item_list(dns64.mapped) + "};\n") if dns64.mapped is defined and dns64.mapped -}} {{ ("mapped {\n" + functions.simple_item_list(dns64.mapped) + "};\n") if dns64.mapped is defined and dns64.mapped -}}
{% endfilter %}}; {% endfilter %}};
{% endfor %} {% endfor %}
{% endif %}
{% if item.options.deny_answer_aliases is defined and item.options.deny_answer_aliases %} {% elif key == 'deny_answer_aliases' %}
deny-answer-aliases { deny-answer-aliases {
{{ functions.simple_item_list(item.options.deny_answer_aliases.names) }}} {{ functions.simple_item_list(value.names) }}}
{%- if item.options.deny_answer_aliases.except_from is defined and item.options.deny_answer_aliases.except_from %} {%- if value.except_from is defined and value.except_from %}
except-from { except-from {
{{ functions.simple_item_list(item.options.deny_answer_aliases.except_from, 4) }}} {{ functions.simple_item_list(value.except_from, 4) }}}
{%- endif %}; {%- endif %};
{% endif %}
{% if item.options.deny_answer_addresses is defined and item.options.deny_answer_addresses %} {% elif key == 'deny_answer_addresses' %}
deny-answer-addresses { deny-answer-addresses {
{{ functions.simple_item_list(item.options.deny_answer_addresses.addresses) }}} {{ functions.simple_item_list(value.addresses) }}}
{%- if item.options.deny_answer_addresses.except_from is defined and item.options.deny_answer_addresses.except_from %} {%- if value.except_from is defined and value.except_from %}
except-from { except-from {
{{ functions.simple_item_list(item.options.deny_answer_addresses.except_from, 4) }}} {{ functions.simple_item_list(value.except_from, 4) }}}
{%- endif %}; {%- endif %};
{% endif %}
{% if item.options.check_names is defined and item.options.check_names %} {% elif key == 'check_names' %}
{% for policy in item.options.check_names %} {% for policy in value %}
check-names {{ policy.type }} {{ policy.action }}; check-names {{ policy.type }} {{ policy.action }};
{% endfor %} {% endfor %}
{% endif %}
{% if item.options.catalog_zones is defined and item.options.catalog_zones %} {% elif key == 'catalog_zones' %}
catalog-zones { catalog-zones {
{% for catalog_zone in item.options.catalog_zones %} {% for catalog_zone in value %}
zone {{ catalog_zone.zone }} zone {{ catalog_zone.zone }}
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
{% if catalog_zone.default_primaries is defined and catalog_zone.default_primaries %} {% if catalog_zone.default_primaries is defined and catalog_zone.default_primaries %}
@@ -178,291 +162,80 @@ default-primaries
{{ ('min-update-interval ' + catalog_zone.min_update_interval | string) if catalog_zone.min_update_interval is defined and catalog_zone.min_update_interval}}; {{ ('min-update-interval ' + catalog_zone.min_update_interval | string) if catalog_zone.min_update_interval is defined and catalog_zone.min_update_interval}};
{% endfilter %} {% endfilter %}
{% endfor %}}; {% endfor %}};
{% endif %}
{{ functions.single_ip_port_dscp('transfer-source', item.options.transfer_source) if item.options.transfer_source is defined and item.options.transfer_source -}} {% elif key in ['transfer_source', 'transfer_source_v6', 'alt_transfer_source', 'alt_transfer_source_v6', 'query_source', 'query_source_v6', 'parental_source', 'parental_source_v6', 'notify_source', 'notify_source_v6'] %}
{{ functions.single_ip_port_dscp('transfer-source-v6', item.options.transfer_source_v6) if item.options.transfer_source_v6 is defined and item.options.transfer_source_v6 -}} {{ functions.single_ip_port_dscp(conf_key, value) -}}
{{ functions.single_ip_port_dscp('alt-transfer-source', item.options.alt_transfer_source) if item.options.alt_transfer_source is defined and item.options.alt_transfer_source -}}
{{ functions.single_ip_port_dscp('alt-transfer-source-v6', item.options.alt_transfer_source_v6) if item.options.alt_transfer_source_v6 is defined and item.options.alt_transfer_source_v6 -}} {% elif key == 'also_notify' and value is not string %}
{{ functions.single_ip_port_dscp('query-source', item.options.query_source) if item.options.query_source is defined and item.options.query_source -}}
{{ functions.single_ip_port_dscp('query-source-v6', item.options.query_source_v6) if item.options.query_source_v6 is defined and item.options.query_source_v6 -}}
{{ functions.single_ip_port_dscp('parental-source', item.options.parental_source) if item.options.parental_source is defined and item.options.parental_source -}}
{{ functions.single_ip_port_dscp('parental-source-v6', item.options.parental_source_v6) if item.options.parental_source_v6 is defined and item.options.parental_source_v6 -}}
{{ functions.single_ip_port_dscp('notify-source', item.options.notify_source) if item.options.notify_source is defined and item.options.notify_source -}}
{{ functions.single_ip_port_dscp('notify-source-v6', item.options.notify_source_v6) if item.options.notify_source_v6 is defined and item.options.notify_source_v6 -}}
{% if item.options.also_notify is defined and item.options.also_notify is not string %}
also-notify also-notify
{{- (' port ' + item.options.also_notify.port | string) if item.options.also_notify.port is defined and item.options.also_notify.port -}} {{- (' port ' + value.port | string) if value.port is defined and value.port -}}
{{- (' dscp ' + item.options.also_notify.dscp | string) if item.options.also_notify.dscp is defined and item.options.also_notify.dscp }} { {{- (' dscp ' + value.dscp | string) if value.dscp is defined and value.dscp }} {
{{ functions.list_address_port_key_tls(item.options.also_notify.addresses) }}}; {{ functions.list_address_port_key_tls(value.addresses) }}};
{% endif %}
{% if item.options.allow_transfer is defined and item.options.allow_transfer is not string %} {% elif key == 'allow_transfer' and value is not string %}
allow-transfer allow-transfer
{{- (' port ' + item.options.allow_transfer.port | string) if item.options.allow_transfer.port is defined and item.options.allow_transfer.port -}} {{- (' port ' + value.port | string) if value.port is defined and value.port -}}
{{- (' transport ' + item.options.allow_transfer.transport) if item.options.allow_transfer.transport is defined and item.options.allow_transfer.transport }} { {{- (' transport ' + value.transport) if value.transport is defined and value.transport }} {
{{ functions.simple_item_list(item.options.allow_transfer.addresses) }}}; {{ functions.simple_item_list(value.addresses) }}};
{% endif %}
{# The rest #} {% elif key == 'disable_algorithms' %}
{% if item.options.disable_algorithms is defined and item.options.disable_algorithms %} {% for item in value %}
{% for item in item.options.disable_algorithms %}
disable-algorithms {{ item.domain }} { "{{ item.algorithms | join('"; "') }}"; }; disable-algorithms {{ item.domain }} { "{{ item.algorithms | join('"; "') }}"; };
{% endfor %} {% endfor %}
{% endif %}
{% if item.options.disable_ds_digests is defined and item.options.disable_ds_digests %} {% elif key == 'disable_ds_digests' %}
{% for item in item.options.disable_ds_digests %} {% for item in value %}
disable-ds-digests {{ item.domain }} { "{{ item.digests | join('"; "') }}"; }; disable-ds-digests {{ item.domain }} { "{{ item.digests | join('"; "') }}"; };
{% endfor %} {% endfor %}
{% endif %}
{# Oddball simple options #} {% elif key == 'root_delegation_only' %}
{% if item.options.fetch_quota_params is defined and item.options.fetch_quota_params is string %} root-delegation-only{% if value.exclude is defined and value.exclude is sequence %} exclude {
fetch-quota-params {{ item.options.fetch_quota_params }}; {{ functions.simple_item_list(value.exclude) }}}
{% endif %}
{% if item.options.fetches_per_server is defined and item.options.fetches_per_server is string %}
fetches-per-server {{ item.options.fetches_per_server }};
{% endif %}
{% if item.options.fetches_per_zone is defined and item.options.fetches_per_zone is string %}
fetches-per-zone {{ item.options.fetches_per_zone }};
{% endif %}
{% if item.options.prefetch is defined and item.options.prefetch %}
prefetch {{ item.options.prefetch }};
{% endif %}
{% if item.options.root_delegation_only is defined and item.options.root_delegation_only %}
root-delegation-only{% if item.options.root_delegation_only.exclude is defined and item.options.root_delegation_only.exclude is sequence %} exclude {
{{ functions.simple_item_list(item.options.root_delegation_only.exclude) }}}
{% endif %}; {% endif %};
{% elif key == 'tkey_dhkey' %}
tkey-dhkey "{{ value.key_name }}" {{ value.key_tag }};
{# --- SPECIAL QUOTED STRINGS --- #}
{% elif key in ['dnstap_identity', 'server_id'] %}
{{ functions.reserved_or_quoted(conf_key, value, ['none', 'hostname']) -}}
{% elif key in ['dnstap_version', 'geoip_directory', 'hostname', 'lock_file', 'pid_file', 'random_device', 'session_keyfile', 'version'] %}
{{ functions.reserved_or_quoted(conf_key, value, ['none']) -}}
{# --- DEPRECATED/OBSOLETE --- #}
{% elif key == 'tkey_domain' %}
{# Obsolete in 9.20 #}
/* WARN: tkey-domain is obsolete in BIND 9.20 */
{{ functions.reserved_or_quoted(conf_key, value, ['none']) -}}
{% elif key == 'tkey_gssapi_credential' %}
{# Deprecated in 9.20 #}
/* WARN: tkey-gssapi-credential is deprecated in BIND 9.20; use tkey-gssapi-keytab */
{{ functions.reserved_or_quoted(conf_key, value, ['none']) -}}
{# --- SIMPLE LISTS --- #}
{% elif key in ['allow_notify', 'allow_query', 'allow_query_cache', 'allow_query_cache_on', 'allow_query_on', 'allow_recursion', 'allow_recursion_on', 'allow_update', 'allow_update_forwarding', 'blackhole', 'keep_response_order', 'no_case_compress', 'sortlist', 'avoid_v4_udp_ports', 'avoid_v6_udp_ports', 'use_v4_udp_ports', 'use_v6_udp_ports', 'validate_except'] %}
{{ conf_key }} {
{{ functions.simple_item_list(value) }}};
{# --- QUOTED STRINGS --- #}
{% elif key in ['bindkeys_file', 'directory', 'dump_file', 'key_directory', 'managed_keys_directory', 'memstatistics_file', 'new_zones_directory', 'recursing_file', 'secroots_file', 'statistics_file', 'tkey_gssapi_keytab'] %}
{{ conf_key }} "{{ value }}";
{# --- BOOLEANS --- #}
{% elif key in ['allow_new_zones', 'answer_cookie', 'auth_nxdomain', 'automatic_interface_scan', 'check_integrity', 'check_sibling', 'check_wildcard', 'dnsrps_enable', 'dnssec_accept_expired', 'dnssec_dnskey_kskonly', 'dnssec_secure_to_insecure', 'empty_zones_enable', 'flush_zones_on_shutdown', 'glue_cache', 'ipv4only_enable', 'match_mapped_addresses', 'memstatistics', 'message_compression', 'minimal_any', 'multi_master', 'notify_to_soa', 'provide_ixfr', 'querylog', 'recursion', 'request_expire', 'request_ixfr', 'request_nsid', 'require_server_cookie', 'reuseport', 'root_key_sentinel', 'send_cookie', 'stale_answer_enable', 'stale_cache_enable', 'synth_from_dnssec', 'trust_anchor_telemetry', 'try_tcp_refresh', 'update_check_ksk', 'use_alt_transfer_source', 'zero_no_soa_ttl', 'zero_no_soa_ttl_cache'] %}
{{ functions.boolean_option(conf_key, value) }}
{# --- BOOLEAN OR STRING --- #}
{% elif key in ['dialup', 'ixfr_from_differences', 'minimal_responses', 'notify', 'zone_statistics', 'dnssec_validation'] %}
{{ conf_key }} {{ functions.boolean_or_string(value) }};
{# --- FALLTHROUGH --- #}
{% else %}
{# Strict mode: Ignore unknown keys or warn if possible. For now, silence is safer than invalid config. #}
{% endif %} {% endif %}
{% if item.options.sig_validity_interval is defined and item.options.sig_validity_interval %}
sig-validity-interval {{ item.options.sig_validity_interval }}; {% endfor %}
{% endif %}
{% if item.options.tkey_dhkey is defined and item.options.tkey_dhkey is mapping %}
tkey-dhkey "{{ item.options.tkey_dhkey.key_name }}" {{ item.options.tkey_dhkey.key_tag }};
{% endif %}
{# special_quoted_string options with reserved keywords #}
{% if item.options.dnstap_identity is defined and item.options.dnstap_identity is string %}
{{ functions.reserved_or_quoted('dnstap-identity', item.options.dnstap_identity, ['none', 'hostname']) -}}
{% endif %}
{% if item.options.dnstap_version is defined and item.options.dnstap_version is string %}
{{ functions.reserved_or_quoted('dnstap-version', item.options.dnstap_version, ['none']) -}}
{% endif %}
{% if item.options.geoip_directory is defined and item.options.geoip_directory is string %}
{{ functions.reserved_or_quoted('geoip-directory', item.options.geoip_directory, ['none']) -}}
{% endif %}
{% if item.options.hostname is defined and item.options.hostname is string %}
{{ functions.reserved_or_quoted('hostname', item.options.hostname, ['none']) -}}
{% endif %}
{% if item.options.lock_file is defined and item.options.lock_file is string %}
{{ functions.reserved_or_quoted('lock-file', item.options.lock_file, ['none']) -}}
{% endif %}
{% if item.options.pid_file is defined and item.options.pid_file is string %}
{{ functions.reserved_or_quoted('pid-file', item.options.pid_file, ['none']) -}}
{% endif %}
{% if item.options.random_device is defined and item.options.random_device is string %}
{{ functions.reserved_or_quoted('random-device', item.options.random_device, ['none']) -}}
{% endif %}
{% if item.options.server_id is defined and item.options.server_id is string %}
{{ functions.reserved_or_quoted('server-id', item.options.server_id, ['none', 'hostname']) -}}
{% endif %}
{% if item.options.session_keyfile is defined and item.options.session_keyfile is string %}
{{ functions.reserved_or_quoted('session-keyfile', item.options.session_keyfile, ['none']) -}}
{% endif %}
{% if item.options.version is defined and item.options.version is string %}
{{ functions.reserved_or_quoted('version', item.options.version, ['none']) -}}
{% endif %}
{# simple list options #}
{{ ('avoid-v4-udp-ports {\n' + functions.simple_item_list(item.options.avoid_v4_udp_ports) + '};\n') if item.options.avoid_v4_udp_ports is defined and item.options.avoid_v4_udp_ports -}}
{{ ('avoid-v6-udp-ports {\n' + functions.simple_item_list(item.options.avoid_v6_udp_ports) + '};\n') if item.options.avoid_v6_udp_ports is defined and item.options.avoid_v6_udp_ports -}}
{{ ('use-v4-udp-ports {\n' + functions.simple_item_list(item.options.use_v4_udp_ports) + '};\n') if item.options.use_v4_udp_ports is defined and item.options.use_v4_udp_ports -}}
{{ ('use-v6-udp-ports {\n' + functions.simple_item_list(item.options.use_v6_udp_ports) + '};\n') if item.options.use_v6_udp_ports is defined and item.options.use_v6_udp_ports -}}
{{ ('validate-except {\n' + functions.simple_item_list(item.options.validate_except) + '};\n') if item.options.validate_except is defined and item.options.validate_except -}}
{# boolean_or_string options #}
{{ ('dialup ' + functions.boolean_or_string(item.options.dialup) + ';\n') if item.options.dialup is defined -}}
{{ ('ixfr-from-differences ' + functions.boolean_or_string(item.options.ixfr_from_differences) + ';\n') if item.options.ixfr_from_differences is defined -}}
{{ ('minimal-responses ' + functions.boolean_or_string(item.options.minimal_responses) + ';\n') if item.options.minimal_responses is defined -}}
{{ ('notify ' + functions.boolean_or_string(item.options.notify) + ';\n') if item.options.notify is defined -}}
{{ ('zone-statistics ' + functions.boolean_or_string(item.options.zone_statistics) + ';\n') if item.options.zone_statistics is defined -}}
{# duration_sizeval options #}
{{ ('fstrm-set-reopen-interval ' + item.options.fstrm_set_reopen_interval | string +';\n') if item.options.fstrm_set_reopen_interval is defined and item.options.fstrm_set_reopen_interval -}}
{{ ('interface-interval ' + item.options.interface_interval | string +';\n') if item.options.interface_interval is defined and item.options.interface_interval -}}
{{ ('lame-ttl ' + item.options.lame_ttl | string +';\n') if item.options.lame_ttl is defined and item.options.lame_ttl -}}
{{ ('lmdb-mapsize ' + item.options.lmdb_mapsize | string +';\n') if item.options.lmdb_mapsize is defined and item.options.lmdb_mapsize -}}
{{ ('max-cache-ttl ' + item.options.max_cache_ttl | string +';\n') if item.options.max_cache_ttl is defined and item.options.max_cache_ttl -}}
{{ ('max-ncache-ttl ' + item.options.max_ncache_ttl | string +';\n') if item.options.max_ncache_ttl is defined and item.options.max_ncache_ttl -}}
{{ ('max-stale-ttl ' + item.options.max_stale_ttl | string +';\n') if item.options.max_stale_ttl is defined and item.options.max_stale_ttl -}}
{{ ('min-cache-ttl ' + item.options.min_cache_ttl | string +';\n') if item.options.min_cache_ttl is defined and item.options.min_cache_ttl -}}
{{ ('min-ncache-ttl ' + item.options.min_ncache_ttl | string +';\n') if item.options.min_ncache_ttl is defined and item.options.min_ncache_ttl -}}
{{ ('nta-lifetime ' + item.options.nta_lifetime | string +';\n') if item.options.nta_lifetime is defined and item.options.nta_lifetime -}}
{{ ('nta-recheck ' + item.options.nta_recheck | string +';\n') if item.options.nta_recheck is defined and item.options.nta_recheck -}}
{{ ('servfail-ttl ' + item.options.servfail_ttl | string +';\n') if item.options.servfail_ttl is defined and item.options.servfail_ttl -}}
{{ ('stale-answer-ttl ' + item.options.stale_answer_ttl | string +';\n') if item.options.stale_answer_ttl is defined and item.options.stale_answer_ttl -}}
{{ ('stale-refresh-time ' + item.options.stale_refresh_time | string +';\n') if item.options.stale_refresh_time is defined and item.options.stale_refresh_time -}}
{# special options options #}
{{ ('auto-dnssec ' + item.options.auto_dnssec | string +';\n') if item.options.auto_dnssec is defined and item.options.auto_dnssec -}}
{{ ('check-dup-records ' + item.options.check_dup_records | string +';\n') if item.options.check_dup_records is defined and item.options.check_dup_records -}}
{{ ('check-mx ' + item.options.check_mx | string +';\n') if item.options.check_mx is defined and item.options.check_mx -}}
{{ ('check-mx-cname ' + item.options.check_mx_cname | string +';\n') if item.options.check_mx_cname is defined and item.options.check_mx_cname -}}
{{ ('check-spf ' + item.options.check_spf | string +';\n') if item.options.check_spf is defined and item.options.check_spf -}}
{{ ('check-srv-cname ' + item.options.check_srv_cname | string +';\n') if item.options.check_srv_cname is defined and item.options.check_srv_cname -}}
{{ ('cookie-algorithm ' + item.options.cookie_algorithm | string +';\n') if item.options.cookie_algorithm is defined and item.options.cookie_algorithm -}}
{{ ('coresize ' + item.options.coresize | string +';\n') if item.options.coresize is defined and item.options.coresize -}}
{{ ('datasize ' + item.options.datasize | string +';\n') if item.options.datasize is defined and item.options.datasize -}}
{{ ('dnssec-update-mode ' + item.options.dnssec_update_mode | string +';\n') if item.options.dnssec_update_mode is defined and item.options.dnssec_update_mode -}}
{{ ('dnssec-validation ' + functions.boolean_or_string(item.options.dnssec_validation) +';\n') if item.options.dnssec_validation is defined -}}
{{ ('files ' + item.options.files | string +';\n') if item.options.files is defined and item.options.files -}}
{{ ('forward ' + item.options.forward | string +';\n') if item.options.forward is defined and item.options.forward -}}
{{ ('fstrm-set-output-queue-model ' + item.options.fstrm_set_output_queue_model | string +';\n') if item.options.fstrm_set_output_queue_model is defined and item.options.fstrm_set_output_queue_model -}}
{{ ('masterfile-format ' + item.options.masterfile_format | string +';\n') if item.options.masterfile_format is defined and item.options.masterfile_format -}}
{{ ('masterfile-style ' + item.options.masterfile_style | string +';\n') if item.options.masterfile_style is defined and item.options.masterfile_style -}}
{{ ('max-cache-size ' + item.options.max_cache_size | string +';\n') if item.options.max_cache_size is defined and item.options.max_cache_size -}}
{{ ('max-ixfr-ratio ' + item.options.max_ixfr_ratio | string +';\n') if item.options.max_ixfr_ratio is defined and item.options.max_ixfr_ratio -}}
{{ ('max-journal-size ' + item.options.max_journal_size | string +';\n') if item.options.max_journal_size is defined and item.options.max_journal_size -}}
{{ ('max-zone-ttl ' + item.options.max_zone_ttl | string +';\n') if item.options.max_zone_ttl is defined and item.options.max_zone_ttl -}}
{{ ('qname-minimization ' + item.options.qname_minimization | string +';\n') if item.options.qname_minimization is defined and item.options.qname_minimization -}}
{{ ('serial-update-method ' + item.options.serial_update_method | string +';\n') if item.options.serial_update_method is defined and item.options.serial_update_method -}}
{{ ('stacksize ' + item.options.stacksize | string +';\n') if item.options.stacksize is defined and item.options.stacksize -}}
{{ ('stale-answer-client-timeout ' + item.options.stale_answer_client_timeout | string +';\n') if item.options.stale_answer_client_timeout is defined and item.options.stale_answer_client_timeout -}}
{{ ('transfer-format ' + item.options.transfer_format | string +';\n') if item.options.transfer_format is defined and item.options.transfer_format -}}
{# quoted_string options #}
{{ ('bindkeys-file "' + item.options.bindkeys_file | string +'";\n') if item.options.bindkeys_file is defined and item.options.bindkeys_file -}}
{{ ('directory "' + item.options.directory | string +'";\n') if item.options.directory is defined and item.options.directory -}}
{{ ('dump-file "' + item.options.dump_file | string +'";\n') if item.options.dump_file is defined and item.options.dump_file -}}
{{ ('key-directory "' + item.options.key_directory | string +'";\n') if item.options.key_directory is defined and item.options.key_directory -}}
{{ ('managed-keys-directory "' + item.options.managed_keys_directory | string +'";\n') if item.options.managed_keys_directory is defined and item.options.managed_keys_directory -}}
{{ ('memstatistics-file "' + item.options.memstatistics_file | string +'";\n') if item.options.memstatistics_file is defined and item.options.memstatistics_file -}}
{{ ('new-zones-directory "' + item.options.new_zones_directory | string +'";\n') if item.options.new_zones_directory is defined and item.options.new_zones_directory -}}
{{ ('recursing-file "' + item.options.recursing_file | string +'";\n') if item.options.recursing_file is defined and item.options.recursing_file -}}
{{ ('secroots-file "' + item.options.secroots_file | string +'";\n') if item.options.secroots_file is defined and item.options.secroots_file -}}
{{ ('statistics-file "' + item.options.statistics_file | string +'";\n') if item.options.statistics_file is defined and item.options.statistics_file -}}
{{ ('tkey-domain "' + item.options.tkey_domain | string +'";\n') if item.options.tkey_domain is defined and item.options.tkey_domain -}}
{{ ('tkey-gssapi-credential "' + item.options.tkey_gssapi_credential | string +'";\n') if item.options.tkey_gssapi_credential is defined and item.options.tkey_gssapi_credential -}}
{{ ('tkey-gssapi-keytab "' + item.options.tkey_gssapi_keytab | string +'";\n') if item.options.tkey_gssapi_keytab is defined and item.options.tkey_gssapi_keytab -}}
{# simple_item_list options #}
{{ ('allow-notify {\n' + functions.simple_item_list(item.options.allow_notify) + '};\n') if item.options.allow_notify is defined and item.options.allow_notify -}}
{{ ('allow-query {\n' + functions.simple_item_list(item.options.allow_query) + '};\n') if item.options.allow_query is defined and item.options.allow_query -}}
{{ ('allow-query-cache {\n' + functions.simple_item_list(item.options.allow_query_cache) + '};\n') if item.options.allow_query_cache is defined and item.options.allow_query_cache -}}
{{ ('allow-query-cache-on {\n' + functions.simple_item_list(item.options.allow_query_cache_on) + '};\n') if item.options.allow_query_cache_on is defined and item.options.allow_query_cache_on -}}
{{ ('allow-query-on {\n' + functions.simple_item_list(item.options.allow_query_on) + '};\n') if item.options.allow_query_on is defined and item.options.allow_query_on -}}
{{ ('allow-recursion {\n' + functions.simple_item_list(item.options.allow_recursion) + '};\n') if item.options.allow_recursion is defined and item.options.allow_recursion -}}
{{ ('allow-recursion-on {\n' + functions.simple_item_list(item.options.allow_recursion_on) + '};\n') if item.options.allow_recursion_on is defined and item.options.allow_recursion_on -}}
{{ ('allow-update {\n' + functions.simple_item_list(item.options.allow_update) + '};\n') if item.options.allow_update is defined and item.options.allow_update -}}
{{ ('allow-update-forwarding {\n' + functions.simple_item_list(item.options.allow_update_forwarding) + '};\n') if item.options.allow_update_forwarding is defined and item.options.allow_update_forwarding -}}
{{ ('blackhole {\n' + functions.simple_item_list(item.options.blackhole) + '};\n') if item.options.blackhole is defined and item.options.blackhole -}}
{{ ('keep-response-order {\n' + functions.simple_item_list(item.options.keep_response_order) + '};\n') if item.options.keep_response_order is defined and item.options.keep_response_order -}}
{{ ('no-case-compress {\n' + functions.simple_item_list(item.options.no_case_compress) + '};\n') if item.options.no_case_compress is defined and item.options.no_case_compress -}}
{{ ('sortlist {\n' + functions.simple_item_list(item.options.sortlist) + '};\n') if item.options.sortlist is defined and item.options.sortlist -}}
{# String options #}
{{ ('attach-cache ' + item.options.attach_cache | string +';\n') if item.options.attach_cache is defined and item.options.attach_cache -}}
{{ ('cookie-secret ' + item.options.cookie_secret | string +';\n') if item.options.cookie_secret is defined and item.options.cookie_secret -}}
{{ ('disable-empty-zone ' + item.options.disable_empty_zone | string +';\n') if item.options.disable_empty_zone is defined and item.options.disable_empty_zone -}}
{{ ('dns64-contact ' + item.options.dns64_contact | string +';\n') if item.options.dns64_contact is defined and item.options.dns64_contact -}}
{{ ('dns64-server ' + item.options.dns64_server | string +';\n') if item.options.dns64_server is defined and item.options.dns64_server -}}
{{ ('dnssec-policy ' + item.options.dnssec_policy | string +';\n') if item.options.dnssec_policy is defined and item.options.dnssec_policy -}}
{{ ('empty-contact ' + item.options.empty_contact | string +';\n') if item.options.empty_contact is defined and item.options.empty_contact -}}
{{ ('empty-server ' + item.options.empty_server | string +';\n') if item.options.empty_server is defined and item.options.empty_server -}}
{{ ('ipv4only-contact ' + item.options.ipv4only_contact | string +';\n') if item.options.ipv4only_contact is defined and item.options.ipv4only_contact -}}
{{ ('ipv4only-server ' + item.options.ipv4only_server | string +';\n') if item.options.ipv4only_server is defined and item.options.ipv4only_server -}}
{{ ('nxdomain-redirect ' + item.options.nxdomain_redirect | string +';\n') if item.options.nxdomain_redirect is defined and item.options.nxdomain_redirect -}}
{{ ('preferred-glue ' + item.options.preferred_glue | string +';\n') if item.options.preferred_glue is defined and item.options.preferred_glue -}}
{{ ('session-keyalg ' + item.options.session_keyalg | string +';\n') if item.options.session_keyalg is defined and item.options.session_keyalg -}}
{{ ('session-keyname ' + item.options.session_keyname | string +';\n') if item.options.session_keyname is defined and item.options.session_keyname -}}
{# Integer options #}
{{ ('clients-per-query ' + item.options.clients_per_query | string +';\n') if item.options.clients_per_query is defined and item.options.clients_per_query -}}
{{ ('dnskey-sig-validity ' + item.options.dnskey_sig_validity | string +';\n') if item.options.dnskey_sig_validity is defined and item.options.dnskey_sig_validity -}}
{{ ('dnssec-loadkeys-interval ' + item.options.dnssec_loadkeys_interval | string +';\n') if item.options.dnssec_loadkeys_interval is defined and item.options.dnssec_loadkeys_interval -}}
{{ ('dscp ' + item.options.dscp | string +';\n') if item.options.dscp is defined and item.options.dscp -}}
{{ ('edns-udp-size ' + item.options.edns_udp_size | string +';\n') if item.options.edns_udp_size is defined and item.options.edns_udp_size -}}
{{ ('fstrm-set-buffer-hint ' + item.options.fstrm_set_buffer_hint | string +';\n') if item.options.fstrm_set_buffer_hint is defined and item.options.fstrm_set_buffer_hint -}}
{{ ('fstrm-set-flush-timeout ' + item.options.fstrm_set_flush_timeout | string +';\n') if item.options.fstrm_set_flush_timeout is defined and item.options.fstrm_set_flush_timeout -}}
{{ ('fstrm-set-input-queue-size ' + item.options.fstrm_set_input_queue_size | string +';\n') if item.options.fstrm_set_input_queue_size is defined and item.options.fstrm_set_input_queue_size -}}
{{ ('fstrm-set-output-notify-threshold ' + item.options.fstrm_set_output_notify_threshold | string +';\n') if item.options.fstrm_set_output_notify_threshold is defined and item.options.fstrm_set_output_notify_threshold -}}
{{ ('fstrm-set-output-queue-size ' + item.options.fstrm_set_output_queue_size | string +';\n') if item.options.fstrm_set_output_queue_size is defined and item.options.fstrm_set_output_queue_size -}}
{{ ('heartbeat-interval ' + item.options.heartbeat_interval | string +';\n') if item.options.heartbeat_interval is defined and item.options.heartbeat_interval -}}
{{ ('http-listener-clients ' + item.options.http_listener_clients | string +';\n') if item.options.http_listener_clients is defined and item.options.http_listener_clients -}}
{{ ('http-port ' + item.options.http_port | string +';\n') if item.options.http_port is defined and item.options.http_port -}}
{{ ('http-streams-per-connection ' + item.options.http_streams_per_connection | string +';\n') if item.options.http_streams_per_connection is defined and item.options.http_streams_per_connection -}}
{{ ('https-port ' + item.options.https_port | string +';\n') if item.options.https_port is defined and item.options.https_port -}}
{{ ('max-clients-per-query ' + item.options.max_clients_per_query | string +';\n') if item.options.max_clients_per_query is defined and item.options.max_clients_per_query -}}
{{ ('max-records ' + item.options.max_records | string +';\n') if item.options.max_records is defined and item.options.max_records -}}
{{ ('max-recursion-depth ' + item.options.max_recursion_depth | string +';\n') if item.options.max_recursion_depth is defined and item.options.max_recursion_depth -}}
{{ ('max-recursion-queries ' + item.options.max_recursion_queries | string +';\n') if item.options.max_recursion_queries is defined and item.options.max_recursion_queries -}}
{{ ('max-refresh-time ' + item.options.max_refresh_time | string +';\n') if item.options.max_refresh_time is defined and item.options.max_refresh_time -}}
{{ ('max-retry-time ' + item.options.max_retry_time | string +';\n') if item.options.max_retry_time is defined and item.options.max_retry_time -}}
{{ ('max-rsa-exponent-size ' + item.options.max_rsa_exponent_size | string +';\n') if item.options.max_rsa_exponent_size is defined and item.options.max_rsa_exponent_size -}}
{{ ('max-transfer-idle-in ' + item.options.max_transfer_idle_in | string +';\n') if item.options.max_transfer_idle_in is defined and item.options.max_transfer_idle_in -}}
{{ ('max-transfer-idle-out ' + item.options.max_transfer_idle_out | string +';\n') if item.options.max_transfer_idle_out is defined and item.options.max_transfer_idle_out -}}
{{ ('max-transfer-time-in ' + item.options.max_transfer_time_in | string +';\n') if item.options.max_transfer_time_in is defined and item.options.max_transfer_time_in -}}
{{ ('max-transfer-time-out ' + item.options.max_transfer_time_out | string +';\n') if item.options.max_transfer_time_out is defined and item.options.max_transfer_time_out -}}
{{ ('max-udp-size ' + item.options.max_udp_size | string +';\n') if item.options.max_udp_size is defined and item.options.max_udp_size -}}
{{ ('min-refresh-time ' + item.options.min_refresh_time | string +';\n') if item.options.min_refresh_time is defined and item.options.min_refresh_time -}}
{{ ('min-retry-time ' + item.options.min_retry_time | string +';\n') if item.options.min_retry_time is defined and item.options.min_retry_time -}}
{{ ('nocookie-udp-size ' + item.options.nocookie_udp_size | string +';\n') if item.options.nocookie_udp_size is defined and item.options.nocookie_udp_size -}}
{{ ('notify-delay ' + item.options.notify_delay | string +';\n') if item.options.notify_delay is defined and item.options.notify_delay -}}
{{ ('notify-rate ' + item.options.notify_rate | string +';\n') if item.options.notify_rate is defined and item.options.notify_rate -}}
{{ ('port ' + item.options.port | string +';\n') if item.options.port is defined and item.options.port -}}
{{ ('recursive-clients ' + item.options.recursive_clients | string +';\n') if item.options.recursive_clients is defined and item.options.recursive_clients -}}
{{ ('resolver-nonbackoff-tries ' + item.options.resolver_nonbackoff_tries | string +';\n') if item.options.resolver_nonbackoff_tries is defined and item.options.resolver_nonbackoff_tries -}}
{{ ('resolver-query-timeout ' + item.options.resolver_query_timeout | string +';\n') if item.options.resolver_query_timeout is defined and item.options.resolver_query_timeout -}}
{{ ('resolver-retry-interval ' + item.options.resolver_retry_interval | string +';\n') if item.options.resolver_retry_interval is defined and item.options.resolver_retry_interval -}}
{{ ('serial-query-rate ' + item.options.serial_query_rate | string +';\n') if item.options.serial_query_rate is defined and item.options.serial_query_rate -}}
{{ ('sig-signing-nodes ' + item.options.sig_signing_nodes | string +';\n') if item.options.sig_signing_nodes is defined and item.options.sig_signing_nodes -}}
{{ ('sig-signing-signatures ' + item.options.sig_signing_signatures | string +';\n') if item.options.sig_signing_signatures is defined and item.options.sig_signing_signatures -}}
{{ ('sig-signing-type ' + item.options.sig_signing_type | string +';\n') if item.options.sig_signing_type is defined and item.options.sig_signing_type -}}
{{ ('startup-notify-rate ' + item.options.startup_notify_rate | string +';\n') if item.options.startup_notify_rate is defined and item.options.startup_notify_rate -}}
{{ ('tcp-advertised-timeout ' + item.options.tcp_advertised_timeout | string +';\n') if item.options.tcp_advertised_timeout is defined and item.options.tcp_advertised_timeout -}}
{{ ('tcp-clients ' + item.options.tcp_clients | string +';\n') if item.options.tcp_clients is defined and item.options.tcp_clients -}}
{{ ('tcp-idle-timeout ' + item.options.tcp_idle_timeout | string +';\n') if item.options.tcp_idle_timeout is defined and item.options.tcp_idle_timeout -}}
{{ ('tcp-initial-timeout ' + item.options.tcp_initial_timeout | string +';\n') if item.options.tcp_initial_timeout is defined and item.options.tcp_initial_timeout -}}
{{ ('tcp-keepalive-timeout ' + item.options.tcp_keepalive_timeout | string +';\n') if item.options.tcp_keepalive_timeout is defined and item.options.tcp_keepalive_timeout -}}
{{ ('tcp-listen-queue ' + item.options.tcp_listen_queue | string +';\n') if item.options.tcp_listen_queue is defined and item.options.tcp_listen_queue -}}
{{ ('tcp-receive-buffer ' + item.options.tcp_receive_buffer | string +';\n') if item.options.tcp_receive_buffer is defined and item.options.tcp_receive_buffer -}}
{{ ('tcp-send-buffer ' + item.options.tcp_send_buffer | string +';\n') if item.options.tcp_send_buffer is defined and item.options.tcp_send_buffer -}}
{{ ('tls-port ' + item.options.tls_port | string +';\n') if item.options.tls_port is defined and item.options.tls_port -}}
{{ ('transfer-message-size ' + item.options.transfer_message_size | string +';\n') if item.options.transfer_message_size is defined and item.options.transfer_message_size -}}
{{ ('transfers-in ' + item.options.transfers_in | string +';\n') if item.options.transfers_in is defined and item.options.transfers_in -}}
{{ ('transfers-out ' + item.options.transfers_out | string +';\n') if item.options.transfers_out is defined and item.options.transfers_out -}}
{{ ('transfers-per-ns ' + item.options.transfers_per_ns | string +';\n') if item.options.transfers_per_ns is defined and item.options.transfers_per_ns -}}
{{ ('udp-receive-buffer ' + item.options.udp_receive_buffer | string +';\n') if item.options.udp_receive_buffer is defined and item.options.udp_receive_buffer -}}
{{ ('udp-send-buffer ' + item.options.udp_send_buffer | string +';\n') if item.options.udp_send_buffer is defined and item.options.udp_send_buffer -}}
{{ ('v6-bias ' + item.options.v6_bias | string +';\n') if item.options.v6_bias is defined and item.options.v6_bias -}}
{# Boolean options #}
{{ (functions.boolean_option('allow-new-zones', item.options.allow_new_zones) + '\n') if item.options.allow_new_zones is defined -}}
{{ (functions.boolean_option('answer-cookie', item.options.answer_cookie) + '\n') if item.options.answer_cookie is defined -}}
{{ (functions.boolean_option('auth-nxdomain', item.options.auth_nxdomain) + '\n') if item.options.auth_nxdomain is defined -}}
{{ (functions.boolean_option('automatic-interface-scan', item.options.automatic_interface_scan) + '\n') if item.options.automatic_interface_scan is defined -}}
{{ (functions.boolean_option('check-integrity', item.options.check_integrity) + '\n') if item.options.check_integrity is defined -}}
{{ (functions.boolean_option('check-sibling', item.options.check_sibling) + '\n') if item.options.check_sibling is defined -}}
{{ (functions.boolean_option('check-wildcard', item.options.check_wildcard) + '\n') if item.options.check_wildcard is defined -}}
{{ (functions.boolean_option('dnsrps-enable', item.options.dnsrps_enable) + '\n') if item.options.dnsrps_enable is defined -}}
{{ (functions.boolean_option('dnssec-accept-expired', item.options.dnssec_accept_expired) + '\n') if item.options.dnssec_accept_expired is defined -}}
{{ (functions.boolean_option('dnssec-dnskey-kskonly', item.options.dnssec_dnskey_kskonly) + '\n') if item.options.dnssec_dnskey_kskonly is defined -}}
{{ (functions.boolean_option('dnssec-secure-to-insecure', item.options.dnssec_secure_to_insecure) + '\n') if item.options.dnssec_secure_to_insecure is defined -}}
{{ (functions.boolean_option('empty-zones-enable', item.options.empty_zones_enable) + '\n') if item.options.empty_zones_enable is defined -}}
{{ (functions.boolean_option('flush-zones-on-shutdown', item.options.flush_zones_on_shutdown) + '\n') if item.options.flush_zones_on_shutdown is defined -}}
{{ (functions.boolean_option('glue-cache', item.options.glue_cache) + '\n') if item.options.glue_cache is defined -}}
{{ (functions.boolean_option('ipv4only-enable', item.options.ipv4only_enable) + '\n') if item.options.ipv4only_enable is defined -}}
{{ (functions.boolean_option('match-mapped-addresses', item.options.match_mapped_addresses) + '\n') if item.options.match_mapped_addresses is defined -}}
{{ (functions.boolean_option('memstatistics', item.options.memstatistics) + '\n') if item.options.memstatistics is defined -}}
{{ (functions.boolean_option('message-compression', item.options.message_compression) + '\n') if item.options.message_compression is defined -}}
{{ (functions.boolean_option('minimal-any', item.options.minimal_any) + '\n') if item.options.minimal_any is defined -}}
{{ (functions.boolean_option('multi-master', item.options.multi_master) + '\n') if item.options.multi_master is defined -}}
{{ (functions.boolean_option('notify-to-soa', item.options.notify_to_soa) + '\n') if item.options.notify_to_soa is defined -}}
{{ (functions.boolean_option('provide-ixfr', item.options.provide_ixfr) + '\n') if item.options.provide_ixfr is defined -}}
{{ (functions.boolean_option('querylog', item.options.querylog) + '\n') if item.options.querylog is defined -}}
{{ (functions.boolean_option('recursion', item.options.recursion) + '\n') if item.options.recursion is defined -}}
{{ (functions.boolean_option('request-expire', item.options.request_expire) + '\n') if item.options.request_expire is defined -}}
{{ (functions.boolean_option('request-ixfr', item.options.request_ixfr) + '\n') if item.options.request_ixfr is defined -}}
{{ (functions.boolean_option('request-nsid', item.options.request_nsid) + '\n') if item.options.request_nsid is defined -}}
{{ (functions.boolean_option('require-server-cookie', item.options.require_server_cookie) + '\n') if item.options.require_server_cookie is defined -}}
{{ (functions.boolean_option('reuseport', item.options.reuseport) + '\n') if item.options.reuseport is defined -}}
{{ (functions.boolean_option('root-key-sentinel', item.options.root_key_sentinel) + '\n') if item.options.root_key_sentinel is defined -}}
{{ (functions.boolean_option('send-cookie', item.options.send_cookie) + '\n') if item.options.send_cookie is defined -}}
{{ (functions.boolean_option('stale-answer-enable', item.options.stale_answer_enable) + '\n') if item.options.stale_answer_enable is defined -}}
{{ (functions.boolean_option('stale-cache-enable', item.options.stale_cache_enable) + '\n') if item.options.stale_cache_enable is defined -}}
{{ (functions.boolean_option('synth-from-dnssec', item.options.synth_from_dnssec) + '\n') if item.options.synth_from_dnssec is defined -}}
{{ (functions.boolean_option('trust-anchor-telemetry', item.options.trust_anchor_telemetry) + '\n') if item.options.trust_anchor_telemetry is defined -}}
{{ (functions.boolean_option('try-tcp-refresh', item.options.try_tcp_refresh) + '\n') if item.options.try_tcp_refresh is defined -}}
{{ (functions.boolean_option('update-check-ksk', item.options.update_check_ksk) + '\n') if item.options.update_check_ksk is defined -}}
{{ (functions.boolean_option('use-alt-transfer-source', item.options.use_alt_transfer_source) + '\n') if item.options.use_alt_transfer_source is defined -}}
{{ (functions.boolean_option('zero-no-soa-ttl', item.options.zero_no_soa_ttl) + '\n') if item.options.zero_no_soa_ttl is defined -}}
{{ (functions.boolean_option('zero-no-soa-ttl-cache', item.options.zero_no_soa_ttl_cache) + '\n') if item.options.zero_no_soa_ttl_cache is defined -}}
{% endfilter %} {% endfilter %}
}; };

View File

@@ -0,0 +1,20 @@
{% for server in item.remote_servers %}
remote-servers "{{ server.name }}" {
{% filter indent(bind9_config_indent, true) %}
{% for key, value in server.items() %}
{% if key != 'name' %}
{# Handle known complex types if any, otherwise default to simple string/block #}
{% if value is iterable and value is not string and value is not mapping %}
{{ key }} {
{% for subitem in value %}
{{ subitem }};
{% endfor %}
};
{% else %}
{{ key }} {{ value }};
{% endif %}
{% endif %}
{% endfor %}
{% endfilter %}
};
{% endfor %}

View File

@@ -2,29 +2,20 @@
zone "{{ zone.name }}" { zone "{{ zone.name }}" {
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
# Zone {{ zone.name }} type {{ zone.type }} {% for key, value in zone.items() %}
{# Most critical/defining statements first #} {% set conf_key = key | replace('_', '-') %}
{{ ('type ' + zone.type | string+';\n') if zone.type is defined and zone.type -}}
{{ ('file "' + zone.file | string+'";\n') if zone.file is defined and zone.file -}} {% if key == 'name' %}
{{ ('forward ' + zone.forward | string+';\n') if zone.forward is defined and zone.forward -}} {# Skip name as it is in the zone header #}
{{ ('journal "' + zone.journal | string+'";\n') if zone.journal is defined and zone.journal -}}
{{ ('key-directory "' + zone.key_directory | string+'";\n') if zone.key_directory is defined and zone.key_directory -}} {# --- COMPLEX BLOCKS --- #}
{# boolean_or_string options #} {% elif key == 'update_policy' %}
{{ ('dialup ' + functions.boolean_or_string(zone.dialup) + ';\n') if zone.dialup is defined -}} {% if value == 'local' %}
{{ ('notify ' + functions.boolean_or_string(zone.notify) + ';\n') if zone.notify is defined -}}
{{ ('zone-statistics ' + functions.boolean_or_string(zone.zone_statistics) + ';\n') if zone.zone_statistics is defined -}}
{# upstream_servers options #}
{{ functions.parent_address_key_tls('also-notify', zone.also_notify) if zone.also_notify is defined and zone.also_notify -}}
{{ functions.parent_address_key_tls('primaries', zone.primaries) if zone.primaries is defined and zone.primaries -}}
{{ functions.parent_address_key_tls('parental-agents', zone.parental_agents) if zone.parental_agents is defined and zone.parental_agents -}}
{# Unicorn Options#}
{% if zone.update_policy is defined and zone.update_policy %}
{% if zone.update_policy == 'local' %}
update-policy local; update-policy local;
{% else %} {% else %}
update-policy { update-policy {
{% filter indent(bind9_config_indent, true) %} {% filter indent(bind9_config_indent, true) %}
{% for policy in zone.update_policy %} {% for policy in value %}
{{ policy.permission -}} {{ policy.permission -}}
{{ ' ' + policy.identity -}} {{ ' ' + policy.identity -}}
{{ ' ' + policy.ruletype -}} {{ ' ' + policy.ruletype -}}
@@ -33,127 +24,61 @@ update-policy {
{% endfor %} {% endfor %}
{% endfilter %}}; {% endfilter %}};
{% endif %} {% endif %}
{% endif %}
{% if zone.sig_validity_interval is defined and zone.sig_validity_interval %} {% elif key == 'sig_validity_interval' %}
sig-validity-interval sig-validity-interval
{{- (' ' + zone.sig_validity_interval.upper | string) }} {{- (' ' + value.upper | string) }}
{{- (' ' + zone.sig_validity_interval.lower | string) if zone.sig_validity_interval.lower is defined and zone.sig_validity_interval.lower -}}; {{- (' ' + value.lower | string) if value.lower is defined and value.lower -}};
{% endif %}
{% if zone.server_names is defined and zone.server_names %} {% elif key in ['server_names', 'server_addresses'] %}
server-names { {{ conf_key }} {
{{ functions.simple_item_list(zone.server_names) }}}; {{ functions.simple_item_list(value) }}};
{% endif %}
{% if zone.server_addresses is defined and zone.server_addresses %} {% elif key in ['also_notify', 'primaries', 'parental_agents'] %}
server-addresses { {{ functions.parent_address_key_tls(conf_key, value) -}}
{{ functions.simple_item_list(zone.server_addresses) }}};
{% endif %} {% elif key == 'forwarders' %}
{{ functions.parent_address_port_tls('forwarders', zone.forwarders) if zone.forwarders is defined and zone.forwarders -}} {{ functions.parent_address_port_dscp('forwarders', value) -}}
{% if zone.allow_transfer is defined and zone.allow_transfer is not string %}
{% elif key == 'allow_transfer' and value is not string and value is mapping %}
allow-transfer allow-transfer
{{- (' port ' + zone.allow_transfer.port | string) if zone.allow_transfer.port is defined and zone.allow_transfer.port -}} {{- (' port ' + value.port | string) if value.port is defined and value.port -}}
{{- (' transport ' + zone.allow_transfer.transport) if zone.allow_transfer.transport is defined and zone.allow_transfer.transport }} { {{- (' transport ' + value.transport) if value.transport is defined and value.transport }} {
{{ functions.simple_item_list(zone.allow_transfer.addresses) }}}; {{ functions.simple_item_list(value.addresses) }}};
{% elif key in ['transfer_source', 'transfer_source_v6', 'alt_transfer_source', 'alt_transfer_source_v6', 'notify_source', 'notify_source_v6', 'parental_source', 'parental_source_v6'] %}
{{ conf_key }} {{ value.address -}}
{{- (' port ' + value.port | string) if value.port is defined and value.port -}}
{{- (' dscp ' + value.dscp | string) if value.dscp is defined and value.dscp }};
{# --- SIMPLE LISTS --- #}
{% elif key in ['allow_notify', 'allow_query', 'allow_query_on', 'allow_update', 'allow_update_forwarding'] %}
{{ conf_key }} {
{{ functions.simple_item_list(value) }}};
{# --- BOOLEANS --- #}
{% elif key in ['check_integrity', 'check_sibling', 'check_wildcard', 'delegation_only', 'dnssec_dnskey_kskonly', 'dnssec_secure_to_insecure', 'inline_signing', 'ixfr_from_differences', 'multi_master', 'notify_to_soa', 'request_expire', 'request_ixfr', 'try_tcp_refresh', 'update_check_ksk', 'use_alt_transfer_source', 'zero_no_soa_ttl'] %}
{{ (functions.boolean_option(conf_key, value)) }}
{# --- BOOLEAN OR STRING --- #}
{% elif key in ['dialup', 'notify', 'zone_statistics'] %}
{{ conf_key }} {{ functions.boolean_or_string(value) }};
{# --- QUOTED STRINGS --- #}
{% elif key in ['file', 'journal', 'key_directory'] %}
{{ conf_key }} "{{ value }}";
{# --- DEPRECATED --- #}
{% elif key == 'auto_dnssec' %}
/* WARN: auto-dnssec is removed in BIND 9.20 */
{{ conf_key }} {{ value }};
{# --- FALLTHROUGH --- #}
{% else %}
{# Strict mode: Ignore unknown keys #}
{% endif %} {% endif %}
{# simple_list options #}
{{ ('allow-notify {\n' + functions.simple_item_list(zone.allow_notify) + '};\n') if zone.allow_notify is defined and zone.allow_notify -}} {% endfor %}
{{ ('allow-query {\n' + functions.simple_item_list(zone.allow_query) + '};\n') if zone.allow_query is defined and zone.allow_query -}}
{{ ('allow-query-on {\n' + functions.simple_item_list(zone.allow_query_on) + '};\n') if zone.allow_query_on is defined and zone.allow_query_on -}}
{{ ('allow-update {\n' + functions.simple_item_list(zone.allow_update) + '};\n') if zone.allow_update is defined and zone.allow_update -}}
{{ ('allow-update-forwarding {\n' + functions.simple_item_list(zone.allow_update_forwarding) + '};\n') if zone.allow_update_forwarding is defined and zone.allow_update_forwarding -}}
{# ip_port_dscp options#}
{% if zone.transfer_source is defined and zone.transfer_source is mapping %}
transfer-source {{ zone.transfer_source.address -}}
{{- (' port ' + zone.transfer_source.port | string) if zone.transfer_source.port is defined and zone.transfer_source.port -}}
{{- (' dscp ' + zone.transfer_source.dscp | string) if zone.transfer_source.dscp is defined and zone.transfer_source.dscp }};
{% endif %}
{% if zone.transfer_source_v6 is defined and zone.transfer_source_v6 is mapping %}
transfer-source-v6 {{ zone.transfer_source_v6.address -}}
{{- (' port ' + zone.transfer_source_v6.port | string) if zone.transfer_source_v6.port is defined and zone.transfer_source_v6.port -}}
{{- (' dscp ' + zone.transfer_source_v6.dscp | string) if zone.transfer_source_v6.dscp is defined and zone.transfer_source_v6.dscp }};
{% endif %}
{% if zone.alt_transfer_source is defined and zone.alt_transfer_source is mapping %}
alt-transfer-source {{ zone.alt_transfer_source.address -}}
{{- (' port ' + zone.alt_transfer_source.port | string) if zone.alt_transfer_source.port is defined and zone.alt_transfer_source.port -}}
{{- (' dscp ' + zone.alt_transfer_source.dscp | string) if zone.alt_transfer_source.dscp is defined and zone.alt_transfer_source.dscp }};
{% endif %}
{% if zone.alt_transfer_source_v6 is defined and zone.alt_transfer_source_v6 is mapping %}
alt-transfer-source-v6 {{ zone.alt_transfer_source_v6.address -}}
{{- (' port ' + zone.alt_transfer_source_v6.port | string) if zone.alt_transfer_source_v6.port is defined and zone.alt_transfer_source_v6.port -}}
{{- (' dscp ' + zone.alt_transfer_source_v6.dscp | string) if zone.alt_transfer_source_v6.dscp is defined and zone.alt_transfer_source_v6.dscp }};
{% endif %}
{% if zone.notify_source is defined and zone.notify_source is mapping %}
notify-source {{ zone.notify_source.address -}}
{{- (' port ' + zone.notify_source.port | string) if zone.notify_source.port is defined and zone.notify_source.port -}}
{{- (' dscp ' + zone.notify_source.dscp | string) if zone.notify_source.dscp is defined and zone.notify_source.dscp }};
{% endif %}
{% if zone.notify_source_v6 is defined and zone.notify_source_v6 is mapping %}
notify-source-v6 {{ zone.notify_source_v6.address -}}
{{- (' port ' + zone.notify_source_v6.port | string) if zone.notify_source_v6.port is defined and zone.notify_source_v6.port -}}
{{- (' dscp ' + zone.notify_source_v6.dscp | string) if zone.notify_source_v6.dscp is defined and zone.notify_source_v6.dscp }};
{% endif %}
{% if zone.parental_source is defined and zone.parental_source is mapping %}
parental-source {{ zone.parental_source.address -}}
{{- (' port ' + zone.parental_source.port | string) if zone.parental_source.port is defined and zone.parental_source.port -}}
{{- (' dscp ' + zone.parental_source.dscp | string) if zone.parental_source.dscp is defined and zone.parental_source.dscp }};
{% endif %}
{% if zone.parental_source_v6 is defined and zone.parental_source_v6 is mapping %}
parental-source-v6 {{ zone.parental_source_v6.address -}}
{{- (' port ' + zone.parental_source_v6.port | string) if zone.parental_source_v6.port is defined and zone.parental_source_v6.port -}}
{{- (' dscp ' + zone.parental_source_v6.dscp | string) if zone.parental_source_v6.dscp is defined and zone.parental_source_v6.dscp }};
{% endif %}
{# integer options #}
{{ ('dnskey-sig-validity ' + zone.dnskey_sig_validity | string+';\n') if zone.dnskey_sig_validity is defined and zone.dnskey_sig_validity -}}
{{ ('dnssec-loadkeys-interval ' + zone.dnssec_loadkeys_interval | string+';\n') if zone.dnssec_loadkeys_interval is defined and zone.dnssec_loadkeys_interval -}}
{{ ('max-records ' + zone.max_records | string+';\n') if zone.max_records is defined and zone.max_records -}}
{{ ('max-refresh-time ' + zone.max_refresh_time | string+';\n') if zone.max_refresh_time is defined and zone.max_refresh_time -}}
{{ ('max-retry-time ' + zone.max_retry_time | string+';\n') if zone.max_retry_time is defined and zone.max_retry_time -}}
{{ ('max-transfer-idle-in ' + zone.max_transfer_idle_in | string+';\n') if zone.max_transfer_idle_in is defined and zone.max_transfer_idle_in -}}
{{ ('max-transfer-idle-out ' + zone.max_transfer_idle_out | string+';\n') if zone.max_transfer_idle_out is defined and zone.max_transfer_idle_out -}}
{{ ('max-transfer-time-in ' + zone.max_transfer_time_in | string+';\n') if zone.max_transfer_time_in is defined and zone.max_transfer_time_in -}}
{{ ('max-transfer-time-out ' + zone.max_transfer_time_out | string+';\n') if zone.max_transfer_time_out is defined and zone.max_transfer_time_out -}}
{{ ('min-refresh-time ' + zone.min_refresh_time | string+';\n') if zone.min_refresh_time is defined and zone.min_refresh_time -}}
{{ ('min-retry-time ' + zone.min_retry_time | string+';\n') if zone.min_retry_time is defined and zone.min_retry_time -}}
{{ ('notify-delay ' + zone.notify_delay | string+';\n') if zone.notify_delay is defined and zone.notify_delay -}}
{{ ('sig-signing-nodes ' + zone.sig_signing_nodes | string+';\n') if zone.sig_signing_nodes is defined and zone.sig_signing_nodes -}}
{{ ('sig-signing-signatures ' + zone.sig_signing_signatures | string+';\n') if zone.sig_signing_signatures is defined and zone.sig_signing_signatures -}}
{{ ('sig-signing-type ' + zone.sig_signing_type | string+';\n') if zone.sig_signing_type is defined and zone.sig_signing_type -}}
{# boolean options #}
{{ (functions.boolean_option('check-integrity', zone.check_integrity) + '\n') if zone.check_integrity is defined -}}
{{ (functions.boolean_option('check-sibling', zone.check_sibling) + '\n') if zone.check_sibling is defined -}}
{{ (functions.boolean_option('check-wildcard', zone.check_wildcard) + '\n') if zone.check_wildcard is defined -}}
{{ (functions.boolean_option('delegation-only', zone.delegation_only) + '\n') if zone.delegation_only is defined -}}
{{ (functions.boolean_option('dnssec-dnskey-kskonly', zone.dnssec_dnskey_kskonly) + '\n') if zone.dnssec_dnskey_kskonly is defined -}}
{{ (functions.boolean_option('dnssec-secure-to-insecure', zone.dnssec_secure_to_insecure) + '\n') if zone.dnssec_secure_to_insecure is defined -}}
{{ (functions.boolean_option('inline-signing', zone.inline_signing) + '\n') if zone.inline_signing is defined -}}
{{ (functions.boolean_option('ixfr-from-differences', zone.ixfr_from_differences) + '\n') if zone.ixfr_from_differences is defined -}}
{{ (functions.boolean_option('multi-master', zone.multi_master) + '\n') if zone.multi_master is defined -}}
{{ (functions.boolean_option('notify-to-soa', zone.notify_to_soa) + '\n') if zone.notify_to_soa is defined -}}
{{ (functions.boolean_option('request-expire', zone.request_expire) + '\n') if zone.request_expire is defined -}}
{{ (functions.boolean_option('request-ixfr', zone.request_ixfr) + '\n') if zone.request_ixfr is defined -}}
{{ (functions.boolean_option('try-tcp-refresh', zone.try_tcp_refresh) + '\n') if zone.try_tcp_refresh is defined -}}
{{ (functions.boolean_option('update-check-ksk', zone.update_check_ksk) + '\n') if zone.update_check_ksk is defined -}}
{{ (functions.boolean_option('use-alt-transfer-source', zone.use_alt_transfer_source) + '\n') if zone.use_alt_transfer_source is defined -}}
{{ (functions.boolean_option('zero-no-soa-ttl', zone.zero_no_soa_ttl) + '\n') if zone.zero_no_soa_ttl is defined -}}
{# multiple_choice options #}
{{ ('auto-dnssec ' + zone.auto_dnssec | string+';\n') if zone.auto_dnssec is defined and zone.auto_dnssec -}}
{{ ('check-dup-records ' + zone.check_dup_records | string+';\n') if zone.check_dup_records is defined and zone.check_dup_records -}}
{{ ('check-mx-cname ' + zone.check_mx_cname | string+';\n') if zone.check_mx_cname is defined and zone.check_mx_cname -}}
{{ ('check-mx ' + zone.check_mx | string+';\n') if zone.check_mx is defined and zone.check_mx -}}
{{ ('check-names ' + zone.check_names | string+';\n') if zone.check_names is defined and zone.check_names -}}
{{ ('check-spf ' + zone.check_spf | string+';\n') if zone.check_spf is defined and zone.check_spf -}}
{{ ('check-srv-cname ' + zone.check_srv_cname | string+';\n') if zone.check_srv_cname is defined and zone.check_srv_cname -}}
{{ ('dnssec-update-mode ' + zone.dnssec_update_mode | string+';\n') if zone.dnssec_update_mode is defined and zone.dnssec_update_mode -}}
{{ ('masterfile-format ' + zone.masterfile_format | string+';\n') if zone.masterfile_format is defined and zone.masterfile_format -}}
{{ ('masterfile-style ' + zone.masterfile_style | string+';\n') if zone.masterfile_style is defined and zone.masterfile_style -}}
{{ ('max-ixfr-ratio ' + zone.max_ixfr_ratio | string+';\n') if zone.max_ixfr_ratio is defined and zone.max_ixfr_ratio -}}
{{ ('max-journal-size ' + zone.max_journal_size | string+';\n') if zone.max_journal_size is defined and zone.max_journal_size -}}
{{ ('max-zone-ttl ' + zone.max_zone_ttl | string+';\n') if zone.max_zone_ttl is defined and zone.max_zone_ttl -}}
{{ ('serial-update-method ' + zone.serial_update_method | string+';\n') if zone.serial_update_method is defined and zone.serial_update_method -}}
{# string options #}
{{ ('database ' + zone.database | string+';\n') if zone.database is defined and zone.database -}}
{{ ('dlz ' + zone.dlz | string+';\n') if zone.dlz is defined and zone.dlz -}}
{{ ('dnssec-policy ' + zone.dnssec_policy | string+';\n') if zone.dnssec_policy is defined and zone.dnssec_policy -}}
{{ ('in-view ' + zone.in_view | string+';\n') if zone.in_view is defined and zone.in_view -}}
{% endfilter %} {% endfilter %}
}; };
{% endfor %} {% endfor %}

View File

@@ -2,4 +2,4 @@
- hosts: localhost - hosts: localhost
remote_user: root remote_user: root
roles: roles:
- bind9 # noqa: syntax-check[specific] - bind9