services/dhcp-inject: update to new templating pattern

- Organise helper functions by prefix (has_, get_)
- Extract configuration generation into focused function
- Use UCI helpers for consistent output formatting
- Add traceability comments for debugging
- Implement early validation with guard clauses
- Remove outdated test cases

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2025-10-19 16:09:56 +02:00
parent 5320e0c6c1
commit aa431900e3
11 changed files with 43 additions and 313 deletions

View File

@@ -1,74 +1,74 @@
{%
// Helper functions
function has_dhcp_inject_config() {
return services.is_present("dhcpinject");
function has_dhcp_inject_interfaces() {
let interfaces = services.lookup_interfaces_by_ssids("dhcp-inject");
return length(interfaces) > 0;
}
function get_dhcp_inject_ssids() {
return services.lookup_ssids("dhcp-inject");
function get_dhcp_inject_interfaces() {
return services.lookup_interfaces_by_ssids("dhcp-inject");
}
function has_dhcp_inject_ssids() {
let ssids = get_dhcp_inject_ssids();
return length(ssids) > 0;
}
function get_upstream_interfaces() {
let interfaces = get_dhcp_inject_interfaces();
let upstreams = [];
function get_dhcp_inject_ports() {
if (dhcp_inject && dhcp_inject.select_ports) {
return ethernet.lookup_by_select_ports(dhcp_inject.select_ports);
for (let iface in interfaces) {
if (iface.role == "upstream")
push(upstreams, iface);
}
return ["eth0"];
return upstreams;
}
function calculate_interface_count() {
let ssids = get_dhcp_inject_ssids();
let iface_count = 0;
for (let ssid in ssids) {
iface_count += length(ssid.wifi_bands);
}
return iface_count;
function has_upstream_interfaces() {
return length(get_upstream_interfaces()) > 0;
}
// Configuration generation functions
function generate_dhcp_inject_config() {
if (!has_dhcp_inject_config() || !has_dhcp_inject_ssids())
let upstreams = get_upstream_interfaces();
let enabled = has_upstream_interfaces();
services.set_enabled("dhcpinject", enabled);
if (!enabled)
return '';
let ports = get_dhcp_inject_ports();
let ssids = get_dhcp_inject_ssids();
let iface_count = calculate_interface_count();
let output = [];
uci_comment(output, '# generated by dhcp_inject.uc');
uci_comment(output, '### generate DHCP Inject service configuration');
// Configure uplink ports
uci_set_string(output, 'dhcpinject.uplink', 'device');
for (let port in ports) {
uci_list_string(output, 'dhcpinject.uplink.port', port);
}
for (let upstream in upstreams) {
let iface_name = ethernet.calculate_name(upstream);
let count = 0;
let freqs = [];
// Configure SSIDs
uci_set_string(output, 'dhcpinject.ssids', 'ssids');
for (let ssid in ssids) {
uci_list_string(output, 'dhcpinject.ssids.ssid', ssid.name);
}
uci_named_section(output, `dhcpinject.${upstream.name}`, 'network');
uci_set_string(output, `dhcpinject.${upstream.name}.upstream`, iface_name);
// Configure dhcpinject section
uci_set_string(output, 'dhcpinject.dhcpinject', 'dhcpinject');
uci_set_number(output, 'dhcpinject.dhcpinject.iface_count', iface_count);
for (let ssid in upstream.ssids) {
count += length(ssid.wifi_bands);
for (let freq in ssid.wifi_bands) {
push(freqs, freq);
uci_list_string(output, `dhcpinject.${upstream.name}.ssid${freq}`, ssid.name);
}
}
for (let freq in uniq(freqs))
uci_list_string(output, `dhcpinject.${upstream.name}.freq`, freq);
uci_set_number(output, `dhcpinject.${upstream.name}.count`, count);
}
return uci_output(output);
}
// Main logic
if (!has_dhcp_inject_config())
return;
let enable = has_dhcp_inject_ssids();
services.set_enabled("dhcpinject", enable);
if (!enable)
if (!has_dhcp_inject_interfaces())
return;
%}

View File

@@ -11,7 +11,6 @@ import * as fs from 'fs';
import { run_tests as admin_ui_tests } from './unit/services/admin_ui/test-admin_ui.uc';
import { run_tests as airtime_fairness_tests } from './unit/services/airtime_fairness/test-airtime_fairness.uc';
import { run_tests as captive_tests } from './unit/services/captive/test-captive.uc';
import { run_tests as dhcp_inject_tests } from './unit/services/dhcp_inject/test-dhcp_inject.uc';
import { run_tests as dhcp_relay_tests } from './unit/services/dhcp_relay/test-dhcp_relay.uc';
import { run_tests as dhcp_snooping_service_tests } from './unit/services/dhcp_snooping/test-dhcp_snooping.uc';
import { run_tests as fingerprint_tests } from './unit/services/fingerprint/test-fingerprint.uc';
@@ -236,7 +235,6 @@ function main() {
{ name: "Admin UI Service", run_tests: admin_ui_tests },
{ name: "Airtime Fairness Service", run_tests: airtime_fairness_tests },
{ name: "Captive Service", run_tests: captive_tests },
{ name: "DHCP Inject Service", run_tests: dhcp_inject_tests },
{ name: "DHCP Relay Service", run_tests: dhcp_relay_tests },
{ name: "DHCP Snooping Service", run_tests: dhcp_snooping_service_tests },
{ name: "Fingerprint Service", run_tests: fingerprint_tests },

View File

@@ -1,61 +0,0 @@
{
"uuid": 1,
"interfaces": [
{
"name": "WAN",
"role": "upstream",
"ethernet": [
{
"select-ports": [
"WAN"
]
}
],
"ipv4": {
"addressing": "dynamic"
}
},
{
"name": "downstream",
"role": "downstream",
"ethernet": [
{
"select-ports": [
"LAN*"
]
}
],
"ipv4": {
"addressing": "static",
"subnet": "192.168.1.1/24"
},
"ssids": [
{
"name": "TestWiFi",
"wifi-bands": [
"2G",
"5G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "testpassword123",
"ieee80211w": "optional"
},
"services": [
"dhcp-inject"
]
}
]
}
],
"services": {
"dhcp-inject": true
},
"dhcp_inject": {
"select_ports": [
"eth0",
"eth1"
]
}
}

View File

@@ -1,69 +0,0 @@
{
"uuid": 1,
"interfaces": [
{
"name": "WAN",
"role": "upstream",
"ethernet": [
{
"select-ports": [
"WAN"
]
}
],
"ipv4": {
"addressing": "dynamic"
}
},
{
"name": "downstream",
"role": "downstream",
"ethernet": [
{
"select-ports": [
"LAN*"
]
}
],
"ipv4": {
"addressing": "static",
"subnet": "192.168.1.1/24"
},
"ssids": [
{
"name": "TestWiFi",
"wifi-bands": [
"2G",
"5G",
"6G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "testpassword123"
},
"services": [
"dhcp-inject"
]
},
{
"name": "GuestWiFi",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "guestpassword456"
},
"services": [
"dhcp-inject"
]
}
]
}
],
"services": {
"dhcp-inject": true
}
}

View File

@@ -1,47 +0,0 @@
{
"uuid": 1,
"interfaces": [
{
"name": "WAN",
"role": "upstream",
"ethernet": [
{
"select-ports": [
"WAN"
]
}
],
"ipv4": {
"addressing": "dynamic"
}
},
{
"name": "downstream",
"role": "downstream",
"ethernet": [
{
"select-ports": [
"LAN*"
]
}
],
"ipv4": {
"addressing": "static",
"subnet": "192.168.1.1/24"
},
"ssids": [
{
"name": "TestWiFi",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "testpassword123"
}
}
]
}
]
}

View File

@@ -1,55 +0,0 @@
{
"uuid": 1,
"interfaces": [
{
"name": "WAN",
"role": "upstream",
"ethernet": [
{
"select-ports": [
"WAN"
]
}
],
"ipv4": {
"addressing": "dynamic"
}
},
{
"name": "downstream",
"role": "downstream",
"ethernet": [
{
"select-ports": [
"LAN*"
]
}
],
"ipv4": {
"addressing": "static",
"subnet": "192.168.1.1/24"
},
"ssids": [
{
"name": "TestWiFi",
"wifi-bands": [
"2G"
],
"bss-mode": "ap",
"encryption": {
"proto": "psk2",
"key": "testpassword123"
}
}
]
}
],
"services": {
"dhcp-inject": true
},
"dhcp_inject": {
"select_ports": [
"eth0"
]
}
}

View File

@@ -1,9 +0,0 @@
# generated by dhcp_inject.uc
### generate DHCP Inject service configuration
set dhcpinject.uplink='device'
set dhcpinject.ssids='ssids'
add_list dhcpinject.ssids.ssid='TestWiFi'
set dhcpinject.dhcpinject='dhcpinject'
set dhcpinject.dhcpinject.iface_count=0

View File

@@ -1,11 +0,0 @@
# generated by dhcp_inject.uc
### generate DHCP Inject service configuration
set dhcpinject.uplink='device'
add_list dhcpinject.uplink.port='eth0'
set dhcpinject.ssids='ssids'
add_list dhcpinject.ssids.ssid='TestWiFi'
add_list dhcpinject.ssids.ssid='GuestWiFi'
set dhcpinject.dhcpinject='dhcpinject'
set dhcpinject.dhcpinject.iface_count=0

View File

@@ -1,16 +0,0 @@
// DHCP Inject service template unit tests
"use strict";
import { TestFramework, create_service_test_cases } from '../../../helpers/test-framework.uc';
export function run_tests() {
let framework = TestFramework("../renderer/templates/services/dhcp_inject.uc", "DHCP Inject Service Template Tests", "unit/services/dhcp_inject");
let test_cases = create_service_test_cases("dhcp_inject", [
"dhcp_inject-basic",
"dhcp_inject-no-config",
"dhcp_inject-no-ssids",
"dhcp_inject-default-ports"
]);
return framework.run_tests(test_cases);
};