WireGuard access classes, firewall nftables fixes, network sync event refactor
- WireGuard: refactor to multi-interface 'access classes' model; extract config generation and helpers into lib/wireguard.py; add per-class up/down endpoints and API routes; update UI with class management pages and QR code component - Firewall: fix zone creation with --new-zone before --set-target; skip masquerade on public zone; add masquerade propagation for nftables backend so NAT works when internal zones exit via public - Network: rename sync event subsystem 'network' -> 'networkd'; always stamp config hash even when deployment fails (fixes pending-changes detection) - DHCP: add new API endpoint and update frontend page - State/Sync: update state collectors and sync buses for new subsystems - Docs: update API and config documentation for new endpoints and schemas
This commit is contained in:
@@ -172,6 +172,30 @@ export default definePage({
|
||||
</td>
|
||||
</tr>`);
|
||||
|
||||
const _setDomain = async (domain) => {
|
||||
const res = await apiFetch('/api/dhcp/domain', {
|
||||
method: 'POST',
|
||||
body: { domain },
|
||||
});
|
||||
if (res.ok) {
|
||||
toast('DNS domain updated', 'success');
|
||||
modelFetch('dnsmasq');
|
||||
} else {
|
||||
toast(res.error || 'Failed to update', 'error');
|
||||
}
|
||||
};
|
||||
|
||||
const currentDomain = dnsCfg.domain || null;
|
||||
const domainSection = html`<div class="domain-config" style="margin-bottom: 1rem;">
|
||||
<label style="font-weight: 600;">Search Domain</label>
|
||||
<p class="text-sm" style="margin: 0.25rem 0 0.5rem;">${currentDomain ? esc(currentDomain) : '<span class="text-muted">(not set)</span>'}</p>
|
||||
<div class="form-inline" style="display: flex; gap: 0.5rem; align-items: center;">
|
||||
<input id="domain-input" class="input" placeholder="example.local" />
|
||||
<button class="btn btn-outline" onClick=${() => _setDomain(($val('domain-input') || '').trim())}>Set</button>
|
||||
<button class="btn btn-outline" onClick=${() => _setDomain(null)}>Clear</button>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
const tabNames = ['ranges', 'leases', 'dns', 'active'];
|
||||
const actions = ActionGroup(
|
||||
html`<button class="btn btn-primary" onClick=${() => makeAddRange(state.firewall.data?.zones?.active, state.firewall.data?.interfaces)(state)}>Add Range</button>`,
|
||||
@@ -222,7 +246,10 @@ export default definePage({
|
||||
state.activeTab === 'leases'
|
||||
? Table({ columns: ['MAC', 'IP', 'Hostname', 'Action'], rows: leaseRows, emptyText: 'No static leases' }) : null,
|
||||
state.activeTab === 'dns'
|
||||
? Table({ columns: ['Name', 'Address', 'Action'], rows: dnsRows, emptyText: 'No custom DNS records' }) : null,
|
||||
? [
|
||||
domainSection,
|
||||
Table({ columns: ['Name', 'Address', 'Action'], rows: dnsRows, emptyText: 'No custom DNS records' })
|
||||
] : null,
|
||||
leaseTable,
|
||||
];
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user