1
0
mirror of https://github.com/nttgin/BGPalerter.git synced 2024-05-19 06:50:08 +00:00

introduced software updates checks (#17)

* check for update feature + converting to standard npm versioning
This commit is contained in:
Massimo Candela
2019-09-19 22:36:12 +02:00
committed by GitHub
parent 8566253c79
commit 1feef2a4bc
18 changed files with 214 additions and 37 deletions

View File

@@ -89,3 +89,5 @@ logging:
zippedArchive: true
maxSize: 20m
maxFiles: 14d
checkForUpdatesAtBoot: true

View File

@@ -34,6 +34,7 @@
export default class Connector {
constructor(name, params, env){
this.version = env.version;
this.config = env.config;
this.logger = env.logger;
this.pubSub = env.pubSub;

View File

@@ -87,7 +87,6 @@ export default class ConnectorRIS extends Connector{
};
_subscribeToAll = (input) => {
console.log("Subscribing to everything");
this.ws.send(JSON.stringify({
type: "ris_subscribe",
data: this.params.subscription
@@ -99,8 +98,8 @@ export default class ConnectorRIS extends Connector{
const monitoredPrefixes = input.getMonitoredLessSpecifics().map(item => item.prefix);
const params = JSON.parse(JSON.stringify(this.params.subscription));
for (let prefix of monitoredPrefixes){
console.log("Monitoring", prefix);
params.prefix = prefix;
console.log("Subscribing to:", prefix);
this.ws.send(JSON.stringify({
type: "ris_subscribe",
data: params

View File

@@ -0,0 +1,83 @@
/*
* BSD 3-Clause License
*
* Copyright (c) 2019, NTT Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import Connector from "./connector";
import axios from "axios";
export default class ConnectorSwUpdates extends Connector{
constructor(name, params, env) {
super(name, params, env);
this.timer = null;
}
connect = () =>
new Promise((resolve, reject) => {
resolve(true);
});
_checkForUpdates = () => {
return axios({
responseType: "json",
url: "https://raw.githubusercontent.com/nttgin/BGPalerter/master/package.json"
})
.then(data => {
if (data && data.data && data.data.version && data.data.version !== this.version){
this._message(JSON.stringify({
type: "software-update",
currentVersion: this.version,
newVersion: data.data.version,
repo: "https://github.com/nttgin/BGPalerter"
}));
}
})
.catch(() => {
this.logger.log({
level: 'error',
message: "It was not possible to check for software updates"
});
});
};
subscribe = (input) =>
new Promise((resolve, reject) => {
if (this.config.checkForUpdatesAtBoot){
this._checkForUpdates();
}
this.timer = setInterval(this._checkForUpdates, 1000 * 3600 * 24 * 5); // Check every 5 days
resolve(true);
});
static transform = (message) => {
return [ message ];
}
};

View File

@@ -39,11 +39,9 @@ export default class ConnectorTest extends Connector{
constructor(name, params, env) {
super(name, params, env);
console.log("Test connector running");
this.pubSub.subscribe("test-type", (type, message) => {
clearInterval(this.timer);
this.subscribe({type: message});
console.log("switching to", message);
});
}

View File

@@ -78,7 +78,7 @@ export default class Consumer {
} catch (error) {
env.logger.log({
level: 'error',
message: error
message: "Error in parsing data, dispatch method of consumer.js: " + error
});
}
};

47
env.js
View File

@@ -100,8 +100,8 @@ let config = {
zippedArchive: true,
maxSize: "20m",
maxFiles: "14d",
}
},
checkForUpdatesAtBoot: true
};
try {
@@ -120,7 +120,7 @@ const transportError = new (winston.transports.DailyRotateFile)({
zippedArchive: config.logging.zippedArchive,
maxSize: config.logging.maxSize,
maxFiles: config.logging.maxFiles,
level: 'error',
level: 'info',
timestamp: true,
eol: '\n',
json: false,
@@ -130,6 +130,7 @@ const transportError = new (winston.transports.DailyRotateFile)({
formatLine
)
});
const transportReports = new (winston.transports.DailyRotateFile)({
filename: config.logging.directory + '/reports-%DATE%.log',
datePattern: config.logging.logRotatePattern,
@@ -148,22 +149,29 @@ const transportReports = new (winston.transports.DailyRotateFile)({
)
});
const wlogger = winston.createLogger({
level: 'info',
transports: [
transportError,
transportReports,
new winston.transports.Console({
format: winston.format.simple()
})
]
});
const winstonTransports = [
transportError,
transportReports
];
if (config.environment === 'production') {
wlogger.remove(wlogger.transports.Console);
if (config.environment !== 'production') {
const consoleTransport = new winston.transports.Console({
format: winston.format.simple()
});
winstonTransports.push(consoleTransport);
}
config.monitors = (config.monitors || [])
const wlogger = winston.createLogger({ transports: winstonTransports });
config.monitors = (config.monitors || []);
config.monitors.push({
file: "monitorSwUpdates",
channel: "software-update",
name: "software-update",
});
config.monitors = config.monitors
.map(item => {
return {
class: require("./monitors/" + item.file).default,
@@ -178,13 +186,18 @@ config.reports = (config.reports || [])
return {
class: require("./reports/" + item.file).default,
channels: item.channels,
channels: [...item.channels, "software-update"],
params: item.params
};
});
config.connectors = config.connectors || [];
config.connectors.push( {
file: "connectorSwUpdates",
name: "upd"
});
if ([...new Set(config.connectors)].length !== config.connectors.length) {
throw new Error('Connectors names MUST be unique');
}

View File

@@ -79,6 +79,6 @@ switch(params._[0]) {
break;
default: // Run monitor
const Monitor = require("./monitor").default;
module.exports = new Monitor(params.c).pubSub;
const Worker = require("./worker").default;
module.exports = new Worker(params.c).pubSub;
}

View File

@@ -31,7 +31,6 @@
*/
import Monitor from "./monitor";
import ipUtils from "../ipUtils";
export default class MonitorHijack extends Monitor {

View File

@@ -31,7 +31,6 @@
*/
import Monitor from "./monitor";
import ipUtils from "../ipUtils";
export default class MonitorNewPrefix extends Monitor {

View File

@@ -0,0 +1,62 @@
/*
* BSD 3-Clause License
*
* Copyright (c) 2019, NTT Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import Monitor from "./monitor";
export default class MonitorSwUpdates extends Monitor {
constructor(name, channel, params, env){
super(name, channel, params, env);
};
filter = (message) => {
return message.type === 'software-update';
};
squashAlerts = (alerts) => {
return alerts[0].message;
};
monitor = (message) =>
new Promise((resolve, reject) => {
this.publishAlert("software-update",
`A new version of BGPalerter is available. Current version: ${message.currentVersion} new version: ${message.newVersion}. Please, go to: ${message.repo}`,
"bgpalerter",
{},
message,
{});
resolve(true);
});
}

View File

@@ -31,7 +31,6 @@
*/
import Monitor from "./monitor";
import ipUtils from "../ipUtils";
export default class MonitorVisibility extends Monitor {

View File

@@ -1,6 +1,6 @@
{
"name": "bgpalerter",
"version": "19.9.19.2",
"version": "1.19.1",
"description": "",
"main": "index.js",
"bin": "index.js",

View File

@@ -39,7 +39,6 @@ export default class ReportFile extends Report {
}
report = (message, content) => {
this.logger.log({
level: 'verbose',
message: content.message

View File

@@ -51,6 +51,11 @@ export default class ReportSlack extends Report {
}
_sendSlackMessage = (url, message, content) => {
const color = (this.params && this.params.colors && this.params.colors[message])
? this.params.colors[message]
: '#4287f5';
axios({
url: url,
method: "POST",
@@ -58,7 +63,7 @@ export default class ReportSlack extends Report {
data: {
attachments: [
{
color: this.params.colors[message],
color: color,
title: message,
text: content.message
}
@@ -75,7 +80,8 @@ export default class ReportSlack extends Report {
report = (message, content) => {
if (this.enabled){
const groups = [...new Set(content.data.map(i => i.matchedRule.group))];
let groups = content.data.map(i => i.matchedRule.group).filter(i => i != null);
groups = (groups.length) ? [...new Set(groups)] : Object.keys(this.params.hooks); // If there are no groups defined, send to all of them
for (let group of groups) {
if (this.params.hooks[group]) {

View File

@@ -43,3 +43,5 @@ logging:
zippedArchive: true
maxSize: 20m
maxFiles: 14d
checkForUpdatesAtBoot: true

View File

@@ -40,11 +40,13 @@ chai.use(chaiSubset);
var expect = chai.expect;
var AS = model.AS;
process.env.npm_package_version = "0.0.1";
global.EXTERNAL_CONFIG_FILE = "tests/config.test.yml";
describe("Tests", function() {
beforeEach(resetCache);
describe("Configuration loader", function () {
global.EXTERNAL_CONFIG_FILE = "tests/config.test.yml";
var env = require("../env");
it("config structure", function () {
@@ -58,7 +60,8 @@ describe("Tests", function() {
"notificationIntervalSeconds",
"clearNotificationQueueAfterSeconds",
"monitoredPrefixesFiles",
"logging"
"logging",
"checkForUpdatesAtBoot"
]);
expect(env.config.connectors[0]).to.have
.property('class')
@@ -122,7 +125,6 @@ describe("Tests", function() {
describe("Input loader", function () {
process.argv[2] = "tests/config.test.yml";
var env = require("../env");
@@ -197,7 +199,6 @@ describe("Tests", function() {
describe("Logging", function () {
process.argv[2] = "tests/config.test.yml";
var env = require("../env");
it("errors logging on the right file", function (done) {
@@ -243,8 +244,22 @@ describe("Tests", function() {
});
describe("Software updates check", function () {
var pubSub = require("../index");
it("new version detected", function (done) {
pubSub.subscribe("software-update", function (type, message) {
expect(type).to.equal("software-update");
done();
});
});
});
describe("Alerting", function () {
process.argv[2] = "tests/config.test.yml";
var pubSub = require("../index");
var env = require("../env");

View File

@@ -34,7 +34,7 @@ import Consumer from "./consumer";
import ConnectorFactory from "./connectorFactory";
import cluster from "cluster";
export default class Monitor {
export default class Worker {
constructor(configFile) {
global.EXTERNAL_CONFIG_FILE = configFile;