Options of a block (server options, a view, a zone) are listed and
written grouped by topic, alphabetical within a group, so the same
option is in the same place everywhere. Top-level statements keep the
order they were added in.
named.conf diffs add the enclosing blocks to each hunk header, like
git's function context: @@ -50,6 +49,8 @@ view "internal" {.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
56 lines
2.6 KiB
Go
56 lines
2.6 KiB
Go
package model
|
|
|
|
// optionGroups orders the options of a block (options, a view, a zone) the
|
|
// same way everywhere: in named.conf, the web UI and the CLI. Related
|
|
// options are grouped; within a group they are alphabetical, and options
|
|
// not listed here come last, alphabetically. named doesn't care about the
|
|
// order of options in a block.
|
|
var optionGroups = [][]string{
|
|
// Files and identity.
|
|
{"bindkeys-file", "directory", "dump-file", "hostname", "managed-keys-directory", "memstatistics-file", "pid-file", "recursing-file", "secroots-file", "server-id", "session-keyfile", "statistics-file", "version"},
|
|
// Listening and source addresses.
|
|
{"listen-on", "listen-on-v6", "notify-source", "notify-source-v6", "query-source", "query-source-v6", "transfer-source", "transfer-source-v6"},
|
|
// Access control.
|
|
{"allow-query", "allow-query-cache", "allow-query-cache-on", "allow-query-on", "allow-recursion", "allow-recursion-on", "allow-update", "allow-update-forwarding", "blackhole", "deny-answer-addresses", "deny-answer-aliases", "update-policy"},
|
|
// Recursion, forwarding and the cache.
|
|
{"forward", "forwarders", "max-cache-size", "max-cache-ttl", "max-ncache-ttl", "minimal-responses", "prefetch", "qname-minimization", "rate-limit", "recursion", "response-policy", "serve-stale", "stale-answer-enable", "stale-answer-ttl", "stale-cache-enable"},
|
|
// DNSSEC.
|
|
{"dnssec-accept-expired", "dnssec-must-be-secure", "dnssec-policy", "dnssec-validation", "inline-signing", "key-directory", "trust-anchor-telemetry", "validate-except"},
|
|
// Transfers and notify.
|
|
{"allow-notify", "allow-transfer", "also-notify", "catalog-zones", "ixfr-from-differences", "masters", "max-transfer-idle-in", "max-transfer-idle-out", "max-transfer-time-in", "max-transfer-time-out", "notify", "notify-to-soa", "primaries", "provide-ixfr", "request-ixfr", "serial-query-rate", "transfer-format", "transfers-in", "transfers-out", "transfers-per-ns"},
|
|
}
|
|
|
|
var optionGroup = func() map[string]int {
|
|
m := map[string]int{}
|
|
for i, g := range optionGroups {
|
|
for _, n := range g {
|
|
m[n] = i
|
|
}
|
|
}
|
|
return m
|
|
}()
|
|
|
|
// optionLess orders two options of the same block: by group, then name,
|
|
// then (for an option given more than once, like listen-on) the order they
|
|
// were added in.
|
|
func optionLess(a, b *Option) bool {
|
|
ga, ok := optionGroup[a.Name]
|
|
if !ok {
|
|
ga = len(optionGroups)
|
|
}
|
|
gb, ok := optionGroup[b.Name]
|
|
if !ok {
|
|
gb = len(optionGroups)
|
|
}
|
|
if ga != gb {
|
|
return ga < gb
|
|
}
|
|
if a.Name != b.Name {
|
|
return a.Name < b.Name
|
|
}
|
|
if a.Position != b.Position {
|
|
return a.Position < b.Position
|
|
}
|
|
return a.ID < b.ID
|
|
}
|