diff --git a/index.js b/index.js index acec6ab..75c949e 100644 --- a/index.js +++ b/index.js @@ -156,14 +156,14 @@ switch(params._[0]) { const inputParameters = { asnList: (params.a) ? params.a.toString().split(",") : null, outputFile: params.o, - exclude: (params.e || "").split(","), + exclude: (params.e) ? params.e.toString().split(",") : null, excludeDelegated: params.i || false, prefixes, monitoredASes, httpProxy: params.x || null, debug, historical, - group: params.g, + group: params.g || null, append: !!params.A, logger: null, getCurrentPrefixesList: () => { diff --git a/src/connectors/connectorRIS.js b/src/connectors/connectorRIS.js index 8ff8b74..5694b30 100644 --- a/src/connectors/connectorRIS.js +++ b/src/connectors/connectorRIS.js @@ -257,7 +257,6 @@ export default class ConnectorRIS extends Connector { }; _onInputChange = (input) => { - this.subscribed = {}; this.connect() .then(() => this.subscribe(input)) .then(() => { diff --git a/src/generatePrefixesList.js b/src/generatePrefixesList.js index 09152b5..8b3c347 100644 --- a/src/generatePrefixesList.js +++ b/src/generatePrefixesList.js @@ -25,6 +25,7 @@ module.exports = function generatePrefixes(inputParameters) { enriched } = inputParameters; + exclude = exclude || []; logger = logger || console.log; const generateList = {}; @@ -194,7 +195,6 @@ module.exports = function generatePrefixes(inputParameters) { return latest.getTime() + (3600 * 24 * 1000) > new Date().getTime(); } }) - } return []; }) @@ -216,8 +216,6 @@ module.exports = function generatePrefixes(inputParameters) { }; const validatePrefix = (asn, prefix) => { - - return rpki .validate(prefix, asn, false) .then(isValid => { @@ -345,6 +343,16 @@ module.exports = function generatePrefixes(inputParameters) { }) .then(list => { logger("Done!"); + const options = { + asnList, + exclude, + excludeDelegated, + prefixes, + monitoredASes, + historical, + group + }; + list.options = Object.assign({}, list.options, { generate: options }); return list; }) .catch((e) => { diff --git a/src/inputs/input.js b/src/inputs/input.js index 356fa9d..34dd65b 100644 --- a/src/inputs/input.js +++ b/src/inputs/input.js @@ -225,13 +225,7 @@ export default class Input { } }; - if (this.config.generatePrefixListEveryDays >= 1 && this.storage) { - return this.storage - .set(this.prefixListStorageKey, inputParameters) - .then(() => generatePrefixes(inputParameters)); - } else { - return generatePrefixes(inputParameters); - } + return generatePrefixes(inputParameters); }); } else { @@ -255,63 +249,58 @@ export default class Input { this.setReGeneratePrefixList(); - this.storage - .get(this.prefixListStorageKey) - .then(inputParameters => { + return this.retrieve() + .then(oldPrefixList => { + const inputParameters = oldPrefixList.options.generate; - if (inputParameters && Object.keys(inputParameters).length > 0) { - inputParameters.logger = (message) => { - this.logger.log({ - level: 'info', - message - }); - }; - - return this.retrieve() - .then(oldPrefixList => { - return generatePrefixes(inputParameters) - .then(newPrefixList => { - - const newPrefixes = []; - const uniquePrefixes = [...new Set(Object.keys(oldPrefixList).concat(Object.keys(newPrefixList)))]; - const asns = [...new Set(Object - .values(oldPrefixList) - .map(i => i.asn) - .concat(Object.keys((oldPrefixList.options || {}).monitorASns || {})))]; - - for (let prefix of uniquePrefixes) { - const oldPrefix = oldPrefixList[prefix]; - const newPrefix = newPrefixList[prefix]; - - // The prefix didn't exist - if (newPrefix && !oldPrefix) { - // The prefix is not RPKI valid - if (!newPrefix.valid) { - // The prefix is not announced by a monitored ASn - if (!newPrefix.asn.some(p => asns.includes(p))) { - newPrefixes.push(prefix); - delete newPrefixList[prefix]; - } - } - } - - } - - if (newPrefixes.length) { - this.logger.log({ - level: 'info', - message: `The rules about ${newPrefixes.join(", ")} cannot be automatically added to the prefix list since their origin cannot be validated. They are not RPKI valid and they are not announced by a monitored AS. Add the prefixes manually if you want to start monitoring them.` - }); - } - - return newPrefixList; - }); - }); - - - } else { + if (!inputParameters) { throw new Error("The prefix list cannot be refreshed because it was not generated automatically or the cache has been deleted."); } + + inputParameters.logger = (message) => { + this.logger.log({ + level: 'info', + message + }); + }; + + return generatePrefixes(inputParameters) + .then(newPrefixList => { + + const newPrefixes = []; + const uniquePrefixes = [...new Set(Object.keys(oldPrefixList).concat(Object.keys(newPrefixList)))]; + const asns = [...new Set(Object + .values(oldPrefixList) + .map(i => i.asn) + .concat(Object.keys((oldPrefixList.options || {}).monitorASns || {})))]; + + for (let prefix of uniquePrefixes) { + const oldPrefix = oldPrefixList[prefix]; + const newPrefix = newPrefixList[prefix]; + + // The prefix didn't exist + if (newPrefix && !oldPrefix) { + // The prefix is not RPKI valid + if (!newPrefix.valid) { + // The prefix is not announced by a monitored ASn + if (!newPrefix.asn.some(p => asns.includes(p))) { + newPrefixes.push(prefix); + delete newPrefixList[prefix]; + } + } + } + + } + + if (newPrefixes.length) { + this.logger.log({ + level: 'info', + message: `The rules about ${newPrefixes.join(", ")} cannot be automatically added to the prefix list since their origin cannot be validated. They are not RPKI valid and they are not announced by a monitored AS. Add the prefixes manually if you want to start monitoring them.` + }); + } + + return newPrefixList; + }); }) .then(this.save) .then(() => { @@ -329,7 +318,7 @@ export default class Input { }; setReGeneratePrefixList = () => { - if (this.config.generatePrefixListEveryDays >= 1 && this.storage) { + if (this.config.generatePrefixListEveryDays >= 1) { const refreshTimer = Math.ceil(this.config.generatePrefixListEveryDays) * 24 * 3600 * 1000; if (this.regeneratePrefixListTimer) { diff --git a/src/inputs/inputYml.js b/src/inputs/inputYml.js index d315d30..f13f75b 100644 --- a/src/inputs/inputYml.js +++ b/src/inputs/inputYml.js @@ -46,6 +46,8 @@ export default class InputYml extends Input { if (!this.config.monitoredPrefixesFiles || this.config.monitoredPrefixesFiles.length === 0) { throw new Error("The monitoredPrefixesFiles key is missing in the config file"); } + + this.watcherSet = false; }; loadPrefixes = () => { @@ -59,21 +61,24 @@ export default class InputYml extends Input { }; _watchPrefixFile = (file) => { - fs.watchFile(file, () => { - this.prefixes = []; - this.asns = []; - this._loadPrefixes() - .then(() => { - return this._change(); - }) - .catch(error => { - this.logger.log({ - level: 'error', - message: error + if (!this.watcherSet) { + this.watcherSet = true; + fs.watchFile(file, () => { + this.prefixes = []; + this.asns = []; + this._loadPrefixes() + .then(() => { + return this._change(); + }) + .catch(error => { + this.logger.log({ + level: 'error', + message: error + }); + process.exit(); }); - process.exit(); - }); - }); + }); + } }; _loadPrefixes = () => @@ -101,20 +106,24 @@ export default class InputYml extends Input { } if (this.validate(monitoredPrefixesFile)) { + if (monitoredPrefixesFile.options) { - if (monitoredPrefixesFile.options && monitoredPrefixesFile.options.monitorASns) { - this.asns = Object - .keys(monitoredPrefixesFile.options.monitorASns) - .map(asn => { - if (uniqueAsns[asn]) { - throw new Error("Duplicate entry for monitored AS " + asn); - } - uniqueAsns[asn] = true; - return Object.assign({ - asn: new AS(asn), - group: 'default' - }, monitoredPrefixesFile.options.monitorASns[asn]); - }); + this.options = monitoredPrefixesFile.options; + + if (monitoredPrefixesFile.options.monitorASns) { + this.asns = Object + .keys(monitoredPrefixesFile.options.monitorASns) + .map(asn => { + if (uniqueAsns[asn]) { + throw new Error("Duplicate entry for monitored AS " + asn); + } + uniqueAsns[asn] = true; + return Object.assign({ + asn: new AS(asn), + group: 'default' + }, monitoredPrefixesFile.options.monitorASns[asn]); + }); + } } const monitoredPrefixes = Object @@ -292,19 +301,16 @@ export default class InputYml extends Input { if (rule.includeMonitors.length) prefixes[prefix].includeMonitors = rule.includeMonitors; } - const options = { - options: { - monitorASns: { - } - } - }; + const monitorASns = {}; for (let asnRule of this.asns) { - options.options.monitorASns[asnRule.asn.getValue()] = { + monitorASns[asnRule.asn.getValue()] = { group: asnRule.group }; } - resolve({ ...prefixes, ...options }); + const options = Object.assign({}, this.options, { monitorASns }); + + resolve(JSON.parse(JSON.stringify({ ...prefixes, options }))); }); } \ No newline at end of file