diff --git a/docs/prefixes.md b/docs/prefixes.md index 8ec8a48..18e9417 100644 --- a/docs/prefixes.md +++ b/docs/prefixes.md @@ -23,6 +23,7 @@ Below the list of possible parameters. **Remember to prepend them with a `--` in | -s | A list of ASns to be monitored. See [monitorASns](#monitorASns) for more information | A comma separated list of integer | 2914,3333 | No | | -m | Monitor all ASns which are origin of at least one of the monitored prefixes. This option is the same of `-s` except that the list of ASns is automatically generated by detecting the origin AS of all the monitored prefixes. See [monitorASns](#monitorASns) for more information | Nothing | | No | | -x | HTTP/HTTPS proxy server to use | A string | http://username:password@proxy.example.org:8080 | No | +| -A | Append the new configuration to the old one. E.g. you can use this option to add another AS. | Nothing | | No | | -D | Enable debug mode. All queries executed in background will be shown. | Nothing | | No | | -H | Use historical visibility data for generating prefix list (prefixes visible in the last week). Useful in case the prefix generation process returns an empty dataset. | Nothing | | No | diff --git a/index.js b/index.js index 591212c..9387b3f 100644 --- a/index.js +++ b/index.js @@ -100,6 +100,10 @@ const params = yargs .nargs('g', 1) .describe('x', 'Define a user group for all the generated rules.') + .alias('A', 'append') + .nargs('A', 0) + .describe('A', 'Append the new configuration to the previous one.') + .alias('D', 'debug') .nargs('D', 0) .describe('D', 'Provide verbose output for debugging') @@ -157,7 +161,8 @@ switch(params._[0]) { httpProxy: params.x || null, debug, historical, - group: params.g + group: params.g, + append: !!params.A }; generatePrefixes(inputParameters); diff --git a/src/generatePrefixesList.js b/src/generatePrefixesList.js index b827b0b..57ccf78 100644 --- a/src/generatePrefixesList.js +++ b/src/generatePrefixesList.js @@ -16,7 +16,8 @@ module.exports = function generatePrefixes(inputParameters) { httpProxy, debug, historical, - group + group, + append } = inputParameters; const generateList = {}; @@ -31,7 +32,7 @@ module.exports = function generatePrefixes(inputParameters) { if (historical) { console.log("WARNING: you are using historical visibility data for generating the prefix list."); } - + if (!asnList && !prefixes) { throw new Error("You need to specify at least an AS number or a list of prefixes."); } @@ -218,7 +219,7 @@ module.exports = function generatePrefixes(inputParameters) { } }) .catch(() => { - console.log("RIPEstat rpki-validation query failed: cannot retrieve information for " + prefix); + console.log("RPKI validation query failed: cannot retrieve information for " + prefix); }); }; @@ -232,6 +233,34 @@ module.exports = function generatePrefixes(inputParameters) { } }; + const getCurrentPrefixes = (outputFile, yamlContent) => { + const content = fs.readFileSync(outputFile, 'utf8'); + const current = yaml.safeLoad(content) || {}; + + function isObject (item) { + return (item && typeof item === 'object' && !Array.isArray(item)); + } + function mergeDeep(target, ...sources) { + if (!sources.length) return target; + const source = sources.shift(); + + if (isObject(target) && isObject(source)) { + for (const key in source) { + if (isObject(source[key])) { + if (!target[key]) Object.assign(target, { [key]: {} }); + mergeDeep(target[key], source[key]); + } else { + Object.assign(target, { [key]: source[key] }); + } + } + } + + return mergeDeep(target, ...sources); + }; + + return mergeDeep(current, yamlContent); + }; + return getBaseRules() .then(items => [].concat.apply([], items)) .then(prefixes => { @@ -273,8 +302,13 @@ module.exports = function generatePrefixes(inputParameters) { // Otherwise nothing }) .then(() => { // write everything into the file - const yamlContent = yaml.dump(generateList); - fs.writeFileSync(outputFile, yamlContent); + + if (append) { + const finalList = getCurrentPrefixes(outputFile, generateList); + fs.writeFileSync(outputFile, yaml.dump(finalList)); + } else { + fs.writeFileSync(outputFile, yaml.dump(generateList)); + } if (someNotValidatedPrefixes) { console.log("WARNING: the generated configuration is a snapshot of what is currently announced. Some of the prefixes don't have ROA objects associated or are RPKI invalid. Please, verify the config file by hand!"); diff --git a/src/inputs/input.js b/src/inputs/input.js index 7bac3df..1edc3ea 100644 --- a/src/inputs/input.js +++ b/src/inputs/input.js @@ -206,7 +206,8 @@ export default class Input { httpProxy: null, debug: false, historical: false, - group: null + group: null, + append: false } return generatePrefixes(inputParameters);