Development

This commit is contained in:
Matthew Grotke 2026-05-27 23:28:55 -04:00
parent 0c0589a0b1
commit a55d44f480
3 changed files with 131 additions and 59 deletions

View file

@ -1,6 +1,7 @@
from pathlib import Path
import copy
import ipaddress
import json
from flask import Blueprint, request, redirect, flash
from auth import require_level
@ -62,6 +63,39 @@ def addvlan_add():
if not _hash_ok():
return redirect(f'/{_PAGE}')
server_identities_raw = request.form.get('server_identities', '[]')
try:
raw_identities = json.loads(server_identities_raw)
if not isinstance(raw_identities, list):
raise ValueError
except (ValueError, TypeError):
flash('Invalid identity data.', 'error')
return redirect(f'/{_PAGE}')
new_identities = []
if raw_identities:
_vlan_net = ipaddress.IPv4Network(f'{subnet}/{subnet_mask}', strict=False)
for raw in raw_identities:
ip_clean = sanitize.ip(str(raw.get('ip', '')))
if not ip_clean:
flash('Invalid IP address in identity.', 'error')
return redirect(f'/{_PAGE}')
if ipaddress.IPv4Address(ip_clean) not in _vlan_net:
flash(f"Identity IP '{ip_clean}' is not in the VLAN subnet ({subnet}/{subnet_mask}).", 'error')
return redirect(f'/{_PAGE}')
ident = {'ip': ip_clean}
desc = str(raw.get('description', '')).strip()
if desc:
ident['description'] = desc
hostname_raw = str(raw.get('hostname', '')).strip()
if hostname_raw:
clean_hostname = sanitize.hostname(hostname_raw)
if clean_hostname is None:
flash(f"'{hostname_raw}' is not a valid hostname.", 'error')
return redirect(f'/{_PAGE}')
ident['hostname'] = clean_hostname
new_identities.append(ident)
cfg = load_config()
vlans = cfg.setdefault('vlans', [])
@ -82,6 +116,7 @@ def addvlan_add():
'use_blocklists': use_blocklists,
'radius_default': radius_default,
'mdns_reflection': mdns_reflection,
'server_identities': new_identities,
}
if is_vpn:
entry['peers'] = []

View file

@ -217,8 +217,34 @@
"type": "hr"
},
{
"type": "identity_builder",
"label": "Router Identities on this VLAN:"
"type": "record_editor",
"label": "Router Identities on this VLAN:",
"name": "server_identities",
"empty_message": "No identities added.",
"fields": [
{
"label": "IP Address",
"name": "ip",
"valtype": "address",
"attrs": {
"data-dep-subnet": "[name='subnet']",
"data-dep-mask": ".subnet-prefix-input"
},
"placeholder": "x.x.x.x",
"required": true
},
{
"label": "Description",
"name": "description",
"placeholder": "Optional label"
},
{
"label": "Hostname",
"name": "hostname",
"validate": "networkname",
"placeholder": "Optional"
}
]
},
{
"type": "hr"