Development

This commit is contained in:
Matthew Grotke 2026-05-31 02:17:25 -04:00
parent 84118a4c2b
commit 916d238602
9 changed files with 51 additions and 51 deletions

View file

@ -112,9 +112,9 @@ def addvlan_add():
inferred_gw = (min(identity_ips, key=lambda ip: int(ip.split('.')[-1])) if identity_ips else '')
new_stored_gw = gateway_raw if (gateway_raw and gateway_raw != inferred_gw) else ''
dns_override = 'dns_server_override' in request.form
dns_override = 'dns_servers_override' in request.form
dns_ips = []
for _line in request.form.get('dns_server', '').splitlines():
for _line in request.form.get('dns_servers', '').splitlines():
_line = _line.strip()
if not _line:
continue
@ -130,9 +130,9 @@ def addvlan_add():
return redirect(f'/{_PAGE}')
new_stored_dns = dns_ips if dns_override else []
ntp_override = 'ntp_server_override' in request.form
ntp_override = 'ntp_servers_override' in request.form
ntp_ips = []
for _line in request.form.get('ntp_server', '').splitlines():
for _line in request.form.get('ntp_servers', '').splitlines():
_line = _line.strip()
if not _line:
continue
@ -207,9 +207,9 @@ def addvlan_add():
if new_stored_gw:
dhcp_overrides['gateway'] = new_stored_gw
if new_stored_dns:
dhcp_overrides['dns_server'] = new_stored_dns
dhcp_overrides['dns_servers'] = new_stored_dns
if new_stored_ntp:
dhcp_overrides['ntp_server'] = new_stored_ntp
dhcp_overrides['ntp_servers'] = new_stored_ntp
if dhcp_overrides:
dhcp_info['explicit_overrides'] = dhcp_overrides
@ -361,9 +361,9 @@ def vlans_edit():
new_stored_gw = gateway_raw if (gateway_raw and gateway_raw != inferred_gw) else ''
existing_gw = existing.get('dhcp_information', {}).get('explicit_overrides', {}).get('gateway', '')
dns_override = 'dns_server_override' in request.form
dns_override = 'dns_servers_override' in request.form
dns_ips = []
for _line in request.form.get('dns_server', '').splitlines():
for _line in request.form.get('dns_servers', '').splitlines():
_line = _line.strip()
if not _line:
continue
@ -382,12 +382,12 @@ def vlans_edit():
flash(f"DNS server '{_ip}' is not in the VLAN subnet ({subnet}/{final_mask}).", 'error')
return redirect(f'/{_PAGE}')
new_stored_dns = dns_ips if dns_override else []
_existing_dns = existing.get('dhcp_information', {}).get('explicit_overrides', {}).get('dns_server', [])
_existing_dns = existing.get('dhcp_information', {}).get('explicit_overrides', {}).get('dns_servers', [])
existing_dns = _existing_dns if isinstance(_existing_dns, list) else ([_existing_dns] if _existing_dns else [])
ntp_override = 'ntp_server_override' in request.form
ntp_ips = []
for _line in request.form.get('ntp_server', '').splitlines():
for _line in request.form.get('ntp_servers', '').splitlines():
_line = _line.strip()
if not _line:
continue
@ -406,7 +406,7 @@ def vlans_edit():
flash(f"NTP server '{_ip}' is not in the VLAN subnet ({subnet}/{final_mask}).", 'error')
return redirect(f'/{_PAGE}')
new_stored_ntp = ntp_ips if ntp_override else []
_existing_ntp = existing.get('dhcp_information', {}).get('explicit_overrides', {}).get('ntp_server', [])
_existing_ntp = existing.get('dhcp_information', {}).get('explicit_overrides', {}).get('ntp_servers', [])
existing_ntp = _existing_ntp if isinstance(_existing_ntp, list) else ([_existing_ntp] if _existing_ntp else [])
_ids_unchanged = (
@ -452,13 +452,13 @@ def vlans_edit():
else:
dhcp_overrides.pop('gateway', None)
if new_stored_dns:
dhcp_overrides['dns_server'] = new_stored_dns
dhcp_overrides['dns_servers'] = new_stored_dns
else:
dhcp_overrides.pop('dns_server', None)
dhcp_overrides.pop('dns_servers', None)
if new_stored_ntp:
dhcp_overrides['ntp_server'] = new_stored_ntp
dhcp_overrides['ntp_servers'] = new_stored_ntp
else:
dhcp_overrides.pop('ntp_server', None)
dhcp_overrides.pop('ntp_servers', None)
if not dhcp_overrides:
existing.get('dhcp_information', {}).pop('explicit_overrides', None)
errors = validate.validate_config(cfg)

View file

@ -221,16 +221,16 @@
{
"type": "overridable_textarea",
"label": "DNS Server(s)",
"name": "dns_server",
"override_name": "dns_server_override",
"name": "dns_servers",
"override_name": "dns_servers_override",
"validate": "VALIDATION_ADDRESS",
"hint": "DNS server(s) advertised to clients via DHCP."
},
{
"type": "overridable_textarea",
"label": "NTP Server(s)",
"name": "ntp_server",
"override_name": "ntp_server_override",
"name": "ntp_servers",
"override_name": "ntp_servers_override",
"validate": "VALIDATION_ADDRESS",
"hint": "NTP server(s) advertised to clients via DHCP."
},

View file

@ -88,7 +88,7 @@ def _build_client_conf(vlan, peer_name, peer_ip, private_key, server_pubkey):
default = str(min((ipaddress.IPv4Address(ip) for ip in ident_ips),
key=lambda x: x.packed[-1])) if ident_ips else str(next(network.hosts()))
gateway = overrides.get('gateway') or default
dns = overrides.get('dns_server') or gateway
dns = overrides.get('dns_servers') or gateway
prefix = network.prefixlen
mtu = overrides.get('mtu', '')
endpoint = info.get('server_endpoint', '')
@ -138,7 +138,7 @@ def wireguard_apply():
listen_port_raw = request.form.get('vpn_listen_port', '').strip()
server_endpoint = validate.domainname(request.form.get('vpn_server_endpoint', ''))
domain = validate.domainname(request.form.get('vpn_domain', ''))
dns_raw = request.form.get('vpn_dns_server', '').strip()
dns_raw = request.form.get('vpn_dns_servers', '').strip()
mtu_raw = request.form.get('vpn_mtu', '').strip()
if not listen_port_raw:
@ -185,9 +185,9 @@ def wireguard_apply():
overrides = info.setdefault('explicit_overrides', {})
if dns_server:
overrides['dns_server'] = dns_server
overrides['dns_servers'] = dns_server
else:
overrides.pop('dns_server', None)
overrides.pop('dns_servers', None)
if mtu is not None:
overrides['mtu'] = mtu
else:

View file

@ -302,10 +302,10 @@ def config_datasource(name):
row['server_identity_gateway'] = (
v.get('dhcp_information', {}).get('explicit_overrides', {}).get('gateway', '')
)
_dns = v.get('dhcp_information', {}).get('explicit_overrides', {}).get('dns_server', [])
row['server_identity_dns_server'] = '\n'.join(_dns) if isinstance(_dns, list) else str(_dns or '')
_ntp = v.get('dhcp_information', {}).get('explicit_overrides', {}).get('ntp_server', [])
row['server_identity_ntp_server'] = '\n'.join(_ntp) if isinstance(_ntp, list) else str(_ntp or '')
_dns = v.get('dhcp_information', {}).get('explicit_overrides', {}).get('dns_servers', [])
row['server_identity_dns_servers'] = '\n'.join(_dns) if isinstance(_dns, list) else str(_dns or '')
_ntp = v.get('dhcp_information', {}).get('explicit_overrides', {}).get('ntp_servers', [])
row['server_identity_ntp_servers'] = '\n'.join(_ntp) if isinstance(_ntp, list) else str(_ntp or '')
rows.append(row)
return rows
@ -819,7 +819,7 @@ def collect_tokens():
tokens['VPN_LISTEN_PORT'] = str(vpn.get('listen_port', ''))
tokens['VPN_SERVER_ENDPOINT'] = str(vpn.get('server_endpoint', ''))
tokens['VPN_DOMAIN'] = str(vpn.get('domain', ''))
tokens['VPN_DNS_SERVER'] = str(overrides.get('dns_server', ''))
tokens['VPN_DNS_SERVER'] = str(overrides.get('dns_servers', ''))
tokens['VPN_MTU'] = str(overrides.get('mtu', ''))
# Compute gateway from server_identities (lowest last-octet), fallback to first subnet host

View file

@ -77,7 +77,7 @@ Edit the `vlans` array to match your network topology. For each VLAN:
"listen_port": 51820,
"server_endpoint": "vpn.example.com",
"domain": "local",
"explicit_overrides": { "gateway": "", "dns_server": "", "mtu": "" }
"explicit_overrides": { "gateway": "", "dns_servers": "", "mtu": "" }
},
"peers": [],
"port_wrangling": []

