mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-31 13:03:02 +02:00
The isoformat() method already includes the timezone offset when the datetime object has timezone info. Appending "+00:00" created an invalid double-timezone suffix like "2025-11-30T13:13:49+00:00+00:00" which failed YANG validation. Error was: admin@bpi-26-60-00:/> show dhcp-server Error running sysrepocfg: Command '['sysrepocfg', '-f', 'json', '-X', '-d', 'operational', '-x', '/infix-dhcp-server:dhcp-server']' returned non-zero exit status 1. No interface data retrieved. With syslog showing: statd[4291]: libyang[0]: Invalid union value "2025-11-30T13:13:49+00:00+00:00" - no matching subtype found Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
98 lines
2.7 KiB
Python
Executable File
98 lines
2.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Collect operational data for infix-dhcp-server.yang from dnsmasq
|
|
"""
|
|
from datetime import datetime, timezone
|
|
import json
|
|
import dbus
|
|
|
|
|
|
def leases(leases_file):
|
|
"""Populate DHCP leases table"""
|
|
table = []
|
|
try:
|
|
with open(leases_file, 'r', encoding='utf-8') as fd:
|
|
for line in fd:
|
|
tokens = line.strip().split(" ")
|
|
if len(tokens) != 5:
|
|
continue
|
|
|
|
# Handle infinite lease time as specified in RFC 2131
|
|
if tokens[0] == "0":
|
|
expires = "never"
|
|
else:
|
|
dt = datetime.fromtimestamp(int(tokens[0]),
|
|
tz=timezone.utc)
|
|
expires = dt.isoformat()
|
|
|
|
row = {
|
|
"expires": expires,
|
|
"address": tokens[2],
|
|
"phys-address": tokens[1],
|
|
}
|
|
|
|
if tokens[3] != '*':
|
|
row["hostname"] = tokens[3]
|
|
else:
|
|
row["hostname"] = ""
|
|
|
|
if tokens[4] != '*':
|
|
row["client-id"] = tokens[4]
|
|
else:
|
|
row["client-id"] = ""
|
|
|
|
table.append(row)
|
|
except (IOError, OSError, ValueError):
|
|
pass
|
|
|
|
return table
|
|
|
|
|
|
def statistics():
|
|
"""Fetch DHCP server metrics over D-Bus"""
|
|
try:
|
|
bus = dbus.SystemBus()
|
|
obj = bus.get_object("uk.org.thekelleys.dnsmasq",
|
|
"/uk/org/thekelleys/dnsmasq")
|
|
srv = dbus.Interface(obj, "uk.org.thekelleys.dnsmasq")
|
|
|
|
metrics = srv.GetMetrics()
|
|
except dbus.exceptions.DBusException:
|
|
metrics = {
|
|
"dhcp_offer": 0,
|
|
"dhcp_ack": 0,
|
|
"dhcp_nak": 0,
|
|
"dhcp_decline": 0,
|
|
"dhcp_discover": 0,
|
|
"dhcp_request": 0,
|
|
"dhcp_release": 0,
|
|
"dhcp_inform": 0
|
|
}
|
|
|
|
return {
|
|
"out-offers": metrics["dhcp_offer"],
|
|
"out-acks": metrics["dhcp_ack"],
|
|
"out-naks": metrics["dhcp_nak"],
|
|
"in-declines": metrics["dhcp_decline"],
|
|
"in-discovers": metrics["dhcp_discover"],
|
|
"in-requests": metrics["dhcp_request"],
|
|
"in-releases": metrics["dhcp_release"],
|
|
"in-informs": metrics["dhcp_inform"]
|
|
}
|
|
|
|
|
|
def operational(leases_file="/var/lib/misc/dnsmasq.leases"):
|
|
"""Return operational status for DHCP server"""
|
|
return {
|
|
"infix-dhcp-server:dhcp-server": {
|
|
"statistics": statistics(),
|
|
"leases": {
|
|
"lease": leases(leases_file)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(json.dumps(operational(leases_file="mock.leases")))
|