This commit is contained in:
紫云徽 2024-08-05 13:25:59 +08:00
parent c9071abfba
commit 5b0fe3cff1
6 changed files with 75 additions and 44 deletions

View File

@ -4,6 +4,7 @@ docker-compose*
.dockerignore .dockerignore
.git .git
.gitignore .gitignore
.prettierrc
README.md README.md
LICENSE LICENSE
.vscode .vscode

4
.gitignore vendored
View File

@ -173,3 +173,7 @@ dist
# Finder (MacOS) folder config # Finder (MacOS) folder config
.DS_Store .DS_Store
.prettierrc
package-lock.json

View File

@ -1,6 +1,7 @@
FROM oven/bun:1 FROM oven/bun:latest
WORKDIR /usr/src/app WORKDIR /usr/src/app
COPY . . COPY . .
COPY config.json /etc/netgateswitch/config.json
RUN bun install --frozen-lockfile --production RUN bun install --frozen-lockfile --production
ENV NODE_ENV=production ENV NODE_ENV=production
EXPOSE 7000/tcp EXPOSE 7000/tcp

View File

@ -1,6 +1,8 @@
services: services:
netgate-switch: netgate-switch:
build: . build: .
ports: ports:
- "7000:7000" - '7000:7000'
restart: unless-stopped restart: unless-stopped
volumes:
- /home/ns:/etc/netgateswitch:ro

View File