View file

@ -298,8 +298,8 @@
"domain": "lan",
"explicit_overrides": {
"gateway": "",
"dns_server": "",
"ntp_server": ""
"dns_servers": "",
"ntp_servers": ""
}
},
"reservations": [
@ -393,8 +393,8 @@
"domain": "lan",
"explicit_overrides": {
"gateway": "",
"dns_server": "",
"ntp_server": ""
"dns_servers": "",
"ntp_servers": ""
}
},
"reservations": [
@ -498,8 +498,8 @@
"domain": "lan",
"explicit_overrides": {
"gateway": "",
"dns_server": "",
"ntp_server": ""
"dns_servers": "",
"ntp_servers": ""
}
},
"reservations": [
@ -562,8 +562,8 @@
"domain": "lan",
"explicit_overrides": {
"gateway": "",
"dns_server": "",
"ntp_server": ""
"dns_servers": "",
"ntp_servers": ""
}
},
"reservations": [
@ -638,7 +638,7 @@
"domain": "lan",
"explicit_overrides": {
"gateway": "",
"dns_server": "",
"dns_servers": "",
"mtu": ""
}
},

View file

@ -195,11 +195,11 @@ def resolve_vlan_options(vlan):
overrides = vpi.get("explicit_overrides", {})
default = lowest_quartet_ip(vlan) or str(next(network_for(vlan).hosts()))
gateway = overrides.get("gateway", "") or default
dns = overrides.get("dns_server", "") or gateway
dns = overrides.get("dns_servers", "") or gateway
return {
"gateway": gateway,
"dns_server": dns,
"ntp_server": None,
"dns_servers": dns,
"ntp_servers": None,
}
overrides = vlan.get("dhcp_information", {}).get("explicit_overrides", {})
default = lowest_quartet_ip(vlan)
@ -210,8 +210,8 @@ def resolve_vlan_options(vlan):
return v or default
return {
"gateway": overrides.get("gateway", "") or default,
"dns_server": _resolve("dns_server"),
"ntp_server": _resolve("ntp_server"),
"dns_servers": _resolve("dns_servers"),
"ntp_servers": _resolve("ntp_servers"),
}
def is_physical(vlan):
@ -481,8 +481,8 @@ def build_vlan_dnsmasq_conf(vlan, data, iface):
line(f"domain={d.get('domain', 'local')}")
line()
line(f"dhcp-option=tag:{name},option:router,{gateway}")
line(f"dhcp-option=tag:{name},option:dns-server,{opts['dns_server']}")
line(f"dhcp-option=tag:{name},option:ntp-server,{opts['ntp_server']}")
line(f"dhcp-option=tag:{name},option:dns-server,{opts['dns_servers']}")
line(f"dhcp-option=tag:{name},option:ntp-server,{opts['ntp_servers']}")
line()
identity_hosts = [s for s in vlan.get("server_identities", []) if s.get("hostname")]

