125 lines
4.5 KiB
JavaScript
125 lines
4.5 KiB
JavaScript
// src/services/opnsenseClient.js
|
|
// Uses OPNsense HAProxy plugin API (add_backend → add_server → add_frontend → reconfigure)
|
|
|
|
import axios from 'axios';
|
|
import https from 'https';
|
|
|
|
const BASE = process.env.OPNSENSE_API_URL;
|
|
const KEY = process.env.OPNSENSE_API_KEY;
|
|
const SECRET = process.env.OPNSENSE_API_SECRET;
|
|
const TIMEOUT_MS = Number(process.env.OPNSENSE_TIMEOUT_MS || 10000);
|
|
|
|
const client = axios.create({
|
|
baseURL: BASE,
|
|
timeout: TIMEOUT_MS,
|
|
httpsAgent: new https.Agent({ rejectUnauthorized: false }),
|
|
auth: { username: KEY, password: SECRET },
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
|
|
// ----------------------------------------------------------------------
|
|
// Health
|
|
// ----------------------------------------------------------------------
|
|
export async function health() {
|
|
try {
|
|
const { data } = await client.get('/haproxy/service/status');
|
|
return data?.status ? true : false;
|
|
} catch (e) {
|
|
console.warn('[opnsense] health check failed:', e.message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
// Create HAProxy backend + server + frontend
|
|
// ----------------------------------------------------------------------
|
|
export async function createPortForward({ vmid, publicPort, privateIp, privatePort }) {
|
|
const backendName = `zpack-backend-${vmid}-${publicPort}`;
|
|
const serverName = `srv-${vmid}-${publicPort}`;
|
|
const frontendName = `zpack-frontend-${vmid}-${publicPort}`;
|
|
|
|
try {
|
|
// 1. Create backend
|
|
const backendPayload = {
|
|
Backend: {
|
|
name: backendName,
|
|
description: `Backend for vmid=${vmid}`,
|
|
mode: 'tcp',
|
|
enabled: '1',
|
|
},
|
|
};
|
|
console.log('[opnsense] add_backend payload=', backendPayload);
|
|
const backendRes = await client.post('/haproxy/settings/add_backend', backendPayload);
|
|
const backendUuid = backendRes?.data?.uuid;
|
|
console.log('[opnsense] add_backend result=', backendRes.data);
|
|
|
|
// 2. Create server bound to backend
|
|
const serverPayload = {
|
|
Server: {
|
|
name: serverName,
|
|
description: `Server for vmid=${vmid}`,
|
|
address: privateIp,
|
|
port: String(privatePort),
|
|
enabled: '1',
|
|
backend: backendUuid,
|
|
},
|
|
};
|
|
console.log('[opnsense] add_server payload=', serverPayload);
|
|
const serverRes = await client.post('/haproxy/settings/add_server', serverPayload);
|
|
console.log('[opnsense] add_server result=', serverRes.data);
|
|
|
|
// 3. Create frontend bound to backend
|
|
const frontendPayload = {
|
|
Frontend: {
|
|
name: frontendName,
|
|
description: `Frontend for vmid=${vmid}`,
|
|
enabled: '1',
|
|
listenAddress: '0.0.0.0',
|
|
listenPort: String(publicPort),
|
|
mode: 'tcp',
|
|
default_backend: backendUuid,
|
|
},
|
|
};
|
|
console.log('[opnsense] add_frontend payload=', frontendPayload);
|
|
const frontendRes = await client.post('/haproxy/settings/add_frontend', frontendPayload);
|
|
const frontendUuid = frontendRes?.data?.uuid;
|
|
console.log('[opnsense] add_frontend result=', frontendRes.data);
|
|
|
|
// 4. Apply changes
|
|
const reconfigRes = await client.post('/haproxy/service/reconfigure');
|
|
console.log('[opnsense] reconfigure result=', reconfigRes.data);
|
|
|
|
return { ok: true, backend: backendRes.data, server: serverRes.data, frontend: frontendRes.data, reconfig: reconfigRes.data };
|
|
} catch (e) {
|
|
console.error('[opnsense] createPortForward error:');
|
|
if (e.response?.data) {
|
|
console.error('Response body:', JSON.stringify(e.response.data, null, 2));
|
|
} else {
|
|
console.error(e.message || e);
|
|
}
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
// Delete frontend + backend (and implicitly server)
|
|
// ----------------------------------------------------------------------
|
|
export async function deletePortForward({ backendUuid, frontendUuid }) {
|
|
try {
|
|
if (frontendUuid) {
|
|
await client.post(`/haproxy/settings/del_frontend/${frontendUuid}`);
|
|
}
|
|
if (backendUuid) {
|
|
await client.post(`/haproxy/settings/del_backend/${backendUuid}`);
|
|
}
|
|
const reconfigRes = await client.post('/haproxy/service/reconfigure');
|
|
console.log('[opnsense] delete reconfigure result=', reconfigRes.data);
|
|
return { ok: true, reconfig: reconfigRes.data };
|
|
} catch (e) {
|
|
console.error('[opnsense] deletePortForward error:', e.response?.data || e.message);
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
export default { health, createPortForward, deletePortForward };
|