@ -1,11 +1,11 @@
import { serve } from 'bun'; import { serve } from 'bun';
import { RouterOSAPI } from 'node-routeros'; import { RouterOSAPI } from 'node-routeros';
import cfg from './config.json'; import cfg from '/etc/netgateswitch/config.json';
let api = new RouterOSAPI({ let api = new RouterOSAPI({
host: cfg.host, host: cfg.host,
user: cfg.user, user: cfg.user,
password: cfg.password password: cfg.password,
}); });
const maincidr = cfg.maincidr; const maincidr = cfg.maincidr;
@ -13,26 +13,29 @@ const proxycidr = cfg.proxycidr;
let haslogin = cfg.login; let haslogin = cfg.login;
type Device = { type Device = {
'id': string, id: string;
'address': string, address: string;
'mac': string, mac: string;
'status': string, status: string;
'host': string, host: string;
'comment': string comment: string;
} };
let list: Device[] = []; let list: Device[] = [];
if (haslogin) { if (haslogin) {
if (!await connectAPI()) { if (!(await connectAPI())) {
haslogin = false; haslogin = false;
} }
} }
const server = serve({ const server = serve({
port: cfg.port, async fetch(request) { port: cfg.port,
async fetch(request) {
const url = new URL(request.url); const url = new URL(request.url);
if (url.pathname === '/') { if (url.pathname === '/') {
let file = haslogin ? Bun.file('./index.html') : Bun.file('./login.html'); let file = haslogin
? Bun.file('./index.html')
: Bun.file('./login.html');
return new Response(file); return new Response(file);
} }
@ -44,10 +47,16 @@ const server = serve({
api = new RouterOSAPI({ api = new RouterOSAPI({
host: data.host, host: data.host,
user: data.user, user: data.user,
password: data.password password: data.password,
}); });
if (await connectAPI()) { if (await connectAPI()) {
writeConfig(data.host, data.user, data.password, data.main, data.proxy); writeConfig(
data.host,
data.user,
data.password,
data.main,
data.proxy
);
console.log('配置文件已更新'); console.log('配置文件已更新');
return new Response('登入成功'); return new Response('登入成功');
} else { } else {
@ -56,17 +65,19 @@ const server = serve({
} }
if (url.pathname === '/core/get/') { if (url.pathname === '/core/get/') {
if (!haslogin) return new Response('ROS配置未设置', { status: 401 }); if (!haslogin)
return new Response('ROS配置未设置', { status: 401 });
return new Response(JSON.stringify(await getDHCPList())); return new Response(JSON.stringify(await getDHCPList()));
} }
if (url.pathname === '/core/switch/') { if (url.pathname === '/core/switch/') {
if (!haslogin) return new Response('ROS配置未设置', { status: 401 }); if (!haslogin)
return new Response('ROS配置未设置', { status: 401 });
let data = await request.json(); let data = await request.json();
let id = data.id; let id = data.id;
let mac = data.mac; let mac = data.mac;
let group = data.group; let group = data.group;
if ((id === '' && mac === '')) { if (id === '' && mac === '') {
return new Response('参数缺失', { status: 401 }); return new Response('参数缺失', { status: 401 });
} }
let isExists: boolean = false; let isExists: boolean = false;
@ -78,14 +89,14 @@ const server = serve({
isExists = true; isExists = true;
} }
} }
if ((!isExists)) { if (!isExists) {
return new Response('设备不存在', { status: 401 }); return new Response('设备不存在', { status: 401 });
} }
if (group !== 'main' && group !== 'proxy') { if (group !== 'main' && group !== 'proxy') {
return new Response('group错误', { status: 401 }); return new Response('group错误', { status: 401 });
} }
if (await switchNetgate(id, addr, group)) { if (await switchNetgate(id, addr, group)) {
return new Response('登入成功'); return new Response('切换成功');
} else { } else {
return new Response('切换失败', { status: 401 }); return new Response('切换失败', { status: 401 });
} }
@ -97,7 +108,7 @@ const server = serve({
} }
return new Response('Page not found', { status: 404 }); return new Response('Page not found', { status: 404 });
} },
}); });
console.log(`前端已开启: http://localhost:${server.port} ...`); console.log(`前端已开启: http://localhost:${server.port} ...`);
@ -118,12 +129,12 @@ async function getDHCPList() {
list = []; list = [];
for (let eq in result) { for (let eq in result) {
list.push({ list.push({
'id': result[eq]['.id'], id: result[eq]['.id'],
'address': result[eq]['address'], address: result[eq]['address'],
'mac': result[eq]['mac-address'], mac: result[eq]['mac-address'],
'status': result[eq]['status'], status: result[eq]['status'],
'host': result[eq]['host-name'], host: result[eq]['host-name'],
'comment': result[eq]['comment'], comment: result[eq]['comment'],
}); });
} }
return list; return list;
@ -132,7 +143,9 @@ async function getDHCPList() {
async function switchNetgate(id: string, addr: string, group: string) { async function switchNetgate(id: string, addr: string, group: string) {
try { try {
let mask = Number.parseInt(maincidr.split('/')[1]); let mask = Number.parseInt(maincidr.split('/')[1]);
let targetcidr = (group === 'proxy' ? proxycidr : maincidr).split('/')[0].split('.'); let targetcidr = (group === 'proxy' ? proxycidr : maincidr)
.split('/')[0]
.split('.');
let address = addr.split('.'); let address = addr.split('.');
let num = 2; let num = 2;
if (mask == 16) { if (mask == 16) {
@ -145,7 +158,10 @@ async function switchNetgate(id: string, addr: string, group: string) {
} }
console.log('原IP' + addr + '切换至' + address.join('.')); console.log('原IP' + addr + '切换至' + address.join('.'));
const result = await api.write('/ip/dhcp-server/lease/set', ['=.id=' + id, '=address=' + address.join('.')]); const result = await api.write('/ip/dhcp-server/lease/set', [
'=.id=' + id,
'=address=' + address.join('.'),
]);
return true; return true;
} catch (err) { } catch (err) {
console.log(err); console.log(err);
@ -153,7 +169,13 @@ async function switchNetgate(id: string, addr: string, group: string) {
} }
} }
async function writeConfig(host: string, user: string, password: string, mcidr: string, pcidr: string) { async function writeConfig(
host: string,
user: string,
password: string,
mcidr: string,
pcidr: string
) {
cfg.login = true; cfg.login = true;
cfg.host = host; cfg.host = host;
cfg.user = user; cfg.user = user;
@ -162,16 +184,16 @@ async function writeConfig(host: string, user: string, password: string, mcidr:
cfg.proxycidr = pcidr; cfg.proxycidr = pcidr;
haslogin = true; haslogin = true;
await Bun.write('./config.json', JSON.stringify(cfg)); await Bun.write('/etc/netgateswitch/config.json', JSON.stringify(cfg));
} }
async function cleanConfig() { async function cleanConfig() {
haslogin = false; haslogin = false;
cfg.login = false; cfg.login = false;
cfg.host = ""; cfg.host = '';
cfg.user = ""; cfg.user = '';
cfg.password = ""; cfg.password = '';
cfg.maincidr = ""; cfg.maincidr = '';
cfg.proxycidr = ""; cfg.proxycidr = '';
await Bun.write('./config.json', JSON.stringify(cfg)); await Bun.write('/etc/netgateswitch/config.json', JSON.stringify(cfg));
} }

View File

@ -12,6 +12,7 @@
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"netgate-switch": "file:",
"node-routeros": "^1.6.9" "node-routeros": "^1.6.9"
} }
} }