fe5fbdaf6d
Implements a Kubernetes operator that manages fleets of BIND9 servers declaratively, using controller-runtime (matching forgebot conventions). - add BindCluster reconciler: StatefulSet (pod-0 primary, secondaries), headless + client Services, rendered named.conf ConfigMap, TSIG keys Secret and rndc control Secret; watches dependent CRs to re-render - add BindTSIGKey reconciler that generates key material into a Secret - add BindZone/DNSRecord reconcilers using fully-dynamic delivery (rndc addzone + TSIG nsupdate against the primary pod) - add BindCatalogZone reconciler so secondaries auto-provision zones - add BindPolicy (RPZ), BindDNSSECPolicy, BindView, BindACL reconcilers - render primary/secondary named.conf variants selected by pod ordinal - generate CRDs, deepcopy and RBAC; add samples mapping the three Puppet roles (authoritative/resolver/external-dns) to three BindClusters - add Makefile, Dockerfile.operator, Woodpecker CI and kind manifests
30 lines
841 B
Go
30 lines
841 B
Go
package bind
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"encoding/hex"
|
|
"strings"
|
|
)
|
|
|
|
// catalogHash returns the unique member label for a catalog zone entry: the
|
|
// hex-encoded SHA-1 digest of the member zone name in DNS wire format, per the
|
|
// BIND catalog-zone schema (RFC 9432).
|
|
func catalogHash(zone string) string {
|
|
sum := sha1.Sum(wireName(zone))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
// wireName encodes a domain name into uncompressed DNS wire format: each label
|
|
// length-prefixed, terminated by a zero-length root label. Names are lowercased.
|
|
func wireName(name string) []byte {
|
|
name = strings.TrimSuffix(strings.ToLower(strings.TrimSpace(name)), ".")
|
|
var out []byte
|
|
if name != "" {
|
|
for _, label := range strings.Split(name, ".") {
|
|
out = append(out, byte(len(label)))
|
|
out = append(out, []byte(label)...)
|
|
}
|
|
}
|
|
return append(out, 0)
|
|
}
|