88fcb97ad1
Replaces the exported-resources → puppet DNS master zone-file flow with per-host RFC2136 dynamic updates against the k8s **bind-authoritative** write endpoint (198.18.200.9). The master no longer manages zone files. ## Design Each node assembles its DNS records into a local concat file; a systemd `.path` unit watches it and runs `dns-update` (nsupdate) on change — exactly the watch-a-file model requested. ## Changes - **profiles::dns::updater** (new): concat records file + TSIG key file + `dns-update` script + `dns-update.service` (oneshot) + `dns-update.path` (watcher). The script sends only the delta since last run and deletes removed records, grouped per zone. - **profiles::dns::record**: writes a local concat fragment (`zone|name|type|ttl|value`) instead of exporting `@@concat::fragment` to the master. - **profiles::dns::base**: includes `profiles::dns::updater` (all nodes). - **hiera**: `profiles::dns::updater` server/key_name/algorithm in common.yaml. ## Inert until keyed The updater does nothing until `profiles::dns::updater::key_secret` (TSIG) is set in eyaml — records are assembled but not applied, so nodes are safe before the key exists. ## Prerequisites (k8s side, separate) 1. The `bind-authoritative` zones must set `dynamicUpdate: true` + an `updateKeyRef` (a client-update BindTSIGKey) so they accept these updates. 2. The TSIG key must be shared: the operator-generated key value goes into eyaml here (or the planned Vault-sync feature bridges it). ## Validated puppet parser/epp validate, puppet-lint, and a functional test of the generated per-zone nsupdate message (replace + delete-removed). Reviewed-on: #475 Co-authored-by: Ben Vincent <ben@unkin.net> Co-committed-by: Ben Vincent <ben@unkin.net>
45 lines
1.3 KiB
Puppet
45 lines
1.3 KiB
Puppet
# profiles::dns::record
|
|
#
|
|
# Declares a DNS record for this host. Publishes it via either or both methods,
|
|
# controlled by profiles::dns::updater's toggles (both on during cutover):
|
|
# - nsupdate: a local concat fragment consumed by profiles::dns::updater,
|
|
# which nsupdates it to the authoritative server.
|
|
# - export: the legacy @@concat::fragment exported to the puppet DNS master.
|
|
define profiles::dns::record (
|
|
String $record,
|
|
Enum[
|
|
'PTR',
|
|
'A',
|
|
'CNAME',
|
|
'MX',
|
|
'NS',
|
|
'SRV',
|
|
'TXT'
|
|
] $type,
|
|
String $value,
|
|
String $zone,
|
|
Integer $order,
|
|
Integer $ttl = 300,
|
|
) {
|
|
include profiles::dns::updater
|
|
|
|
# new: local records file consumed by the nsupdate service
|
|
if $profiles::dns::updater::manage_nsupdate {
|
|
# zone|name|type|ttl|value (parsed by the dns-update script)
|
|
concat::fragment { "dns-record-${name}":
|
|
target => $profiles::dns::updater::records_file,
|
|
content => "${zone}|${record}|${type}|${ttl}|${value}\n",
|
|
order => sprintf('%03d', $order),
|
|
}
|
|
}
|
|
|
|
# legacy: export the fragment to the puppet DNS master
|
|
if $profiles::dns::updater::manage_export {
|
|
@@concat::fragment { "${zone}_${name}":
|
|
target => "${profiles::dns::updater::master_basedir}/${zone}.conf",
|
|
content => "${record} IN ${type} ${value}\n",
|
|
order => $order,
|
|
}
|
|
}
|
|
}
|