v1.0
This commit is contained in:
parent
29cc87399e
commit
efacb10259
@ -1 +1 @@
|
|||||||
{"login":true,"host":"10.225.0.1","user":"lan","password":"xp258147","maincidr":"10.225.1.0/24","proxycidr":"10.225.2.0/24"}
|
{"port":7000,"login":false,"host":"","user":"","password":"","maincidr":"","proxycidr":""}
|
149
index.html
149
index.html
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 30rem;
|
max-width: 60rem;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
@ -35,10 +35,20 @@
|
|||||||
box-shadow: 0.5rem 0.5rem 1rem rgba(0, 0, 0, 0.2);
|
box-shadow: 0.5rem 0.5rem 1rem rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 20rem;
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
width: 3rem;
|
width: 6rem;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
margin-bottom: 1rem;
|
margin: 0.2rem;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background-color: #dfdfdf;
|
background-color: #dfdfdf;
|
||||||
@ -54,24 +64,46 @@
|
|||||||
box-shadow: 0 3px #666;
|
box-shadow: 0 3px #666;
|
||||||
transform: translateY(2px);
|
transform: translateY(2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<h1 class="title">NetgateSwitch</h1>
|
<h1 class="title">NetgateSwitch</h1>
|
||||||
<form>
|
<div class="container">
|
||||||
<div class="text-area">
|
<table id="table">
|
||||||
|
</table>
|
||||||
</div>
|
<button class="btn" id="delcfg" style="margin-bottom: 1rem;">删除配置</button>
|
||||||
<button class="btn" id="getlist">获取</button>
|
</div>
|
||||||
<button class="btn" id="switchaddr">更改</button>
|
|
||||||
</form>
|
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('getlist').addEventListener('click', async (event) => {
|
document.getElementById("delcfg").addEventListener('click', async () => {
|
||||||
|
try {
|
||||||
|
let res = await fetch('./core/logout/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}, body: {}
|
||||||
|
});
|
||||||
|
if (!res.ok) {
|
||||||
|
alert(await res.text());
|
||||||
|
} else {
|
||||||
|
window.location.href = "./";
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
getDHCPList();
|
||||||
|
|
||||||
|
async function getDHCPList() {
|
||||||
try {
|
try {
|
||||||
let res = await fetch('./core/get/', {
|
let res = await fetch('./core/get/', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -81,30 +113,89 @@
|
|||||||
});
|
});
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
alert(await res.text());
|
alert(await res.text());
|
||||||
|
} else {
|
||||||
|
showDevices(await res.json());
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
document.getElementById('switchaddr').addEventListener('click', async (event) => {
|
|
||||||
try {
|
|
||||||
let res = await fetch('./core/switch/', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}, body: JSON.stringify({
|
|
||||||
id: 'a',
|
|
||||||
group: 'main',
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) {
|
function showDevices(list) {
|
||||||
alert(await res.text());
|
const tb = document.getElementById('table');
|
||||||
}
|
let trn = document.createElement('tr');
|
||||||
} catch (err) {
|
let td1 = document.createElement('td');
|
||||||
console.log(err);
|
let td2 = document.createElement('td');
|
||||||
|
let td3 = document.createElement('td');
|
||||||
|
let td4 = document.createElement('td');
|
||||||
|
let btn = document.createElement('button');
|
||||||
|
while (tb.firstChild) {
|
||||||
|
tb.removeChild(tb.firstChild);
|
||||||
}
|
}
|
||||||
});
|
td1.setAttribute('scope', 'col');
|
||||||
|
td1.append('设备名');
|
||||||
|
td2.setAttribute('scope', 'col');
|
||||||
|
td2.append('IP地址');
|
||||||
|
td3.setAttribute('scope', 'col');
|
||||||
|
td3.append('MAC地址');
|
||||||
|
td4.setAttribute('scope', 'col');
|
||||||
|
td4.append('操作');
|
||||||
|
trn.append(td1, td2, td3, td4);
|
||||||
|
tb.append(trn);
|
||||||
|
for (let i in list) {
|
||||||
|
trn = document.createElement('tr');
|
||||||
|
td1 = document.createElement('td');
|
||||||
|
td2 = document.createElement('td');
|
||||||
|
td3 = document.createElement('td');
|
||||||
|
td4 = document.createElement('td');
|
||||||
|
btn1 = document.createElement('button');
|
||||||
|
btn1.setAttribute('class', 'btn swbtn');
|
||||||
|
btn1.setAttribute('cidrgroup', 'main');
|
||||||
|
btn1.setAttribute('deviceid', list[i].id);
|
||||||
|
btn1.append('切换至Main');
|
||||||
|
btn2 = document.createElement('button');
|
||||||
|
btn2.setAttribute('class', 'btn swbtn');
|
||||||
|
btn2.setAttribute('cidrgroup', 'proxy');
|
||||||
|
btn2.setAttribute('deviceid', list[i].id);
|
||||||
|
btn2.append('切换至Proxy');
|
||||||
|
td1.append(list[i].host);
|
||||||
|
td2.append(list[i].address);
|
||||||
|
td3.append(list[i].mac);
|
||||||
|
td4.append(btn1);
|
||||||
|
td4.append(btn2);
|
||||||
|
trn.append(td1, td2, td3, td4);
|
||||||
|
tb.append(trn);
|
||||||
|
}
|
||||||
|
bindEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindEvent() {
|
||||||
|
document.querySelectorAll('.swbtn').forEach((button) => {
|
||||||
|
button.addEventListener('click', async () => {
|
||||||
|
try {
|
||||||
|
let res = await fetch('./core/switch/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}, body: JSON.stringify({
|
||||||
|
id: button.getAttribute('deviceid'),
|
||||||
|
group: button.getAttribute('cidrgroup'),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
console.log(button.getAttribute('cidrgroup'));
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
alert(await res.text());
|
||||||
|
} else {
|
||||||
|
alert('切换成功');
|
||||||
|
window.location.href = "./";
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</html>
|
</html>
|
122
index.ts
122
index.ts
@ -1,16 +1,27 @@
|
|||||||
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 './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
|
||||||
});
|
});
|
||||||
let haslogin = cfg.login;
|
|
||||||
const maincidr = cfg.maincidr;
|
const maincidr = cfg.maincidr;
|
||||||
const proxycidr = cfg.proxycidr;
|
const proxycidr = cfg.proxycidr;
|
||||||
|
|
||||||
|
let haslogin = cfg.login;
|
||||||
|
type Device = {
|
||||||
|
'id': string,
|
||||||
|
'address': string,
|
||||||
|
'mac': string,
|
||||||
|
'status': string,
|
||||||
|
'host': string,
|
||||||
|
'comment': string
|
||||||
|
}
|
||||||
|
let list: Device[] = [];
|
||||||
|
|
||||||
if (haslogin) {
|
if (haslogin) {
|
||||||
if (!await connectAPI()) {
|
if (!await connectAPI()) {
|
||||||
haslogin = false;
|
haslogin = false;
|
||||||
@ -18,17 +29,17 @@ if (haslogin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const server = serve({
|
const server = serve({
|
||||||
port: 3000, 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.pathname === "/core/login/") {
|
if (url.pathname === '/core/login/') {
|
||||||
let data = await request.json();
|
let data = await request.json();
|
||||||
if (data.user === "" || data.password === "" || data.host === "") {
|
if (data.user === '' || data.password === '' || data.host === '') {
|
||||||
return new Response("参数错误", { status: 400 });
|
return new Response('参数缺失', { status: 400 });
|
||||||
}
|
}
|
||||||
api = new RouterOSAPI({
|
api = new RouterOSAPI({
|
||||||
host: data.host,
|
host: data.host,
|
||||||
@ -37,71 +48,109 @@ const server = serve({
|
|||||||
});
|
});
|
||||||
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 {
|
||||||
return new Response("ROS登入失败", { status: 400 });
|
return new Response('ROS登入失败', { status: 400 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 === "") || group === "") {
|
if ((id === '' && mac === '')) {
|
||||||
return new Response("400 Bad Request", { status: 400 });
|
return new Response('参数缺失', { status: 401 });
|
||||||
|
}
|
||||||
|
let isExists: boolean = false;
|
||||||
|
let addr = '';
|
||||||
|
for (let i in list) {
|
||||||
|
if (list[i].id === id || list[i].mac === mac) {
|
||||||
|
id = list[i].id;
|
||||||
|
addr = list[i].address;
|
||||||
|
isExists = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((!isExists)) {
|
||||||
|
return new Response('设备不存在', { status: 401 });
|
||||||
|
}
|
||||||
|
if (group !== 'main' && group !== 'proxy') {
|
||||||
|
return new Response('group错误', { status: 401 });
|
||||||
|
}
|
||||||
|
if (await switchNetgate(id, addr, group)) {
|
||||||
|
return new Response('登入成功');
|
||||||
|
} else {
|
||||||
|
return new Response('切换失败', { status: 401 });
|
||||||
}
|
}
|
||||||
switchNetgate('*458',group);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.pathname === "/core/logout/") {
|
if (url.pathname === '/core/logout/') {
|
||||||
cleanConfig();
|
cleanConfig();
|
||||||
return new Response("已登出");
|
return new Response('已登出');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response("Page not found", { status: 404 });
|
return new Response('Page not found', { status: 404 });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(`Listening on http://localhost:${server.port} ...`);
|
console.log(`前端已开启: http://localhost:${server.port} ...`);
|
||||||
|
|
||||||
async function connectAPI() {
|
async function connectAPI() {
|
||||||
try {
|
try {
|
||||||
await api.connect();
|
await api.connect();
|
||||||
console.log("API登入成功");
|
console.log('API登入成功');
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
console.log("API登入失败");
|
console.log('API登入失败');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getDHCPList() {
|
async function getDHCPList() {
|
||||||
const result = await api.write('/ip/dhcp-server/lease/print');
|
const result = await api.write('/ip/dhcp-server/lease/print');
|
||||||
let 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-address': result[eq]['mac-address'],
|
'mac': result[eq]['mac-address'],
|
||||||
'status': result[eq]['status'],
|
'status': result[eq]['status'],
|
||||||
'host-name': result[eq]['host-name'],
|
'host': result[eq]['host-name'],
|
||||||
'comment': result[eq]['comment'],
|
'comment': result[eq]['comment'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
console.log(list);
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function switchNetgate(id:string,group:string) {
|
async function switchNetgate(id: string, addr: string, group: string) {
|
||||||
const result = await api.write('/ip/dhcp-server/lease/set',['=.id='+id,'=address='+(group==='proxy'?'10.225.1.100':'10.225.0.100')]);
|
try {
|
||||||
|
let mask = Number.parseInt(maincidr.split('/')[1]);
|
||||||
|
let targetcidr = (group === 'proxy' ? proxycidr : maincidr).split('/')[0].split('.');
|
||||||
|
let address = addr.split('.');
|
||||||
|
let num = 2;
|
||||||
|
if (mask == 16) {
|
||||||
|
num = 1;
|
||||||
|
} else if (mask == 8) {
|
||||||
|
num = 0;
|
||||||
|
}
|
||||||
|
for (let i = 0; i <= num; i++) {
|
||||||
|
address[i] = targetcidr[i];
|
||||||
|
}
|
||||||
|
console.log('原IP' + addr + '切换至' + address.join('.'));
|
||||||
|
|
||||||
|
const result = await api.write('/ip/dhcp-server/lease/set', ['=.id=' + id, '=address=' + address.join('.')]);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -113,11 +162,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('./config.json', JSON.stringify(cfg));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cleanConfig() {
|
async function cleanConfig() {
|
||||||
cfg.login = false;
|
|
||||||
haslogin = false;
|
haslogin = false;
|
||||||
await Bun.write("./config.json", JSON.stringify(cfg));
|
cfg.login = false;
|
||||||
|
cfg.host = "";
|
||||||
|
cfg.user = "";
|
||||||
|
cfg.password = "";
|
||||||
|
cfg.maincidr = "";
|
||||||
|
cfg.proxycidr = "";
|
||||||
|
await Bun.write('./config.json', JSON.stringify(cfg));
|
||||||
}
|
}
|
@ -108,7 +108,7 @@
|
|||||||
if(!res.ok){
|
if(!res.ok){
|
||||||
alert(await res.text());
|
alert(await res.text());
|
||||||
}else{
|
}else{
|
||||||
window.location.href("./");
|
window.location.href="./";
|
||||||
}
|
}
|
||||||
}catch(err){
|
}catch(err){
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user