fix(opnsense): correct Kea leases4 del_lease endpoint — path param, not body
CI / test (3.10) (push) Failing after 7s
CI / test (3.11) (push) Failing after 7s
CI / test (3.12) (push) Failing after 8s
CI / test (3.9) (push) Failing after 7s

The lease-delete call never actually worked: it posted {"ip-address": ip}
to /api/kea/leases4/delLease, both wrong. Verified live against a real
OPNsense instance while cleaning up stale leases left by failed NetOrk VM
provisioning attempts — every call returned {"status": "error", "message":
"Missing lease IP parameter"} despite three different body-parameter
guesses (ips as list, ips as string, ip singular). The official API docs
(docs.opnsense.org/development/api/core/kea.html) show LeasesController as
"Abstract [non-callable]" with a del_lease($ips=null) action; despite that
signature looking like a body field, the concrete leases4 route only
accepts the IP as a URL path segment: POST /api/kea/leases4/del_lease/{ip}
confirmed {"status": "ok"} and the lease actually gone from a follow-up
search.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Christian Manivong
2026-07-09 10:31:05 +02:00
co-authored by Claude Sonnet 5
parent b8dac1db63
commit b8a68fc3a8
2 changed files with 23 additions and 10 deletions
+8 -2
View File
@@ -1379,8 +1379,14 @@ class TestDeleteDhcpReservationAndLease:
reconfigure_call = driver.session.post.call_args_list[2]
assert reconfigure_call.args[0] == "https://opnsense.example.com/api/kea/service/reconfigure"
del_lease_call = driver.session.post.call_args_list[3]
assert del_lease_call.args[0] == "https://opnsense.example.com/api/kea/leases4/delLease"
assert del_lease_call.kwargs["json"] == {"ip-address": "172.22.8.253"}
# IP is a URL path segment, not a JSON body field — verified live
# against a real OPNsense instance; a {"ips": [ip]} body (the
# natural reading of the documented del_lease($ips=null) signature)
# returns {"status": "error", "message": "Missing lease IP parameter"}.
assert (
del_lease_call.args[0]
== "https://opnsense.example.com/api/kea/leases4/del_lease/172.22.8.253"
)
def test_noop_when_no_reservation_and_no_lease_found(self, driver):
driver.session.post.return_value = _make_json_response({"rows": []})