From 0380a8087feb932fcc2480463ddd35205038b294 Mon Sep 17 00:00:00 2001 From: tigerbot Date: Wed, 4 Oct 2017 18:27:29 -0600 Subject: [PATCH] automatically add `id` to modules and domains --- bin/goldilocks.js | 172 ++++++++++++++++++++++++++++++---------------- 1 file changed, 111 insertions(+), 61 deletions(-) diff --git a/bin/goldilocks.js b/bin/goldilocks.js index 6b71c75..456e9a9 100755 --- a/bin/goldilocks.js +++ b/bin/goldilocks.js @@ -8,6 +8,7 @@ if (!cluster.isMaster) { return; } +var crypto = require('crypto'); var PromiseA = require('bluebird'); var fs = PromiseA.promisifyAll(require('fs')); 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 snakeCopy = recase.snakeCopy.bind(recase); var camelCopy = recase.camelCopy.bind(recase); @@ -40,13 +79,25 @@ function createStorage(filename, filetype) { dump = yaml.safeDump; } - function read() { - return fs.readFileAsync(filename).then(parse).catch(function (err) { + async function read() { + var text; + try { + text = await fs.readFileAsync(filename); + } catch (err) { 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 = { @@ -76,72 +127,71 @@ function createStorage(filename, filetype) { }; return result; } -function checkConfigLocation(cwd, configFile) { +async function checkConfigLocation(cwd, configFile) { cwd = cwd || process.cwd(); var path = require('path'); - var filename; + var filename, text; - var prom; if (configFile) { filename = path.resolve(cwd, configFile); - prom = fs.readFileAsync(filename) - .catch(function (err) { - if (err.code !== 'ENOENT') { - return PromiseA.reject(err); - } - if (path.extname(filename) === '.json') { - return '{}'; - } - return ''; - }) - ; + try { + text = await fs.readFileAsync(filename); + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; + } + if (path.extname(filename) === '.json') { + return { name: filename, type: 'json' }; + } else { + return { name: filename, type: 'yaml' }; + } + } } else { - prom = PromiseA.reject('blah') - .catch(function () { - filename = path.resolve(cwd, 'goldilocks.yml'); - return fs.readFileAsync(filename); - }) - .catch(function () { - filename = path.resolve(cwd, 'goldilocks.json'); - return fs.readFileAsync(filename); - }) - .catch(function () { - filename = path.resolve(cwd, 'etc/goldilocks/goldilocks.yml'); - return fs.readFileAsync(filename); - }) - .catch(function () { - filename = '/etc/goldilocks/goldilocks.yml'; - return fs.readFileAsync(filename); - }) - .catch(function () { - filename = path.resolve(cwd, 'goldilocks.yml'); - return ''; - }) - ; + // Note that `path.resolve` can handle both relative and absolute paths. + var defLocations = [ + path.resolve(cwd, 'goldilocks.yml') + , path.resolve(cwd, 'goldilocks.json') + , path.resolve(cwd, 'etc/goldilocks/goldilocks.yml') + , '/etc/goldilocks/goldilocks.yml' + , path.resolve(cwd, 'goldilocks.yml') + ]; + + var ind; + for (ind = 0; ind < defLocations.length; ind += 1) { + try { + text = await fs.readFileAsync(defLocations[ind]); + filename = defLocations[ind]; + break; + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; + } + } + } + + if (!filename) { + filename = defLocations[0]; + text = ''; + } } - return prom.then(function (text) { - try { - JSON.parse(text); - return { name: filename, type: 'json' }; - } catch (err) {} + try { + JSON.parse(text); + return { name: filename, type: 'json' }; + } catch (err) {} - try { - require('js-yaml').safeLoad(text); - return { name: filename, type: 'yaml' }; - } catch (err) {} + try { + require('js-yaml').safeLoad(text); + return { name: filename, type: 'yaml' }; + } 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) { - return checkConfigLocation(args.cwd, args.config) - .then(function (result) { - console.log('config file', result.name, 'is of type', result.type); - configStorage = createStorage(result.name, result.type); - return configStorage.read(); - }) - ; +async function createConfigStorage(args) { + var result = await checkConfigLocation(args.cwd, args.config); + console.log('config file', result.name, 'is of type', result.type); + configStorage = await createStorage(result.name, result.type); + return configStorage.read(); } var tcpProm;