Development

This commit is contained in:
Matthew Grotke 2026-06-01 01:25:16 -04:00
parent 705c69abc4
commit 470cc39356
5 changed files with 244 additions and 245 deletions

View file

@ -25,16 +25,6 @@ def _hash_ok():
return True
def _flat_index_to_vlan_res(vlans, flat_idx):
pos = 0
for vi, vlan in enumerate(vlans):
for ri in range(len(vlan.get('reservations', []))):
if pos == flat_idx:
return vi, ri
pos += 1
return None, None
def _parse_ip():
raw = request.form.get('ip', '').strip()
if not raw:
@ -67,7 +57,7 @@ def addreservation_add():
if not _hash_ok():
return redirect(f'/{_PAGE}')
cfg = load_config()
cfg = load_config()
vlans = cfg.get('vlans', [])
vlan = next((v for v in vlans if v.get('name') == vlan_name), None)
if vlan is None:
@ -86,8 +76,9 @@ def addreservation_add():
'ip': ip,
'radius_client': radius_client,
'enabled': True,
'vlan': vlan_name,
}
vlan.setdefault('reservations', []).append(entry)
cfg.setdefault('dhcp_reservations', []).append(entry)
errors = validate.validate_config(cfg)
if errors:
for msg in errors:
@ -95,7 +86,7 @@ def addreservation_add():
return redirect(f'/{_PAGE}')
changes = diff_fields(None, entry)
flash(record_group(cfg, f'vlans[name={vlan_name}].reservations', 'mac', mac, changes, 'core apply'), 'success')
flash(record_group(cfg, 'dhcp_reservations', 'mac', mac, changes, 'core apply'), 'success')
return redirect(f'/{_PAGE}')
@ -109,14 +100,13 @@ def reservations_toggle():
if not _hash_ok():
return redirect(f'/{_PAGE}')
cfg = load_config()
vlans = cfg.get('vlans', [])
vi, ri = _flat_index_to_vlan_res(vlans, idx)
if vi is None:
cfg = load_config()
items = cfg.get('dhcp_reservations', [])
if idx < 0 or idx >= len(items):
flash('Entry not found.', 'error')
return redirect(f'/{_PAGE}')
res = vlans[vi]['reservations'][ri]
res = items[idx]
old_enabled = res.get('enabled', True)
before = copy.deepcopy(res)
res['enabled'] = not old_enabled
@ -126,9 +116,8 @@ def reservations_toggle():
flash(msg, 'error')
return redirect(f'/{_PAGE}')
vlan_name = vlans[vi]['name']
changes = diff_fields(before, res)
flash(record_group(cfg, f'vlans[name={vlan_name}].reservations', 'mac', res['mac'], changes, 'core apply'), 'success')
flash(record_group(cfg, 'dhcp_reservations', 'mac', res['mac'], changes, 'core apply'), 'success')
return redirect(f'/{_PAGE}')
@ -154,19 +143,21 @@ def reservations_edit():
if not _hash_ok():
return redirect(f'/{_PAGE}')
cfg = load_config()
vlans = cfg.get('vlans', [])
vi, ri = _flat_index_to_vlan_res(vlans, idx)
if vi is None:
cfg = load_config()
items = cfg.get('dhcp_reservations', [])
if idx < 0 or idx >= len(items):
flash('Entry not found.', 'error')
return redirect(f'/{_PAGE}')
conflict = validate.check_reservation_ip_conflicts(ip, vlans[vi])
if conflict:
flash(f'The configuration has not been saved because {conflict}', 'error')
return redirect(f'/{_PAGE}')
res = items[idx]
vlan_name = res.get('vlan', '')
vlan = next((v for v in cfg.get('vlans', []) if v.get('name') == vlan_name), None)
if vlan:
conflict = validate.check_reservation_ip_conflicts(ip, vlan)
if conflict:
flash(f'The configuration has not been saved because {conflict}', 'error')
return redirect(f'/{_PAGE}')
res = vlans[vi]['reservations'][ri]
before = copy.deepcopy(res)
res.update({
'description': description,
@ -182,9 +173,8 @@ def reservations_edit():
flash(msg, 'error')
return redirect(f'/{_PAGE}')
vlan_name = vlans[vi]['name']
changes = diff_fields(before, res)
flash(record_group(cfg, f'vlans[name={vlan_name}].reservations', 'mac', mac, changes, 'core apply'), 'success')
flash(record_group(cfg, 'dhcp_reservations', 'mac', mac, changes, 'core apply'), 'success')
return redirect(f'/{_PAGE}')
@ -198,15 +188,13 @@ def reservations_delete():
if not _hash_ok():
return redirect(f'/{_PAGE}')
cfg = load_config()
vlans = cfg.get('vlans', [])
vi, ri = _flat_index_to_vlan_res(vlans, idx)
if vi is None:
cfg = load_config()
items = cfg.get('dhcp_reservations', [])
if idx < 0 or idx >= len(items):
flash('Entry not found.', 'error')
return redirect(f'/{_PAGE}')
vlan_name = vlans[vi]['name']
removed = vlans[vi]['reservations'].pop(ri)
removed = items.pop(idx)
errors = validate.validate_config(cfg)
if errors:
for msg in errors:
@ -214,5 +202,5 @@ def reservations_delete():
return redirect(f'/{_PAGE}')
changes = diff_fields(removed, None)
flash(record_group(cfg, f'vlans[name={vlan_name}].reservations', 'mac', removed['mac'], changes, 'core apply'), 'success')
flash(record_group(cfg, 'dhcp_reservations', 'mac', removed['mac'], changes, 'core apply'), 'success')
return redirect(f'/{_PAGE}')

View file

@ -334,11 +334,10 @@ def config_datasource(name):
if name == 'dhcp_reservations':
rows = []
for vlan in vlans:
for res in vlan.get('reservations', []):
row = dict(res)
row['vlan_name'] = vlan.get('name', '-')
rows.append(row)
for res in cfg.get('dhcp_reservations', []):
row = dict(res)
row['vlan_name'] = res.get('vlan', '-')
rows.append(row)
return rows
if name == 'ddns_providers':
@ -795,10 +794,9 @@ def collect_tokens():
_vn = _v.get('name', '')
if not _vn:
continue
_res_ips_by_vlan[_vn] = [r['ip'] for r in _v.get('reservations', [])
if r.get('ip') and r['ip'] != 'dynamic']
_res_hosts_by_vlan[_vn] = [r['hostname'] for r in _v.get('reservations', [])
if r.get('hostname')]
_vlan_res = [r for r in cfg.get('dhcp_reservations', []) if r.get('vlan') == _vn]
_res_ips_by_vlan[_vn] = [r['ip'] for r in _vlan_res if r.get('ip') and r['ip'] != 'dynamic']
_res_hosts_by_vlan[_vn] = [r['hostname'] for r in _vlan_res if r.get('hostname')]
tokens['RESERVATION_IPS_BY_VLAN_JSON'] = json.dumps(_res_ips_by_vlan)
tokens['RESERVATION_HOSTNAMES_BY_VLAN_JSON'] = json.dumps(_res_hosts_by_vlan)
tokens['EXISTING_VLAN_IDS_JSON'] = json.dumps([v.get('vlan_id') for v in vlans])