Skip to content

Releases: fenleytech/ez-kea

v0.9.2

Choose a tag to compare

@KalebFenley KalebFenley released this 02 Aug 20:11
9230ee2

Fixed

Found by a second from-scratch install, this time onto a fresh Ubuntu 26 VM
running ISC's own Kea 3.2 packages untouched — same premise as the 0.9.1 pass
below, different (and worse) bugs. All four are regression-tested; see
AUDIT_FINDINGS.md for the full write-up of each.

  • A Kea config full of ISC's own ///#//* */ comments — i.e. every
    packaged install's default config, unmodified — silently parsed as empty

    instead of failing loudly, and saving anything on top of that emptied
    skeleton overwrote the real subnets/reservations on disk with no warning
    anywhere. load_json() now strips Kea's comment syntax before parsing, and
    a file that still fails to parse after that raises instead of silently
    returning a blank skeleton.
  • Saving Global Settings could still duplicate the logger's output-path key
    and get the config rejected by Kea. 0.9.1 fixed the two places that write
    this key but missed that the skeleton default load_json() falls back to
    still hardcoded the old, wrong spelling — so the fallback path alone was
    enough to reproduce the exact bug 0.9.1 believed it had closed.
  • A config-parse fallback could leak one protocol's data into the other
    protocol's file.
    The fallback skeleton was shared, mutable, module-level
    state, and one DHCPv6 route fetched the DHCPv4 skeleton by mistake when its
    own config didn't parse — together, creating an IPv6 subnet could write a
    stray Dhcp4 block into kea-dhcp6.conf, which Kea then refused to load.
    The fallback is now always an independent deep copy, and every DHCPv6 call
    site was audited to fetch the right skeleton.
  • Every DHCPv6 Prefix Delegation pool created through the UI was rejected by
    Kea.
    The only way to create one stored the whole prefix/length string as
    Kea's prefix field and never set the separate prefix-len field Kea's
    schema requires, so kea-dhcp6 -t failed with "missing parameter
    'prefix-len'" on every single one. Fixed to submit prefix and prefix-len
    as the separate fields Kea expects.

v0.9.1

Choose a tag to compare

@KalebFenley KalebFenley released this 01 Aug 03:21
6290a2d

Fixed

Found by deploying from scratch onto a clean Ubuntu 24.04 box running ISC's own
Kea 3.2 packages — every one of these was reproduced on that machine, and all
are regression-tested in tests/test_greenfield_regressions.py.

  • Kea configs are now genuinely backed up before every write. Automatic
    backup did not exist: copy_file() was reachable only from the explicit
    Backup and Restore buttons, while all 23 config-write paths (subnets, pools,
    reservations, options, HA, global settings) called save_json() directly.
    Writes now go through save_kea_config(), which backs up first, prunes to the
    most recent 100 per config, and refuses the write if the backup fails.
  • Restore no longer fails on a normal packaged Kea install. It used
    shutil.copy2(), which chmods the destination — and chmod needs ownership,
    which EZ-KEA does not have over a _kea-owned /etc/kea/kea-dhcp4.conf. It
    raised EPERM after writing the contents, so the restore silently succeeded
    while reporting HTTP 500. Now uses copyfile(), leaving ownership and mode to
    whoever set up Kea.
  • Saving Global Settings no longer writes a config Kea refuses to load. It
    emitted output_options (underscore) alongside the correct output-options,
    which Kea rejects as a duplicate, and injected an empty
    host-reservation-identifiers: [], which Kea rejects outright. One Save click
    left the live config unloadable.
  • Saving Global Settings no longer silently demotes the other protocol to the
    sandbox.
    On the first save the settings file was seeded from the ./data
    defaults, so saving the DHCPv4 form pinned DHCPv6 to a sandbox path — and
    writing the file makes discovery stop looking for the running daemon. Every
    later DHCPv6 edit then went to a file kea-dhcp6 never reads, with no warning.
    The version not being saved is now seeded from what discovery actually
    resolved.
  • The control-socket reload strategy works against a stock ISC config. Those
    configs use a bare relative socket-name (kea4-ctrl-socket), which Kea
    resolves against /var/run/kea; EZ-KEA passed it to connect() verbatim, so
    it looked in its own working directory. This mattered doubly because Kea 3.2
    ships no keactrl, leaving the control socket as the only reload path.
  • The DHCPv6 Pools page shows standalone subnets. Kea writes a plain
    single-subnet v6 server as a top-level Dhcp6.subnet6[], and the page read
    only shared-networks — so such a server displayed as "No IPv6 Shared
    Networks Configured", hiding live subnets and inviting the operator to
    recreate config that already existed. Standalone v6 subnets can now be
    listed, created, deleted, and given options, matching DHCPv4.
  • An unreadable Kea config now explains itself instead of returning a 500.
    load_json() handled missing and corrupt files but not PermissionError,
    which is the normal first-run state against packaged Kea (/etc/kea is 0750
    _kea:_kea). It now raises ConfigAccessError, rendered as a 503 naming the
    file and the group fix, and the log indexer no longer logs a traceback every
    60 seconds. It deliberately does not fall back to the empty skeleton —
    that would show a real server as having no subnets, and the next save would
    overwrite the operator's config with it.

