automatically add `id` to modules and domains

This commit is contained in:
tigerbot 2017-10-04 18:27:29 -06:00
parent d04b750f87
commit 0380a8087f
1 changed files with 111 additions and 61 deletions

View File

@ -8,6 +8,7 @@ if (!cluster.isMaster) {
return; return;
} }
var crypto = require('crypto');
var PromiseA = require('bluebird'); var PromiseA = require('bluebird');
var fs = PromiseA.promisifyAll(require('fs')); var fs = PromiseA.promisifyAll(require('fs'));
var configStorage; var configStorage;
@ -25,7 +26,45 @@ function mergeSettings(orig, changes) {
} }
}); });
} }
function createStorage(filename, filetype) {
function fixRawConfig(config) {
var updated = false;
function updateModules(list) {
if (!Array.isArray(list)) {
return;
}
list.forEach(function (mod) {
if (!mod.id) {
mod.id = crypto.randomBytes(8).toString('hex');
updated = true;
}
});
}
function updateDomains(list) {
if (!Array.isArray(list)) {
return;
}
list.forEach(function (mod) {
if (!mod.id) {
mod.id = crypto.randomBytes(8).toString('hex');
updated = true;
}
updateModules(mod.modules);
});
}
[ 'dns', 'tcp', 'http', 'tls' ].forEach(function (key) {
if (!config[key]) {
return;
}
updateModules(config[key].modules);
updateDomains(config[key].domains);
});
return updated;
}
async function createStorage(filename, filetype) {
var recase = require('recase').create({}); var recase = require('recase').create({});
var snakeCopy = recase.snakeCopy.bind(recase); var snakeCopy = recase.snakeCopy.bind(recase);
var camelCopy = recase.camelCopy.bind(recase); var camelCopy = recase.camelCopy.bind(recase);
@ -40,13 +79,25 @@ function createStorage(filename, filetype) {
dump = yaml.safeDump; dump = yaml.safeDump;
} }
function read() { async function read() {
return fs.readFileAsync(filename).then(parse).catch(function (err) { var text;
try {
text = await fs.readFileAsync(filename);
} catch (err) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
return ''; return {};
} }
return PromiseA.reject(err); throw err;
}); }
var rawConfig = parse(text);
if (fixRawConfig(rawConfig)) {
await fs.writeFileAsync(filename, dump(rawConfig));
text = await fs.readFileAsync(filename);
rawConfig = parse(text);
}
return rawConfig;
} }
var result = { var result = {
@ -76,72 +127,71 @@ function createStorage(filename, filetype) {
}; };
return result; return result;
} }
function checkConfigLocation(cwd, configFile) { async function checkConfigLocation(cwd, configFile) {
cwd = cwd || process.cwd(); cwd = cwd || process.cwd();
var path = require('path'); var path = require('path');
var filename; var filename, text;
var prom;
if (configFile) { if (configFile) {
filename = path.resolve(cwd, configFile); filename = path.resolve(cwd, configFile);
prom = fs.readFileAsync(filename) try {
.catch(function (err) { text = await fs.readFileAsync(filename);
if (err.code !== 'ENOENT') { } catch (err) {
return PromiseA.reject(err); if (err.code !== 'ENOENT') {
} throw err;
if (path.extname(filename) === '.json') { }
return '{}'; if (path.extname(filename) === '.json') {
} return { name: filename, type: 'json' };
return ''; } else {
}) return { name: filename, type: 'yaml' };
; }
}
} else { } else {
prom = PromiseA.reject('blah') // Note that `path.resolve` can handle both relative and absolute paths.
.catch(function () { var defLocations = [
filename = path.resolve(cwd, 'goldilocks.yml'); path.resolve(cwd, 'goldilocks.yml')
return fs.readFileAsync(filename); , path.resolve(cwd, 'goldilocks.json')
}) , path.resolve(cwd, 'etc/goldilocks/goldilocks.yml')
.catch(function () { , '/etc/goldilocks/goldilocks.yml'
filename = path.resolve(cwd, 'goldilocks.json'); , path.resolve(cwd, 'goldilocks.yml')
return fs.readFileAsync(filename); ];
})
.catch(function () { var ind;
filename = path.resolve(cwd, 'etc/goldilocks/goldilocks.yml'); for (ind = 0; ind < defLocations.length; ind += 1) {
return fs.readFileAsync(filename); try {
}) text = await fs.readFileAsync(defLocations[ind]);
.catch(function () { filename = defLocations[ind];
filename = '/etc/goldilocks/goldilocks.yml'; break;
return fs.readFileAsync(filename); } catch (err) {
}) if (err.code !== 'ENOENT') {
.catch(function () { throw err;
filename = path.resolve(cwd, 'goldilocks.yml'); }
return ''; }
}) }
;
if (!filename) {
filename = defLocations[0];
text = '';
}
} }
return prom.then(function (text) { try {
try { JSON.parse(text);
JSON.parse(text); return { name: filename, type: 'json' };
return { name: filename, type: 'json' }; } catch (err) {}
} catch (err) {}
try { try {
require('js-yaml').safeLoad(text); require('js-yaml').safeLoad(text);
return { name: filename, type: 'yaml' }; return { name: filename, type: 'yaml' };
} catch (err) {} } catch (err) {}
throw new Error('Could not load "' + filename + '" as JSON nor YAML'); throw new Error('Could not load "' + filename + '" as JSON nor YAML');
});
} }
function createConfigStorage(args) { async function createConfigStorage(args) {
return checkConfigLocation(args.cwd, args.config) var result = await checkConfigLocation(args.cwd, args.config);
.then(function (result) { console.log('config file', result.name, 'is of type', result.type);
console.log('config file', result.name, 'is of type', result.type); configStorage = await createStorage(result.name, result.type);
configStorage = createStorage(result.name, result.type); return configStorage.read();
return configStorage.read();
})
;
} }
var tcpProm; var tcpProm;