Development
This commit is contained in:
parent
ac0aa4de22
commit
91d8b950b7
5 changed files with 38 additions and 35 deletions
|
|
@ -331,11 +331,11 @@ def validate_config(data):
|
|||
_vid = _derived_ids[i]
|
||||
vlan_ifaces.append(_lan if _vid == 1 else f"{_lan}.{_vid}")
|
||||
|
||||
# -- upstream_dns block ----------------------------------------------------
|
||||
# upstream_dns block ============================================
|
||||
if not data.get("upstream_dns", {}).get("upstream_servers"):
|
||||
errors.append("upstream_dns.upstream_servers is missing or empty.")
|
||||
|
||||
# -- WAN / LAN interfaces --------------------------------------------------
|
||||
# WAN / LAN interfaces ==========================================
|
||||
gen = data.get("network_interfaces", {})
|
||||
wan = gen.get("wan_interface", "")
|
||||
lan = gen.get("lan_interface", "")
|
||||
|
|
@ -357,7 +357,7 @@ def validate_config(data):
|
|||
if wan == lan:
|
||||
errors.append(f"network_interfaces.wan_interface and network_interfaces.lan_interface must be different (both set to '{wan}').")
|
||||
|
||||
# -- Blocklist library -----------------------------------------------------
|
||||
# Blocklist library =============================================
|
||||
blocklists_by_name = {}
|
||||
for idx, bl in enumerate(data.get("dns_blocking", {}).get("blocklists", [])):
|
||||
name = bl.get("name", "")
|
||||
|
|
@ -373,7 +373,7 @@ def validate_config(data):
|
|||
else:
|
||||
blocklists_by_name[name] = bl
|
||||
|
||||
# -- Per-VLAN validation ---------------------------------------------------
|
||||
# Per-VLAN validation ===========================================
|
||||
vlan_networks = {} # iface -> IPv4Network (used for NAT section)
|
||||
|
||||
for i, (vlan, iface) in enumerate(zip(_all_vlans, vlan_ifaces)):
|
||||
|
|
@ -403,7 +403,7 @@ def validate_config(data):
|
|||
errors.append(f"{label}: mdns_reflection must be false for WireGuard interfaces.")
|
||||
|
||||
if is_wg(vlan):
|
||||
# -- vpn_information -----------------------------------------------
|
||||
# vpn_information =======================================
|
||||
vpi = vlan.get("vpn_information")
|
||||
if not isinstance(vpi, dict):
|
||||
errors.append(f"{label}: vpn_information must be a plain object.")
|
||||
|
|
@ -418,7 +418,7 @@ def validate_config(data):
|
|||
else:
|
||||
seen_listen_ports[lp] = name
|
||||
|
||||
# -- subnet/subnet_mask --------------------------------------------
|
||||
# subnet/subnet_mask ====================================
|
||||
for field in ("subnet", "subnet_mask"):
|
||||
if not vlan.get(field):
|
||||
errors.append(f"{label}: missing required field '{field}'.")
|
||||
|
|
@ -430,7 +430,7 @@ def validate_config(data):
|
|||
except ValueError as e:
|
||||
errors.append(f"{label}: invalid subnet/subnet_mask: {e}")
|
||||
|
||||
# -- server_identities ---------------------------------------------
|
||||
# server_identities =====================================
|
||||
if not vlan.get("server_identities"):
|
||||
errors.append(f"{label}: server_identities is empty or missing.")
|
||||
identity_ips = []
|
||||
|
|
@ -449,7 +449,7 @@ def validate_config(data):
|
|||
else:
|
||||
identity_ips.append(ip_addr)
|
||||
|
||||
# -- vpn_information.explicit_overrides ----------------------------
|
||||
# vpn_information.explicit_overrides ====================
|
||||
eo = vpi.get("explicit_overrides", {}) if isinstance(vpi, dict) else {}
|
||||
if not isinstance(eo, dict):
|
||||
errors.append(f"{label}: vpn_information.explicit_overrides must be a plain object.")
|
||||
|
|
@ -476,7 +476,7 @@ def validate_config(data):
|
|||
if domain_val and not domainname(domain_val):
|
||||
errors.append(f"{label}: vpn_information.domain '{domain_val}' is not a valid domain name.")
|
||||
|
||||
# -- peers ---------------------------------------------------------
|
||||
# peers =================================================
|
||||
seen_peer_names = {}
|
||||
seen_peer_ips = {}
|
||||
for pidx, peer in enumerate(vlan.get("peers", [])):
|
||||
|
|
@ -556,7 +556,7 @@ def validate_config(data):
|
|||
if ip:
|
||||
identity_ips.append(ip)
|
||||
|
||||
# -- Validate explicit_overrides ---------------------------------------
|
||||
# Validate explicit_overrides ===============================
|
||||
eo = d.get("explicit_overrides", {})
|
||||
if not isinstance(eo, dict):
|
||||
errors.append(f"{label}: explicit_overrides must be a plain object.")
|
||||
|
|
@ -642,7 +642,7 @@ def validate_config(data):
|
|||
if bl_name not in blocklists_by_name:
|
||||
errors.append(f"{label}: use_blocklists references unknown blocklist '{bl_name}'.")
|
||||
|
||||
# -- NAT / firewall validation ---------------------------------------------
|
||||
# NAT / firewall validation =====================================
|
||||
valid_protos = VALID_PROTOCOLS
|
||||
known_interfaces = set(seen_interfaces.keys())
|
||||
|
||||
|
|
@ -675,7 +675,7 @@ def validate_config(data):
|
|||
if net:
|
||||
nat_check_ip_in_network(f"{label} redirect_to", r.get("redirect_to", ""), net)
|
||||
|
||||
# -- port_forwarding validation (top-level) --------------------------------
|
||||
# port_forwarding validation (top-level) ========================
|
||||
for idx, r in enumerate(data.get("port_forwarding", [])):
|
||||
desc = r.get("description", "?")
|
||||
label = f"port_forwarding[{idx}] '{desc}'"
|
||||
|
|
@ -709,13 +709,13 @@ def validate_config(data):
|
|||
if r.get("dst_port") is not None:
|
||||
nat_check_port(f"{label} dst_port", r.get("dst_port"))
|
||||
|
||||
# -- radius_default uniqueness check ---------------------------------------
|
||||
# radius_default uniqueness check ===============================
|
||||
defaults = [v["name"] for v in data.get("vlans", []) if v.get("radius_default") is True]
|
||||
if len(defaults) > 1:
|
||||
errors.append(f"Multiple VLANs have radius_default: true ({', '.join(defaults)}). "
|
||||
f"Only one VLAN may be the RADIUS default.")
|
||||
|
||||
# -- RADIUS requires multiple VLANs ----------------------------------------
|
||||
# RADIUS requires multiple VLANs ================================
|
||||
non_wg_vlans = [v for v in data.get("vlans", []) if not is_wg(v)]
|
||||
has_radius_clients = any(
|
||||
r.get("radius_client")
|
||||
|
|
@ -728,7 +728,7 @@ def validate_config(data):
|
|||
"Dynamic VLAN assignment requires at least two VLANs."
|
||||
)
|
||||
|
||||
# -- host_overrides validation ---------------------------------------------
|
||||
# host_overrides validation =====================================
|
||||
all_vlan_nets = list(vlan_networks.values())
|
||||
for idx, entry in enumerate(data.get("host_overrides", [])):
|
||||
lbl = f"host_overrides[{idx}] '{entry.get('host', '?')}'"
|
||||
|
|
@ -744,7 +744,7 @@ def validate_config(data):
|
|||
if all_vlan_nets and not any(ip_addr in net for net in all_vlan_nets):
|
||||
errors.append(f"{lbl}: '{ip_str}' does not fall within any configured VLAN subnet.")
|
||||
|
||||
# -- banned_ips validation -------------------------------------------------
|
||||
# banned_ips validation =========================================
|
||||
for idx, entry in enumerate(data.get("banned_ips", [])):
|
||||
ip_val = entry.get("ip", "")
|
||||
lbl = f"banned_ips[{idx}] '{entry.get('description', '')}'"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue