From 427c17333b86046f10609bf661143682bc4a0dab Mon Sep 17 00:00:00 2001 From: Massimo Candela Date: Mon, 14 Sep 2020 18:30:14 +0200 Subject: [PATCH] introduced multiple path matches #317 --- src/inputs/inputYml.js | 26 ++-- src/monitors/monitorPath.js | 87 +++++++------- tests/.cache_clone/status-path-matching.json | 2 +- tests/2_alerting.js | 120 +++++++++++-------- tests/prefixes.test.yml | 9 +- 5 files changed, 137 insertions(+), 107 deletions(-) diff --git a/src/inputs/inputYml.js b/src/inputs/inputYml.js index f13f75b..2afaeb3 100644 --- a/src/inputs/inputYml.js +++ b/src/inputs/inputYml.js @@ -229,18 +229,22 @@ export default class InputYml extends Input { } if (item.path) { - if (!item.path.matchDescription){ - return "No matchDescription set"; - } - this._validateRegex(item.path.match); - this._validateRegex(item.path.notMatch); - if (item.path.maxLength && !(typeof(item.path.maxLength) == "number" && item.path.maxLength > 1)) { - return "Not valid maxLength"; - } + ((item.path.length) ? item.path : [item.path]) + .map(rule => { + if (!rule.matchDescription){ + return "No matchDescription set"; + } + this._validateRegex(rule.match); + this._validateRegex(rule.notMatch); + if (rule.maxLength && !(typeof(rule.maxLength) == "number" && rule.maxLength > 1)) { + return "Not valid maxLength"; + } + + if (rule.minLength && !(typeof(rule.minLength) == "number" && rule.minLength > 1)) { + return "Not valid minLength"; + } + }) - if (item.path.minLength && !(typeof(item.path.minLength) == "number" && item.path.minLength > 1)) { - return "Not valid minLength"; - } } return null; diff --git a/src/monitors/monitorPath.js b/src/monitors/monitorPath.js index 04ed1ff..1e7b054 100644 --- a/src/monitors/monitorPath.js +++ b/src/monitors/monitorPath.js @@ -54,12 +54,56 @@ export default class MonitorPath extends Monitor { if (peers >= this.thresholdMinPeers) { const lengthViolation = (alerts.some(i => i.extra.lengthViolation)) ? "(including length violation) " : ""; - return `Matched ${alerts[0].matchedRule.path.matchDescription} on prefix ${alerts[0].matchedMessage.prefix} ${lengthViolation}${alerts.length} times`; + return `Matched ${alerts[0].extra.matchDescription} on prefix ${alerts[0].matchedMessage.prefix} ${lengthViolation}${alerts.length} times`; } return false; }; + pathRuleCheck = (pathRule, index, message, matchedRule) => { + const messagePrefix = message.prefix; + const pathString = message.path.getValues().join(","); + + let expMatch = true; + let expNotMatch = true; + let correctLength = true; + + if (pathRule.match) { + expMatch = (new RegExp(pathRule.match)).test(pathString); + if (!expMatch) { + return; + } + } + + if (pathRule.notMatch){ + expNotMatch = !(new RegExp(pathRule.notMatch)).test(pathString); + if (!expNotMatch) { + return; + } + } + + if (pathRule.maxLength && message.path.getValues().length > pathRule.maxLength) { + correctLength = false; + } + + if (pathRule.minLength && message.path.getValues().length < pathRule.minLength) { + correctLength = false; + } + + if (expMatch && expNotMatch && + ((!pathRule.maxLength && !pathRule.maxLength) || !correctLength)) { + + this.publishAlert(`${messagePrefix}-${index}`, + matchedRule.prefix, + matchedRule, + message, + { + lengthViolation: !correctLength, + matchDescription: pathRule.matchDescription + }); + } + }; + monitor = (message) => new Promise((resolve, reject) => { @@ -67,47 +111,10 @@ export default class MonitorPath extends Monitor { const matchedRule = this.getMoreSpecificMatch(messagePrefix, false); if (matchedRule && !matchedRule.ignore && matchedRule.path) { - const pathString = message.path.getValues().join(","); + const pathRules = (matchedRule.path.length) ? matchedRule.path : [ matchedRule.path ]; - let expMatch = true; - let expNotMatch = true; - let correctLength = true; + pathRules.map((pathRule, position) => this.pathRuleCheck(pathRule, position, message, matchedRule)); - if (matchedRule.path.match) { - expMatch = (new RegExp(matchedRule.path.match)).test(pathString); - if (!expMatch) { - resolve(true); - return; - } - } - - if (matchedRule.path.notMatch){ - expNotMatch = !(new RegExp(matchedRule.path.notMatch)).test(pathString); - if (!expNotMatch) { - resolve(true); - return; - } - } - - if (matchedRule.path.maxLength && message.path.getValues().length > matchedRule.path.maxLength) { - correctLength = false; - } - - if (matchedRule.path.minLength && message.path.getValues().length < matchedRule.path.minLength) { - correctLength = false; - } - - if (expMatch && expNotMatch && - ((!matchedRule.path.maxLength && !matchedRule.path.maxLength) || !correctLength)) { - - this.publishAlert(messagePrefix, - matchedRule.prefix, - matchedRule, - message, - { - lengthViolation: !correctLength - }); - } } resolve(true); diff --git a/tests/.cache_clone/status-path-matching.json b/tests/.cache_clone/status-path-matching.json index b28a578..5044b43 100644 --- a/tests/.cache_clone/status-path-matching.json +++ b/tests/.cache_clone/status-path-matching.json @@ -1 +1 @@ -{"date":1593370452107,"value":{"alerts":{},"sent":{"98.5.4.3/22":1593370447102,"99.5.4.3/22":1593370447103},"truncated":{},"fadeOff":{}}} \ No newline at end of file +{"date":1593370452107,"value":{"alerts":{},"sent":{"98.5.4.3/22-1":1593370447102,"99.5.4.3/22-0":1593370447103},"truncated":{},"fadeOff":{}}} \ No newline at end of file diff --git a/tests/2_alerting.js b/tests/2_alerting.js index e2d59a0..396fb00 100644 --- a/tests/2_alerting.js +++ b/tests/2_alerting.js @@ -378,71 +378,87 @@ describe("Alerting", function () { pubSub.publish("test-type", "path"); const expectedData = { - "98.5.4.3/22": { - id: '98.5.4.3/22', + "98.5.4.3/22-1": { + id: '98.5.4.3/22-1', origin: 'path-matching', affected: "98.5.4.3/22", - message: 'Matched test description on prefix 98.5.4.3/22 (including length violation) 1 times', - data: [ - { - extra: { - lengthViolation: true - }, - matchedRule: { - prefix: '98.5.4.3/22', - group: 'default', - description: 'path matching test regex and maxLength', - asn: [2914], - ignoreMorespecifics: false, - ignore: false, - path: { - match: ".*2914$", - matchDescription: "test description", - maxLength: 3, + message: 'Matched test description2 on prefix 98.5.4.3/22 (including length violation) 1 times', + "data": + [ + { + + "affected":"98.5.4.3/22", + "matchedRule":{ + "prefix":"98.5.4.3/22", + "group":"default", + "ignore":false, + "excludeMonitors":[], + "includeMonitors":[], + "description":"path matching test regex and maxLength", + "asn":[2914], + "ignoreMorespecifics":false, + "path":[ + { + "match":".*2915$", + "maxLength":4, + "matchDescription":"test description1" + },{ + "match":".*2914$", + "maxLength":3, + "matchDescription":"test description2" + } + ] + },"matchedMessage":{ + "type":"announcement", + "prefix":"98.5.4.3/22", + "peer":"124.0.0.3", + "path":[1,2,3,4321,5060,2914], + "originAS":[2914], + "nextHop":"124.0.0.3", + "aggregator":null}, + "extra":{ + "lengthViolation":true, + "matchDescription":"test description2" } - }, - matchedMessage: { - type: 'announcement', - prefix: '98.5.4.3/22', - peer: '124.0.0.3', - path: [1, 2, 3, 4321, 5060, 2914], - originAS: [2914], - nextHop: '124.0.0.3' } - } - ] + ] }, - "99.5.4.3/22": { - id: '99.5.4.3/22', + "99.5.4.3/22-0": { + id: '99.5.4.3/22-0', origin: 'path-matching', affected: "99.5.4.3/22", message: 'Matched test description on prefix 99.5.4.3/22 1 times', data: [ { - extra: { - lengthViolation: false - }, - matchedRule: { - prefix: '99.5.4.3/22', - group: 'default', - description: 'path matching test regex and minLength', - asn: [2914], - ignoreMorespecifics: false, - ignore: false, - path: { - match: ".*2914$", - matchDescription: "test description", - minLength: 2, + "affected":"99.5.4.3/22", + "matchedRule": { + "prefix":"99.5.4.3/22", + "group":"default", + "ignore":false, + "excludeMonitors":[], + "includeMonitors":[], + "description":"path matching test regex and minLength", + "asn":[2914], + "ignoreMorespecifics":false, + "path":{ + "match":".*2914$", + "minLength":2, + "matchDescription":"test description" } }, - matchedMessage: { - type: 'announcement', - prefix: '99.5.4.3/22', - peer: '124.0.0.3', - path: [1, 2, 3, 4321, 5060, 2914], - originAS: [2914], - nextHop: '124.0.0.3' + "matchedMessage":{ + "type":"announcement", + "prefix":"99.5.4.3/22", + "peer":"124.0.0.3", + "path":[1,2,3,4321,5060,2914], + "originAS":[2914], + "nextHop":"124.0.0.3", + "aggregator":null + }, + "extra":{ + "lengthViolation":false, + "matchDescription":"test description" } } ] diff --git a/tests/prefixes.test.yml b/tests/prefixes.test.yml index fedf18c..c1d4734 100644 --- a/tests/prefixes.test.yml +++ b/tests/prefixes.test.yml @@ -70,9 +70,12 @@ ignoreMorespecifics: false ignore: false path: - match: ".*2914$" - maxLength: 3 - matchDescription: test description + - match: ".*2915$" + maxLength: 4 + matchDescription: test description1 + - match: ".*2914$" + maxLength: 3 + matchDescription: test description2 99.5.4.3/22: description: path matching test regex and minLength