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,51 +127,54 @@ 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);
} catch (err) {
if (err.code !== 'ENOENT') { if (err.code !== 'ENOENT') {
return PromiseA.reject(err); throw err;
} }
if (path.extname(filename) === '.json') { if (path.extname(filename) === '.json') {
return '{}'; return { name: filename, type: 'json' };
}
return '';
})
;
} else { } else {
prom = PromiseA.reject('blah') return { name: filename, type: 'yaml' };
.catch(function () { }
filename = path.resolve(cwd, 'goldilocks.yml'); }
return fs.readFileAsync(filename); } else {
}) // Note that `path.resolve` can handle both relative and absolute paths.
.catch(function () { var defLocations = [
filename = path.resolve(cwd, 'goldilocks.json'); 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, 'etc/goldilocks/goldilocks.yml'); , path.resolve(cwd, 'goldilocks.yml')
return fs.readFileAsync(filename); ];
})
.catch(function () { var ind;
filename = '/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 = path.resolve(cwd, 'goldilocks.yml'); break;
return ''; } catch (err) {
}) if (err.code !== 'ENOENT') {
; throw err;
}
}
}
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' };
@ -132,16 +186,12 @@ function checkConfigLocation(cwd, configFile) {
} 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 = createStorage(result.name, result.type); configStorage = await createStorage(result.name, result.type);
return configStorage.read(); return configStorage.read();
})
;
} }
var tcpProm; var tcpProm;