mirror of
https://github.com/dec0dOS/zero-ui.git
synced 2025-08-19 13:01:30 -07:00
feat: wip implementation of dns: {...} stanza handling
backend/services/network.js implements correct handling of dns: stanza required by ZeroNSd. Unfortunately this breaks frontend. I think this is because of delete statements. Unfortunately I know too little about nodejs to implement a proper solution. I tried mitigating problem using a copy of the data, but that didn't work. Anything else coming to mind seems to ugly to be 'right'.
This commit is contained in:
parent
5ce0bd1009
commit
0b77e9594b
3 changed files with 163 additions and 70 deletions
|
@ -4,7 +4,7 @@ const axios = require("axios");
|
|||
const api = require("../utils/controller-api");
|
||||
const db = require("../utils/db");
|
||||
const constants = require("../utils/constants");
|
||||
const startStopDNS = require("../utils/zns");
|
||||
const zns = require("../utils/zns");
|
||||
|
||||
async function getNetworkAdditionalData(data) {
|
||||
let additionalData = db
|
||||
|
@ -22,11 +22,22 @@ async function getNetworkAdditionalData(data) {
|
|||
delete data.remoteTraceLevel;
|
||||
delete data.remoteTraceTarget;
|
||||
|
||||
let ad = { ...additionalData.value() };
|
||||
data.dns = {
|
||||
domain: ad.dnsDomain,
|
||||
servers: ["pippo"],
|
||||
};
|
||||
if (ad.dnsIP) data.dns["servers"].push(ad.dnsIP);
|
||||
console.log(`*** dns="${JSON.stringify(ad)}" -> ${JSON.stringify(data.dns)}`);
|
||||
delete ad.dnsIP;
|
||||
delete ad.dnsDomain;
|
||||
delete ad.dnsEnable;
|
||||
delete ad.dnsWildcard;
|
||||
return {
|
||||
id: data.id,
|
||||
type: "Network",
|
||||
clock: Math.floor(new Date().getTime() / 1000),
|
||||
...additionalData.value(),
|
||||
...ad,
|
||||
config: data,
|
||||
};
|
||||
}
|
||||
|
@ -47,13 +58,11 @@ async function getNetworksData(nwids) {
|
|||
return [];
|
||||
});
|
||||
|
||||
let data = Promise.all(
|
||||
return Promise.all(
|
||||
multipleRes.map((el) => {
|
||||
return getNetworkAdditionalData(el.data);
|
||||
})
|
||||
);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
exports.createNetworkAdditionalData = createNetworkAdditionalData;
|
||||
|
@ -84,6 +93,12 @@ async function updateNetworkAdditionalData(nwid, data) {
|
|||
additionalData.rulesSource = data.rulesSource;
|
||||
}
|
||||
if (data.hasOwnProperty("dnsEnable")) {
|
||||
if (data.dnsEnable) {
|
||||
//TODO: start ZeroNSd and get its IP address
|
||||
additionalData.dnsIP = "127.0.0.1";
|
||||
} else {
|
||||
additionalData.dnsIP = null;
|
||||
}
|
||||
additionalData.dnsEnable = data.dnsEnable;
|
||||
}
|
||||
if (data.hasOwnProperty("dnsDomain")) {
|
||||
|
@ -101,17 +116,7 @@ async function updateNetworkAdditionalData(nwid, data) {
|
|||
.write();
|
||||
|
||||
if (data.hasOwnProperty("dnsEnable")) {
|
||||
let token = db.get("users").value()[0];
|
||||
token = token.token;
|
||||
let config = db.get("networks").find({ id: nwid }).value();
|
||||
let ret = startStopDNS(token, config.id, config.additionalConfig);
|
||||
if (ret) {
|
||||
db.get("networks")
|
||||
.filter({ id: nwid })
|
||||
.map("additionalConfig")
|
||||
.map((additionalConfig) => _.assign(additionalConfig, ret))
|
||||
.write();
|
||||
}
|
||||
zns.handleNet(db.get("networks").filter({ id: nwid }).value()[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,64 +1,147 @@
|
|||
const { spawn } = require("child_process");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
function pidIsRunning(pid) {
|
||||
try {
|
||||
process.kill(pid, 0);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
const db = require("../utils/db");
|
||||
const cp = require("child_process");
|
||||
|
||||
//TODO: does this kind of "optimization" make sense in Node.js?
|
||||
let token = null;
|
||||
function getToken() {
|
||||
if (!token)
|
||||
try {
|
||||
token = db.get("users").value()[0].token;
|
||||
} catch {
|
||||
console.warn("*** token retrieval failed");
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
function setPid(nwid, pid) {
|
||||
db.get("networks")
|
||||
.filter({ id: nwid })
|
||||
.map("additionalConfig")
|
||||
.map((additionalConfig) => (additionalConfig.pidDNS = pid))
|
||||
.write();
|
||||
}
|
||||
|
||||
const isRunning = (query, pid) => {
|
||||
return new Promise(function (resolve) {
|
||||
//FIXME: Check if pgrep is available
|
||||
cp.exec(`pgrep ${query}`, (err, stdout) => {
|
||||
resolve(stdout.indexOf(`${pid}`) > -1);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function startDNS(token, nwid, conf) {
|
||||
if (conf.hasOwnProperty("pidDNS")) {
|
||||
if (pidIsRunning(conf.pidDNS)) {
|
||||
return null;
|
||||
//FIXME: check it does the right thing when conf.pidDNS is null/undefined
|
||||
isRunning("zeronsd", conf.pidDNS).then((ok) => {
|
||||
if (ok) {
|
||||
console.log(
|
||||
`startDNS(${token}, ${nwid}): already active on PID ${conf.pidDNS}`
|
||||
);
|
||||
} else {
|
||||
let cmd = "zeronsd";
|
||||
let opts = Array();
|
||||
if (process.geteuid() === 0) {
|
||||
// production in Docker container
|
||||
} else {
|
||||
// we are debugging
|
||||
let myLocal = "/home/mcon/.cargo/bin";
|
||||
let pth = process.env.PATH.split(path.delimiter);
|
||||
if (!pth.includes(myLocal)) pth.push(myLocal);
|
||||
if (
|
||||
!process.env.PATH.split(path.delimiter).some(function (d) {
|
||||
let e = path.resolve(d, cmd);
|
||||
console.log(`*** PATH testing: "${d}" -> "${e}"`);
|
||||
try {
|
||||
fs.accessSync(e, fs.constants.X_OK);
|
||||
console.log(" is executable");
|
||||
cmd = "sudo";
|
||||
opts.push("-E", e);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.warn(` cannot execute (${e})`);
|
||||
return false;
|
||||
}
|
||||
})
|
||||
) {
|
||||
console.error(`*** zeronsd not found in PATH (${process.env.PATH})`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
opts.push("start", "-v", "-v");
|
||||
if (conf.hasOwnProperty("dnsWildcard") && conf.dnsWildcard) {
|
||||
opts.push("-w");
|
||||
}
|
||||
if (conf.hasOwnProperty("dnsDomain") && !!conf.dnsDomain) {
|
||||
opts.push("-d", conf.dnsDomain);
|
||||
}
|
||||
opts.push(nwid);
|
||||
process.env.ZEROTIER_CENTRAL_TOKEN = token;
|
||||
console.log(`*** PATH: "${process.env.PATH}"`);
|
||||
console.log(
|
||||
`*** ZEROTIER_CENTRAL_TOKEN: "${process.env.ZEROTIER_CENTRAL_TOKEN}"`
|
||||
);
|
||||
let dns = cp.spawn(cmd, opts, { detached: true });
|
||||
dns.on("spawn", () => {
|
||||
console.log(
|
||||
`zeronsd successfully spawned [${dns.pid}](${dns.spawnargs})`
|
||||
);
|
||||
setPid(nwid, dns.pid);
|
||||
});
|
||||
dns.stdout.on("data", (data) => {
|
||||
console.log(`zeronsd spawn stdout: ${data}`);
|
||||
});
|
||||
dns.stderr.on("data", (data) => {
|
||||
console.error(`zeronsd spawn stderr: ${data}`);
|
||||
});
|
||||
dns.on("error", (error) => {
|
||||
console.log(`zeronsd spawn ERROR: [${error}](${dns.spawnargs})`);
|
||||
});
|
||||
dns.on("close", (code) => {
|
||||
console.log(`zeronsd exited: [${code}](${dns.spawnargs})`);
|
||||
setPid(nwid, null);
|
||||
});
|
||||
}
|
||||
delete conf.pidDNS;
|
||||
}
|
||||
const opts = Array("start");
|
||||
if (conf.hasOwnProperty("dnsWildcard") && conf.dnsWildcard) {
|
||||
opts.push("-w");
|
||||
}
|
||||
if (conf.hasOwnProperty("dnsDomain") && !!conf.dnsDomain) {
|
||||
opts.push("-d", conf.dnsDomain);
|
||||
}
|
||||
opts.push(nwid);
|
||||
let env = process.env;
|
||||
env.ZEROTIER_CENTRAL_TOKEN = token;
|
||||
console.log(`*** PATH: "${env.PATH}"`);
|
||||
const dns = spawn("zeronsd", opts, {
|
||||
detached: true,
|
||||
env: env,
|
||||
});
|
||||
dns.on("spawn", () => {
|
||||
console.log(`zeronsd successfully spawned [${dns.pid}](${dns.spawnargs})`);
|
||||
console.log("*** should update PID ***");
|
||||
});
|
||||
dns.on("error", (error) => {
|
||||
console.log(`zeronsd spawn ERROR: [${error}](${dns.spawnargs})`);
|
||||
});
|
||||
conf.pidDNS = dns.pid;
|
||||
return conf;
|
||||
}
|
||||
|
||||
function stopDNS(conf) {
|
||||
if (conf.hasOwnProperty("pidDNS")) {
|
||||
try {
|
||||
process.kill(conf.pidDNS);
|
||||
} catch (e) {}
|
||||
delete conf.pidDNS;
|
||||
return conf;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = function (token, nwid, conf) {
|
||||
let ret;
|
||||
if (conf.dnsEnable) {
|
||||
ret = startDNS(token, nwid, conf);
|
||||
function stopDNS(nwid, conf) {
|
||||
let pid = conf.pidDNS;
|
||||
if (pid) {
|
||||
isRunning("zeronsd", pid).then((ok) => {
|
||||
if (ok) {
|
||||
console.log(`stopDNS(${nwid}): stopping PID ${pid}`);
|
||||
try {
|
||||
process.kill(pid);
|
||||
} catch (e) {
|
||||
console.error(`stopDNS(${nwid}): stopping PID ${pid} FAILED (${e})`);
|
||||
}
|
||||
} else {
|
||||
console.log(`stopDNS(${nwid}): PID ${pid} is stale`);
|
||||
}
|
||||
});
|
||||
setPid(nwid, null);
|
||||
} else {
|
||||
ret = stopDNS(conf);
|
||||
console.log(`stopDNS(${nwid}): net has no PID`);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
exports.handleNet = handleNet;
|
||||
function handleNet(net) {
|
||||
let cfg = net.additionalConfig;
|
||||
if (cfg.dnsEnable) {
|
||||
startDNS(getToken(), net.id, cfg);
|
||||
} else {
|
||||
stopDNS(net.id, cfg);
|
||||
}
|
||||
}
|
||||
|
||||
exports.scan = scan;
|
||||
function scan() {
|
||||
let nets = db.get("networks").value();
|
||||
nets.forEach((net) => {
|
||||
handleNet(net);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -41,6 +41,11 @@ function NetworkSettings({ network, setNetwork }) {
|
|||
sendReq(data);
|
||||
};
|
||||
|
||||
console.log(
|
||||
`*** dns="${JSON.stringify(network)}" -> ${JSON.stringify(
|
||||
network["config"]
|
||||
)}`
|
||||
);
|
||||
return (
|
||||
<Accordion>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue