Skip to content
Snippets Groups Projects
Commit 10f94c52 authored by Ferenc Schulcz's avatar Ferenc Schulcz
Browse files

Load zone from master on startup

parent 8d1fbabb
No related branches found
No related tags found
No related merge requests found
......@@ -3,5 +3,10 @@
"knotLocation": "/usr/sbin/knotc",
"dbHost": "localhost",
"listenAddress": "127.0.0.1",
"listenPort": 3000
"listenPort": 3000,
"master": {
"address": "https://dyndns.example.com",
"myId": "ns-test",
"key": "verysecret"
}
}
\ No newline at end of file
......@@ -48,7 +48,28 @@ function updateDomain(domain, token, ip) {
Domain.updateOne({ token: token }, { name: domain, token: token, ip: ip })
.catch((err) => reject())
.then((d) => resolve());
})
});
}
function insertDomain(domain, token, ip) {
return new Promise((resolve, reject) => {
const record = new Domain({
name: domain,
token: token,
ip: ip
});
record.save()
.catch((err) => reject(err))
.then(() => resolve());
});
}
function clearDomains() {
return new Promise((resolve, reject) => {
Domain.deleteMany({})
.catch(err => reject(err))
.then(() => resolve());
});
}
module.exports = {
......@@ -56,5 +77,7 @@ module.exports = {
domainExists: domainExists,
registerDomain: registerDomain,
getDomain: getDomain,
updateDomain: updateDomain
updateDomain: updateDomain,
insertDomain: insertDomain,
clearDomains: clearDomains
}
\ No newline at end of file
const https = require('https');
const express = require('express');
// Initialize
// --------------------------------------------------------
const app = express();
const config = require('./config');
......@@ -7,9 +12,65 @@ config.init();
const db = require('./database');
db.init();
// Sync records from master
// --------------------------------------------------------
console.log("Syncing records from " + config.config().master.address + "/ ...");
https.get(config.config().master.address + '/dyndns-list?id=' + config.config().master.myId + '&key=' + config.config().master.key, (res) => {
if (res.statusCode > 299) {
process.exit(2);
return;
}
let response = '';
res.on('data', (chunk) => response += chunk);
res.on('end', () => {
db.clearDomains().then(() => {
knotdns.clearZone().then(() => {
console.log("Purged existing domains");
try {
records = JSON.parse(response);
async function loadRecords(records) {
for (const r of records) {
const domain = r.domain.split(".")[0];
const token = r.token;
const ip = r.ip;
if (ip == "null") {
await db.registerDomain(domain, token);
console.log("Registering record without IP: " + domain);
} else {
await db.insertDomain(domain, token, ip);
await knotdns.updateRecord(domain, ip);
console.log("Registering domain " + domain + " to " + ip);
}
};
}
loadRecords(records);
} catch (error) {
console.error("Error parsing records from master: ", error);
process.exit(1);
}
})
})
});
}).on('error', (error) => {
console.error("Could not sync records from master: ", error);
process.exit(1);
});
// Register and serve endpoints
// --------------------------------------------------------
const registerMW = require('./middleware/registerMW');
const replyMW = require('./middleware/replyMW');
const updateMW = require('./middleware/updateMW');
const { error } = require('console');
const knotdns = require('./knotdns');
// register a new dyndns record
app.get('/register', registerMW(), replyMW());
......
......@@ -3,6 +3,37 @@ const exec = util.promisify(require('child_process').exec);
const config = require('./config');
async function clearZone() {
const { stdout, stderr } = await exec(config.config().knotLocation + " zone-read " + config.config().higherLevelDomain);
const domains = stdout
.split('\n')
.filter(line => line.includes(' 60 A ')) //filter for A records
.map(line => line.match('\] (.*) 60 A ')[1]) // regex match for full domains
.map(domain => domain.split('.')[0]); // cut subdomain
await exec(config.config().knotLocation + " zone-begin " + config.config().higherLevelDomain);
for (domain of domains) {
await exec(config.config().knotLocation + " zone-unset " + config.config().higherLevelDomain + " " + domain);
}
await exec(config.config().knotLocation + " zone-commit " + config.config().higherLevelDomain);
}
async function insertRecord(domain, ip) {
try {
await exec(config.config().knotLocation + " zone-begin " + config.config().higherLevelDomain);
await exec(config.config().knotLocation + " zone-set " + config.config().higherLevelDomain + " " + domain + " 60 A " + ip);
await exec(config.config().knotLocation + " zone-commit " + config.config().higherLevelDomain);
} catch (error) {
try {
await exec(config.config().knotLocation + " zone-abort " + config.config().higherLevelDomain);
console.log("Problem with manipulating DNS zone " + config.config().higherLevelDomain + ". Aborted transaction. " + error);
} catch {
console.log("Problem with manipulating DNS zone " + config.config().higherLevelDomain + ". Could not even abort transaction. " + error);
}
}
}
async function updateRecord(domain, ip) {
try {
await exec(config.config().knotLocation + " zone-begin " + config.config().higherLevelDomain);
......@@ -23,6 +54,10 @@ async function updateRecord(domain, ip) {
}
}
module.exports = {
updateRecord: updateRecord
updateRecord: updateRecord,
insertRecord: insertRecord,
clearZone: clearZone
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment