Development

This commit is contained in:
Matthew Grotke 2026-06-03 02:24:21 -04:00
parent f04b2b36cc
commit 5a3a18d5b0
7 changed files with 123 additions and 33 deletions

View file

@ -687,7 +687,7 @@
"description": "Doorbell Camera",
"hostname": "doorbell-camera",
"mac": "aa:bb:cc:dd:ee:16",
"ip": "dynamic",
"ip": "",
"vlan": "iot"
},
{
@ -695,7 +695,7 @@
"description": "Smart Speaker",
"hostname": "smart-speaker",
"mac": "aa:bb:cc:dd:ee:17",
"ip": "dynamic",
"ip": "",
"vlan": "iot"
},
{
@ -703,7 +703,7 @@
"description": "Family Member Phone 1",
"hostname": "phone-1",
"mac": "aa:bb:cc:dd:ee:20",
"ip": "dynamic",
"ip": "",
"vlan": "guest"
},
{
@ -711,7 +711,7 @@
"description": "Family Member Phone 2",
"hostname": "phone-2",
"mac": "aa:bb:cc:dd:ee:21",
"ip": "dynamic",
"ip": "",
"vlan": "guest"
},
{
@ -719,7 +719,7 @@
"description": "Child 1 Laptop",
"hostname": "child1-laptop",
"mac": "aa:bb:cc:dd:ee:30",
"ip": "dynamic",
"ip": "",
"vlan": "kids"
},
{
@ -727,7 +727,7 @@
"description": "Child 2 Laptop",
"hostname": "child2-laptop",
"mac": "aa:bb:cc:dd:ee:31",
"ip": "dynamic",
"ip": "",
"vlan": "kids"
},
{
@ -735,7 +735,7 @@
"description": "Child 3 Laptop",
"hostname": "child3-laptop",
"mac": "aa:bb:cc:dd:ee:32",
"ip": "dynamic",
"ip": "",
"vlan": "kids"
},
{
@ -743,7 +743,7 @@
"description": "Child Tablet",
"hostname": "child-tablet",
"mac": "aa:bb:cc:dd:ee:33",
"ip": "dynamic",
"ip": "",
"vlan": "kids"
}
],

View file

@ -518,20 +518,23 @@ def build_vlan_dnsmasq_conf(vlan, data, iface):
for group in ordered:
if len(group) == 1:
r = group[0]
h = r.get('hostname', '')
line(f"# {r['description']}")
if is_dynamic_ip(r):
line(f"dhcp-host=set:{name},{r['mac']},{r['hostname']},{d['lease_time']}")
line(f"dhcp-host=set:{name},{r['mac']},{h},{d['lease_time']}" if h else
f"dhcp-host=set:{name},{r['mac']},{d['lease_time']}")
else:
line(f"dhcp-host=set:{name},{r['mac']},{r['ip']},{r['hostname']},{d['lease_time']}")
line(f"dhcp-host=set:{name},{r['mac']},{r['ip']},{h},{d['lease_time']}" if h else
f"dhcp-host=set:{name},{r['mac']},{r['ip']},{d['lease_time']}")
else:
# Multiple MACs share the same IP -- combine into one dhcp-host line
descs = ", ".join(r['description'] for r in group)
macs = ",".join(r['mac'] for r in group)
ip = group[0]['ip']
# Use first entry's hostname; all share the same IP anyway
hostname = group[0]['hostname']
descs = ", ".join(r['description'] for r in group)
macs = ",".join(r['mac'] for r in group)
ip = group[0]['ip']
hostname = group[0].get('hostname', '')
line(f"# {descs}")
line(f"dhcp-host=set:{name},{macs},{ip},{hostname},{d['lease_time']}")
line(f"dhcp-host=set:{name},{macs},{ip},{hostname},{d['lease_time']}" if hostname else
f"dhcp-host=set:{name},{macs},{ip},{d['lease_time']}")
line()
if inactive_res:

View file

@ -739,8 +739,9 @@ def validate_config(data):
f"pool ({pool_start} - {pool_end})."
)
seen_res_ips = {}
seen_res_macs = {}
seen_res_ips = {}
seen_res_macs = {}
seen_res_hostnames = {}
vlan_name_key = vlan.get("name", "")
for r in [r for r in data.get("dhcp_reservations", []) if r.get("vlan") == vlan_name_key]:
rdesc = r.get("description", "?")
@ -784,6 +785,16 @@ def validate_config(data):
else:
seen_res_macs[rmac] = rdesc
rhost = r.get("hostname", "").strip().lower()
if rhost:
if rhost in seen_res_hostnames:
errors.append(
f"{label}: reservation '{rdesc}' hostname '{rhost}' duplicates "
f"'{seen_res_hostnames[rhost]}'."
)
else:
seen_res_hostnames[rhost] = rdesc
for bl_name in vlan.get("use_blocklists", []):
if bl_name not in blocklists_by_name:
errors.append(f"{label}: use_blocklists references unknown blocklist '{bl_name}'.")