You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+30Lines changed: 30 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,35 @@
1
1
# Changelog
2
2
3
+
## 0.8.0 (2026-04-26)
4
+
5
+
### Added — Dynamic DNS (DDNS) support for Kea 3.0+
6
+
Models the full `kea-dhcp-ddns` (D2) configuration surface and the per-server / per-subnet / per-class `ddns-*` knobs that `kea-dhcp4`/`kea-dhcp6` can render. Gated behind the `enable_ddns` plugin setting (which requires `enable_netbox_dns=True` — TSIG keys are plugin-local but zones and nameservers come from `netbox-plugin-dns`).
7
+
8
+
-**New models**
9
+
-`TSIGKey` — RFC 2845 keys with algorithm choices, optional digest-bits truncation, and a pluggable `secret_backend` registry (v1 ships `plaintext`; `vault` reserved for future). Secret values are auto-generated on save when input is empty or not algorithm-length base64 — paste `tsig-keygen` output verbatim or just save and let the plugin mint one. Plaintext reveal is gated by a dedicated `view_secret_tsigkey` permission.
10
+
-`D2Daemon` — one row per logical D2 service. `listener_mode` chooses between `local` (renders `127.0.0.1`; deploy one D2 instance per peer for HA-pair DDNS redundancy) and `remote` (single shared instance pinned to an IPAM record). Includes NCR transport, control-socket path (defaults from `d2_default_control_socket_path` plugin setting), and a per-daemon `/api/.../d2-daemons/<id>/kea-config/` endpoint that emits a complete `kea-dhcp-ddns.conf`.
11
+
-`DDNSDomain` — binds a `D2Daemon` to a `netbox_dns.Zone`. Forward/reverse direction is derived from the zone name at emission time. Authoritative nameserver IPs are resolved from the zone's `NameServer` records (A/AAAA/CNAME chain) at config-emit time. Create form is multi-zone — pick any combination of forward and reverse zones in one shot.
12
+
-`DDNSPolicy` — reusable `ddns-*` override group (`ddns-send-updates`, `ddns-override-no-update`, `ddns-replace-client-name`, `ddns-generated-prefix`/`-qualifying-suffix`, `hostname-char-set`/`-replacement`, conflict-resolution mode, TTL knobs). All fields nullable — `to_kea_overrides()` emits only the keys the operator set, kebab-cased.
13
+
14
+
-**Existing model changes** (all nullable FKs, `on_delete=SET_NULL`)
-**HA-pair precedence** — `DHCPServer.effective_d2_daemon` and `effective_ddns_policy` properties: when the server's HA relationship has a value set, that wins (peers must agree on the D2 target and the `ddns-*` policy). Sender IP/port stay per-server (the local source endpoint is always per-host). The DHCPServer detail page shows the effective values with an "inherited from HA relationship" badge.
21
+
22
+
-**Kea config emission** — no Python-side merging of override hierarchies. Each non-null `DDNSPolicy.to_kea_overrides()` is emitted verbatim at the JSON level the policy is attached to (server-level → `Dhcp4`/`Dhcp6` root, subnet-level → subnet dict, class-level → client-class dict). Kea resolves the precedence chain itself when processing packets.
23
+
24
+
-**Bulk edit** — `DDNSDomain` got a bulk-edit view + form so you can set `d2_daemon` / `tsig_key` on many rows at once.
25
+
26
+
-**Quick-add** — `tsig_key` field on `DDNSDomain` form has the `+` quick-add button so a new TSIG key can be created inline without leaving the form.
27
+
28
+
### Plugin settings
29
+
-`enable_ddns` (default `False`) — master switch; nav, URLs, API routes, form fields, and serializer fields are all gated by it.
30
+
-`ddns_secret_backend` (default `"plaintext"`) — backend identifier for `TSIGKey.get_secret()`.
31
+
-`d2_default_control_socket_path` (default `"/tmp/kea-dhcp-ddns-ctrl.sock"`) — pre-fills the control socket field on new `D2Daemon` rows.
Copy file name to clipboardExpand all lines: README.md
+21Lines changed: 21 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,6 +31,7 @@ This plugin bridges the gap between NetBox IPAM and ISC KEA DHCP server configur
31
31
-**HA Relationships**: Configure High Availability relationships between DHCP servers
32
32
-**Stork Servers**: Manage ISC Stork monitoring server instances
33
33
-**Stork Agent Groups**: Configure Stork agent groups that link DHCP servers to a Stork monitoring server
34
+
-**TSIG Keys, D2 Daemons, DDNS Domains, DDNS Policies**: Optional Kea 3.0+ Dynamic DNS modelling (see [Dynamic DNS (DDNS)](#dynamic-dns-ddns))
34
35
35
36
### Stork Monitoring Integration
36
37
@@ -42,6 +43,26 @@ This plugin bridges the gap between NetBox IPAM and ISC KEA DHCP server configur
42
43
- Stork features are fully optional — disable with `enable_stork: False` in plugin settings
43
44
- API endpoints support `Accept: text/plain` for easy integration with Ansible `uri` module
44
45
46
+
### Dynamic DNS (DDNS)
47
+
48
+
Optional Kea 3.0+ Dynamic DNS support — model `kea-dhcp-ddns` (D2) instances, TSIG keys, forward/reverse zones, and the `ddns-*` policy knobs that `kea-dhcp4`/`kea-dhcp6` render at server / subnet / client-class scope.
49
+
50
+
DDNS support is **disabled by default** and requires `enable_netbox_dns: True` (zones and nameservers are sourced from [`netbox-plugin-dns`](https://github.com/peteeckel/netbox-plugin-dns); TSIG keys are plugin-local). Enable with `enable_ddns: True` in `PLUGINS_CONFIG` (see [Configuration](#configuration)) — when off, the navigation entries, URLs, API routes, and form fields are all hidden.
51
+
52
+
-**Models**
53
+
-`TSIGKey` — RFC 2845 keys with algorithm choices (`HMAC-MD5`/`SHA1`/`SHA224`/`SHA256`/`SHA384`/`SHA512`), optional digest-bits truncation, and a pluggable `secret_backend` registry (v1 ships `plaintext`; `vault` reserved). Secret values are auto-generated on save when input is empty or not algorithm-length base64 — you can paste `tsig-keygen` output verbatim or just save and let the plugin mint a fresh one. Plaintext reveal is gated by a dedicated `view_secret_tsigkey` permission.
54
+
-`D2Daemon` — one row per logical D2 service. `listener_mode` chooses between **local** (renders `127.0.0.1`; deploy one D2 instance per peer for HA-pair DDNS redundancy) and **remote** (single shared instance pinned to an IPAM record). Each daemon exposes a per-instance `/api/plugins/netbox_dhcp_kea_plugin/d2-daemons/<id>/kea-config/` endpoint that emits a complete `kea-dhcp-ddns.conf`.
55
+
-`DDNSDomain` — binds a `D2Daemon` to a `netbox_dns.Zone`. Forward/reverse direction is derived from the zone name at emission time. Authoritative nameserver IPs are resolved from the zone's `NameServer` records (A/AAAA/CNAME chain) when the config is rendered. The create form is multi-zone — pick any combination of forward and reverse zones in one shot.
56
+
-`DDNSPolicy` — reusable `ddns-*` override group attachable at server / subnet / client-class scope (`ddns-send-updates`, `ddns-override-no-update`, `ddns-replace-client-name`, `ddns-generated-prefix`/`-qualifying-suffix`, `hostname-char-set`/`-replacement`, conflict-resolution mode, TTL knobs). All fields nullable — only the keys you set are emitted, kebab-cased.
57
+
58
+
-**HA-pair precedence** — when a `DHCPServer` is in an HA relationship and the relationship has its own `d2_daemon` or `ddns_policy` set, the relationship's value wins (peers must agree on the D2 target and the policy knobs). Sender IP/port stay per-server because the local source endpoint is per-host. The DHCPServer detail page shows the effective values with an "inherited from HA relationship" badge.
59
+
60
+
-**Local-D2 redundancy pattern (recommended for HA)** — set `listener_mode: local` on the `D2Daemon` shared by an HA pair, then deploy `kea-dhcp-ddns` on every peer host with the same rendered config. Each peer's `kea-dhcp4`/`6` posts NCRs to its own `127.0.0.1:53001`. If the active peer reboots, the standby's local D2 takes over with no DDNS gap.
61
+
62
+
-**Kea config emission** — no Python-side merging of override hierarchies. Each non-null `DDNSPolicy.to_kea_overrides()` is emitted verbatim at the JSON level the policy is attached to (server-level → `Dhcp4`/`Dhcp6` root, subnet-level → subnet dict, class-level → client-class dict). Kea resolves the precedence chain itself when processing packets.
63
+
64
+
-**Bulk edit + quick-add** — `DDNSDomain` has a bulk-edit form (set `d2_daemon` / `tsig_key` on many rows at once), and the `tsig_key` field on the DDNS Domain form has a `+` quick-add button so a new TSIG key can be created inline without leaving the form.
65
+
45
66
### High Availability (HA) Support
46
67
47
68
- Configure HA relationships with multiple modes: hot-standby, load-balancing, passive-backup
0 commit comments