Development

This commit is contained in:
Matthew Grotke 2026-05-31 22:01:59 -04:00
parent 6c3abca58c
commit 96f6e32c8f
9 changed files with 294 additions and 166 deletions

View file

@ -218,25 +218,37 @@ def vlans_addedit():
existing = vlans[edit_idx]
is_vpn = existing.get('is_vpn', False)
if is_vpn and mdns_reflection:
flash('mDNS reflection is not supported on VPN VLANs.', 'error')
# VPN VLANs do not support mDNS reflection
err = validate.check_mdns_vpn(is_vpn, mdns_reflection)
if err:
flash(err, 'error')
return redirect(f'/{_PAGE}')
# VLAN 1 maps to the physical LAN interface; its ID is fixed
current_id = existing.get('vlan_id')
if current_id == 1 and vlan_id != 1:
flash('VLAN 1 is the physical interface and cannot change its ID.', 'error')
return redirect(f'/{_PAGE}')
if vlan_id != current_id and any(
v.get('vlan_id') == vlan_id for i, v in enumerate(vlans) if i != edit_idx
):
flash(f'VLAN ID {vlan_id} is already in use.', 'error')
# VLAN ID must be unique across all VLANs (used as 802.1Q tag and interface name)
err = validate.check_vlan_id_unique(vlans, vlan_id, exclude_idx=edit_idx)
if err:
flash(err, 'error')
return redirect(f'/{_PAGE}')
if radius_default and any(i != edit_idx and v.get('radius_default') for i, v in enumerate(vlans)):
flash('Only one VLAN can be the RADIUS default.', 'error')
# VLAN name must be unique - it is used as the change-history lookup key
err = validate.check_vlan_name_unique(vlans, name, exclude_idx=edit_idx)
if err:
flash(err, 'error')
return redirect(f'/{_PAGE}')
# Only one VLAN may be the RADIUS default (used for dynamic VLAN assignment)
if radius_default:
err = validate.check_radius_default_unique(vlans, exclude_idx=edit_idx)
if err:
flash(err, 'error')
return redirect(f'/{_PAGE}')
before = copy.deepcopy(existing)
existing.update({
'name': name,
@ -269,18 +281,31 @@ def vlans_addedit():
else:
is_vpn = 'is_vpn' in request.form
if is_vpn and mdns_reflection:
flash('mDNS reflection is not supported on VPN VLANs.', 'error')
# VPN VLANs do not support mDNS reflection
err = validate.check_mdns_vpn(is_vpn, mdns_reflection)
if err:
flash(err, 'error')
return redirect(f'/{_PAGE}')
if any(v.get('vlan_id') == vlan_id for v in vlans):
flash(f'VLAN ID {vlan_id} is already in use.', 'error')
# VLAN ID must be unique across all VLANs (used as 802.1Q tag and interface name)
err = validate.check_vlan_id_unique(vlans, vlan_id)
if err:
flash(err, 'error')
return redirect(f'/{_PAGE}')
if radius_default and any(v.get('radius_default') for v in vlans):
flash('Only one VLAN can be the RADIUS default.', 'error')
# VLAN name must be unique - it is used as the change-history lookup key
err = validate.check_vlan_name_unique(vlans, name)
if err:
flash(err, 'error')
return redirect(f'/{_PAGE}')
# Only one VLAN may be the RADIUS default (used for dynamic VLAN assignment)
if radius_default:
err = validate.check_radius_default_unique(vlans)
if err:
flash(err, 'error')
return redirect(f'/{_PAGE}')
entry = {
'name': name,
'vlan_id': vlan_id,