View file

@ -122,7 +122,7 @@ def build_client_conf(vlan, peer_ip, private_key, server_pub, split_tunnel):
default = str(min((ipaddress.IPv4Address(ip) for ip in ident_ips),
key=lambda x: x.packed[-1])) if ident_ips else str(next(network.hosts()))
gateway = overrides.get("gateway") or default
dns = overrides.get("dns_server") or gateway
dns = overrides.get("dns_servers") or gateway
prefix = network.prefixlen
mtu = overrides.get("mtu", "")
endpoint = info.get("server_endpoint", "")

View file

@ -460,7 +460,7 @@ def validate_config(data):
f"any server_identity IP. Must be one of: "
f"{[str(ip) for ip in identity_ips]}."
)
dns = eo.get("dns_server", "")
dns = eo.get("dns_servers", "")
if dns and not ipv4(dns):
errors.append(f"{label}: vpn_information.explicit_overrides.dns_server '{dns}' is not a valid IPv4 address.")
mtu = eo.get("mtu", "")
@ -564,14 +564,14 @@ def validate_config(data):
f"any server_identity IP. Must be one of: "
f"{[str(ip) for ip in identity_ips]}."
)
dns = eo.get("dns_server", "")
dns = eo.get("dns_servers", "")
if dns:
for _ip in (dns if isinstance(dns, list) else [dns]):
check_ip("explicit_overrides.dns_server", _ip)
ntp = eo.get("ntp_server", "")
check_ip("explicit_overrides.dns_servers", _ip)
ntp = eo.get("ntp_servers", "")
if ntp:
for _ip in (ntp if isinstance(ntp, list) else [ntp]):
check_ip("explicit_overrides.ntp_server", _ip)
check_ip("explicit_overrides.ntp_servers", _ip)
pool_start = check_ip("dynamic_pool_start", d["dynamic_pool_start"])
pool_end = check_ip("dynamic_pool_end", d["dynamic_pool_end"])