Removed

  • jsonify==0.5 from requirements.txt — an abandoned no-op package unrelated
    to Flask's jsonify, imported nowhere, with no wheel on PyPI, so it was built
    from source during the first command every install runs.

Changed

  • Commercial licensing now states a price. $500 a year for a single
    deployment — one production install, in one environment, run by one
    organization — with volume licensing quoted for anyone running more than
    one. The README, the in-app Licensing page, and the unlicensed footer note
    and banner all said "commercial use requires a license" without naming a
    number, so the only way to learn the price was to send an email. No licensing
    behaviour changed: nothing is gated, blocked, or expired, and the free
    noncommercial terms are exactly as they were.

v0.9.0

Choose a tag to compare

@KalebFenley KalebFenley released this 31 Jul 06:50
461b106

First tagged release. EZ-KEA has been public since 29 July 2026; this puts a version on it so an install can be identified.

While EZ-KEA is on 0.x, environment variable names, settings keys, and the on-disk layout under data/ may still change between releases. Your Kea configuration is never one of those things — EZ-KEA edits the file Kea already reads, and always backs it up first.

Added

  • Kea 3.x support. Kea 3.0 renamed the singular control-socket object to a control-sockets list. EZ-KEA now reads either spelling, and probes kea-dhcp4 -v to decide which one to write, so a generated config is accepted by the version actually installed. Configs written for Kea 2.x keep working untouched.
  • Control-socket reload strategy. Sends config-reload down the daemon's own command socket and reports whether the reload succeeded. This is ISC's recommended path now that the Control Agent is gone, and it is the only one that works on Kea 3.2 installed from ISC's packages, which ship no keactrl at all. Selectable in Global Settings alongside keactrl and Docker SIGHUP.
  • Full-history log search backed by a SQLite index, rather than tailing.
  • A Kea 3.2.0 testbed target (ISC's own packages from Cloudsmith) next to the existing Ubuntu 2.0.2 one. Both build the same testbed, so .env.testbed and test_suite.sh work against either unchanged.

Fixed

  • HA peer status no longer breaks on Kea 3.x. It looked up the control socket by the pre-3.0 key name only, so on a 3.x config it found nothing and reported the peer unreachable.
  • The testbed Kea container no longer crash-loops on a stale PID file.
  • test_suite.sh runs against either Kea target. This also uncovered a test that passed by matching a label in its own capture file rather than a delivered DHCP option.

Changed

  • Relicensed to PolyForm Noncommercial 1.0.0 (source-available; free and unlimited for noncommercial use, commercial use needs a paid license). All runtime enforcement was removed with it — the previous 100-lease free tier, grace period, and write lock are gone. Unlicensed installs show a footer note and nothing more.

Full detail in CHANGELOG.md.