init
commit
b1e0651885
|
|
@ -0,0 +1,130 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "derdackbhomwebhook",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "commonjs",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"build": "npx webpack --config webpack.config.js"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.23.7",
|
||||||
|
"@babel/preset-env": "^7.23.8",
|
||||||
|
"babel-loader": "^9.1.3",
|
||||||
|
"webpack": "^5.89.0",
|
||||||
|
"webpack-bundle-analyzer": "^4.10.1",
|
||||||
|
"webpack-cli": "^5.1.4",
|
||||||
|
"webpack-node-externals": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"deepmerge": "^4.3.1",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
|
"mustache": "^4.2.0",
|
||||||
|
"request": "^2.8.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
var mockPrefixEnabled = false;
|
||||||
|
|
||||||
|
|
||||||
|
function enableMockPrefix()
|
||||||
|
{
|
||||||
|
mockPrefixEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function writeLog(identifier, message)
|
||||||
|
{
|
||||||
|
if (!mockPrefixEnabled)
|
||||||
|
{
|
||||||
|
console.log(`${identifier} | ${message}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var date = `${new Date()} | `;
|
||||||
|
console.log(`${date}${identifier} | ${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
writeLog: writeLog,
|
||||||
|
enableMockPrefix: enableMockPrefix
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
const Script = require('./Main.js');
|
||||||
|
|
||||||
|
|
||||||
|
class Mock {
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
|
||||||
|
this.Logger = require('./Logger');
|
||||||
|
this.Logger.enableMockPrefix();
|
||||||
|
this.Express = null;
|
||||||
|
this.Webapp = null;
|
||||||
|
this.callbackOnSubscriptionEvent = null;
|
||||||
|
this.listenPort = 8080;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLogger()
|
||||||
|
{
|
||||||
|
return this.Logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getLogFnName(fnName)
|
||||||
|
{
|
||||||
|
return `Mock::${fnName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mockOnGetProcessId(pid)
|
||||||
|
{
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockOnGetProcessId.name), `*** Node script reported the following PID: ${pid} ***`);
|
||||||
|
}
|
||||||
|
|
||||||
|
mockCallbackSaveState(state)
|
||||||
|
{
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockCallbackSaveState.name), `*** State Saved ***`);
|
||||||
|
}
|
||||||
|
|
||||||
|
mockCallbackSetStatusError(message)
|
||||||
|
{
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockCallbackSetStatusError.name), `*** Script status changed to ERROR. User message: ${message} ***`);
|
||||||
|
}
|
||||||
|
|
||||||
|
mockCallbackSetStatusOK(message)
|
||||||
|
{
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockCallbackSetStatusOK.name), `*** Script status changed to OK. User message: ${message} ***`);
|
||||||
|
}
|
||||||
|
|
||||||
|
mockOnSubscriptionEvent(callbackOnSubscriptionEvent, scriptName)
|
||||||
|
{
|
||||||
|
this.Express = require('express');
|
||||||
|
this.Webapp = this.Express();
|
||||||
|
this.callbackOnSubscriptionEvent = callbackOnSubscriptionEvent;
|
||||||
|
|
||||||
|
this.Webapp.use(this.Express.json());
|
||||||
|
this.Webapp.post(`/eventFromS4-${scriptName}`, function (request, response) {
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.callbackOnSubscriptionEvent((object1, returnValue) => {}, request.body);
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockOnSubscriptionEvent.name), `Error on handling subscription event: ${error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.set('Content-Type', 'text/plain');
|
||||||
|
response.send('OK');
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
this.Webapp.listen(this.listenPort, function (error) {
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockOnSubscriptionEvent.name), `Error while trying to listen on port: ${this.listenPort}: ${error}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockOnSubscriptionEvent.name), `eventFromS4 endpoint is listening on port ${this.listenPort}..`);
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async mockCallbackRaiseEvent(event, targetURL)
|
||||||
|
{
|
||||||
|
var request = require('request');
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
url: targetURL,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(event, null, 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
request.post(options, function (error, response, body) {
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockCallbackRaiseEvent.name), `Error while sending event to S4: ${error.message}`);
|
||||||
|
return reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockCallbackRaiseEvent.name), `Event SENT to S4. Status code received: ${response.statusCode}`);
|
||||||
|
|
||||||
|
return resolve(true);
|
||||||
|
}.bind(this));
|
||||||
|
}).catch((error) => {
|
||||||
|
this.Logger.writeLog(this.getLogFnName(this.mockCallbackRaiseEvent.name), `Following error occurred while sending to S4: ${error}`);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function mockCallbackSetStatusError(message)
|
||||||
|
{
|
||||||
|
new Mock().mockCallbackSetStatusError(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mockCallbackSetStatusOK(message)
|
||||||
|
{
|
||||||
|
new Mock().mockCallbackSetStatusOK(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function mockCallbackRaiseEvent(event)
|
||||||
|
{
|
||||||
|
await new Mock().mockCallbackRaiseEvent(event, "https://connect.signl4.com/webhook/seo6p3wh");
|
||||||
|
}
|
||||||
|
|
||||||
|
function mockCallbackSaveState(state)
|
||||||
|
{
|
||||||
|
new Mock().mockCallbackSaveState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var appContext = {
|
||||||
|
config: {
|
||||||
|
serverURL: '',
|
||||||
|
username: '',
|
||||||
|
password: ''
|
||||||
|
},
|
||||||
|
runtimeInfo: {
|
||||||
|
subscriptionId: '',
|
||||||
|
scriptId: '413f5213-40ab-468a-b0f2-cd898f749cbb', // Choose what you want for dev from https://www.uuidgenerator.net/version4
|
||||||
|
scriptName: 'ConnectorZabbix',
|
||||||
|
callbackRaiseEvent: mockCallbackRaiseEvent,
|
||||||
|
callbackSetStatusError: mockCallbackSetStatusError,
|
||||||
|
callbackSetStatusOK: mockCallbackSetStatusOK
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
items: new Array(),
|
||||||
|
callbackSaveState: mockCallbackSaveState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Creat mock subscription event handler with use of a webhook listener via express
|
||||||
|
//
|
||||||
|
var mockSubscriptionEvent = new Mock();
|
||||||
|
mockSubscriptionEvent.mockOnSubscriptionEvent(Script.onSubscriptionEvent, appContext.runtimeInfo.scriptName);
|
||||||
|
|
||||||
|
|
||||||
|
// Have mocked-prefix logging in the app
|
||||||
|
//
|
||||||
|
Script.setLogger(mockSubscriptionEvent.getLogger());
|
||||||
|
|
||||||
|
|
||||||
|
// Get Process Id for Actor
|
||||||
|
//
|
||||||
|
Script.onGetProcessId((object1, returnValue) => {
|
||||||
|
new Mock().mockOnGetProcessId(returnValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Configure app
|
||||||
|
//
|
||||||
|
Script.onConfigureApp((object1, returnValue) => {
|
||||||
|
}, appContext);
|
||||||
|
|
||||||
|
|
||||||
|
// Start
|
||||||
|
//
|
||||||
|
Script.onStartBackgroundJobs((object1, returnValue) => {
|
||||||
|
});
|
||||||
|
|
||||||
|
//const timeoutObj = setTimeout(onStopBackgroundJobs, 9500);
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Result {
|
||||||
|
|
||||||
|
constructor(ok, data) {
|
||||||
|
|
||||||
|
this._ok = ok;
|
||||||
|
this._data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
get ok() {
|
||||||
|
return this._ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
get data() {
|
||||||
|
|
||||||
|
return this._data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = Result;
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"open": {
|
||||||
|
"active": false,
|
||||||
|
"note": "Opened in Derdack with id"
|
||||||
|
},
|
||||||
|
"acknowledge": {
|
||||||
|
"active": true,
|
||||||
|
"note": "EA: Event was acknowledged by user "
|
||||||
|
},
|
||||||
|
"close": {
|
||||||
|
"active": false,
|
||||||
|
"note": "Test event id {{id}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,445 @@
|
||||||
|
|
||||||
|
var dotenv = require('dotenv').config({ path: __dirname + '/.env' })
|
||||||
|
var request = require('request');
|
||||||
|
|
||||||
|
const Result = require('./Result');
|
||||||
|
var Logger = require('./Logger');
|
||||||
|
|
||||||
|
const { readFileSync } = require('fs');
|
||||||
|
|
||||||
|
const merge = require('deepmerge');
|
||||||
|
|
||||||
|
const Mustache = require('mustache');
|
||||||
|
|
||||||
|
|
||||||
|
var defaultConfig = {
|
||||||
|
"open": {
|
||||||
|
"id": 0,
|
||||||
|
"active": false,
|
||||||
|
"note": "Opened in Derdack with id"
|
||||||
|
},
|
||||||
|
"acknowledge": {
|
||||||
|
"endpoint": "/events-service/api/v1.0/events/{{alert.externalEventId}}",
|
||||||
|
"sendF": request.patch,
|
||||||
|
"sendNF": request.post,
|
||||||
|
"id": 1,
|
||||||
|
"active": true,
|
||||||
|
"note": "EA: Event was acknowledged by user {{user.username}} and owner set",
|
||||||
|
"body": {
|
||||||
|
"status": "ACK",
|
||||||
|
"user_assigned": "{{user.username}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"close": {
|
||||||
|
"endpoint": "/events-service/api/v1.0/events/operations/close",
|
||||||
|
"sendF": request.post,
|
||||||
|
"id": 2,
|
||||||
|
"active": false,
|
||||||
|
"body": {
|
||||||
|
"eventIds": [
|
||||||
|
"{{alert.externalEventId}}"
|
||||||
|
],
|
||||||
|
"slots": {
|
||||||
|
"notes": "EA: Event was close by user {{user.username}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
onDispose: async function (callback) {
|
||||||
|
callback(null, await onDispose());
|
||||||
|
},
|
||||||
|
// Useful to let this app be configured in a UI by the user
|
||||||
|
onGetAppConfig: async function (callback) {
|
||||||
|
callback(null, await onGetAppConfig());
|
||||||
|
},
|
||||||
|
// Useful to let this app be configured in a UI by the user
|
||||||
|
onConfigureApp: async function (callback, context) {
|
||||||
|
callback(null, await onConfigureApp(context));
|
||||||
|
},
|
||||||
|
// Handle various events from EA related to the team or alerts
|
||||||
|
onSubscriptionEvent: async function (callback, event) {
|
||||||
|
callback(null, await onSubscriptionEvent(event));
|
||||||
|
},
|
||||||
|
onGetProcessId: function (callback) {
|
||||||
|
callback(null, (() => {
|
||||||
|
let process = require('process');
|
||||||
|
return process.pid;
|
||||||
|
})());
|
||||||
|
},
|
||||||
|
setLogger: (logger) => {
|
||||||
|
Logger = logger;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Context with config and callbacks from EA
|
||||||
|
var appContext = null;
|
||||||
|
|
||||||
|
async function onConfigureApp(context) {
|
||||||
|
let fnName = onConfigureApp.name;
|
||||||
|
try {
|
||||||
|
// Save app context locally here in that script. This is not failure save, of course
|
||||||
|
//
|
||||||
|
appContext = context;
|
||||||
|
|
||||||
|
// Build callbacks that allow us to send events to EA
|
||||||
|
//
|
||||||
|
if (appContext.state.callbackSaveState != undefined)
|
||||||
|
appContext.state.callbackSaveState = eval(appContext.state.callbackSaveState);
|
||||||
|
else
|
||||||
|
appContext.state.callbackSaveState = () => { };
|
||||||
|
|
||||||
|
if (appContext.runtimeInfo.callbackSetStatusError != undefined)
|
||||||
|
appContext.runtimeInfo.callbackSetStatusError = eval(appContext.runtimeInfo.callbackSetStatusError);
|
||||||
|
else
|
||||||
|
appContext.runtimeInfo.callbackSetStatusError = () => { };
|
||||||
|
|
||||||
|
|
||||||
|
if (appContext.runtimeInfo.callbackSetStatusOK != undefined)
|
||||||
|
appContext.runtimeInfo.callbackSetStatusOK = eval(appContext.runtimeInfo.callbackSetStatusOK);
|
||||||
|
else
|
||||||
|
appContext.runtimeInfo.callbackSetStatusOK = () => { };
|
||||||
|
|
||||||
|
if (appContext.runtimeInfo.callbackSendMail != undefined)
|
||||||
|
appContext.runtimeInfo.callbackSendMail = eval(appContext.runtimeInfo.callbackSendMail);
|
||||||
|
else
|
||||||
|
appContext.runtimeInfo.callbackSendMail = () => { };
|
||||||
|
|
||||||
|
Logger.writeLog(fnName, `Configured Target Url: ${appContext.config.targetUrl}`);
|
||||||
|
|
||||||
|
|
||||||
|
let customConfig = JSON.parse(readFileSync(__dirname + '/config.json'));
|
||||||
|
appContext.config["webhookConfig"]= merge(defaultConfig,customConfig);
|
||||||
|
|
||||||
|
console.log(appContext.config["webhookConfig"]);
|
||||||
|
|
||||||
|
|
||||||
|
//Check first if EnvironmentVaribales are set.
|
||||||
|
//Both JWT Token or apiKey are possible
|
||||||
|
if (process.env["bhome_access_key"] && process.env["bhome_access_secret_key"]) {
|
||||||
|
|
||||||
|
appContext.config["access_key"] = process.env["bhome_access_key"];
|
||||||
|
appContext.config["access_secret_key"] = process.env["bhome_access_secret_key"];
|
||||||
|
appContext.config["authmod"] = "Bearer";
|
||||||
|
|
||||||
|
} else if (process.env["bhome_api_token"]) {
|
||||||
|
|
||||||
|
appContext.config["api_key"] = process.env["bhome_api_key"];
|
||||||
|
appContext.config["authmod"] = "apiKey";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Parameters in URL overrides Environment Variables
|
||||||
|
let bhomUrl = new URL(appContext.config.targetUrl);
|
||||||
|
|
||||||
|
if(bhomUrl.searchParams.get("access_key") && bhomUrl.searchParams.get("access_secret_key")) {
|
||||||
|
appContext.config["access_key"] = bhomUrl.searchParams.get("access_key");
|
||||||
|
appContext.config["access_secret_key"] = bhomUrl.searchParams.get("access_secret_key");
|
||||||
|
appContext.config["authmod"] = "Bearer";
|
||||||
|
}
|
||||||
|
else if(bhomUrl.searchParams.get("apiKey")) {
|
||||||
|
appContext.config["api_key"] = bhomUrl.searchParams.get("apiKey");
|
||||||
|
appContext.config["authmod"] = "apiKey";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
Logger.writeLog(fnName, `Error on handling configuration: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onGetAppConfig() {
|
||||||
|
|
||||||
|
|
||||||
|
// App could update config with e.g. a current connection status
|
||||||
|
|
||||||
|
return appContext.config;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWebhookConfig(actionCode) {
|
||||||
|
|
||||||
|
for (var key of Object.keys(appContext.config["webhookConfig"])) {
|
||||||
|
if(appContext.config["webhookConfig"][key]["id"] == actionCode && appContext.config["webhookConfig"][key]["active"]==true) {
|
||||||
|
return appContext.config["webhookConfig"][key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("no active WebhookConfig found for action code "+ actionCode);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function onSubscriptionEvent(event) {
|
||||||
|
let fnName = onSubscriptionEvent.name;
|
||||||
|
Logger.writeLog(fnName, event.eventType);
|
||||||
|
|
||||||
|
if (!appContext.config["authmod"]) {
|
||||||
|
console.log("bhome_access_key, bhome_access_secret_key OR bhome_api_key must be set as environment variables");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Get Event ID
|
||||||
|
var eventId = event.alert.externalEventId;
|
||||||
|
Logger.writeLog(fnName, "Value EventID: " + eventId);
|
||||||
|
|
||||||
|
// Exit if no ZabbixEventID found
|
||||||
|
if (eventId == "") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let bhom_event_id = "";
|
||||||
|
for (param of event.alert.parameters) {
|
||||||
|
if (param.name.toLocaleLowerCase() == "event id") {
|
||||||
|
//Logger.writeLog(fnName, param.value);
|
||||||
|
bhom_event_id = param.value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bhom_event_id == "") {
|
||||||
|
Logger.writeLog(fnName, "Event update in BHOM failed! No bhome_event_id found! Please make sure to include Event ID in the webhook payload that gets sent from BHOM to EnterpriseAlert..");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Logger.writeLog(fnName, `bhom_event_id: ${bhom_event_id}`);
|
||||||
|
Logger.writeLog(fnName, `event type: ${event.eventType} and statusCode: ${event.alert.statusCode}`);
|
||||||
|
// Handle this update
|
||||||
|
//
|
||||||
|
var message = "";
|
||||||
|
var actionCode = 0;
|
||||||
|
if (event.eventType === 201 && event.alert.statusCode === 2) {
|
||||||
|
|
||||||
|
|
||||||
|
Logger.writeLog(fnName, `=== Alert was acked....`);
|
||||||
|
|
||||||
|
// ------------------
|
||||||
|
// Alert acknowledged
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
// Update status
|
||||||
|
actionCode = 1;
|
||||||
|
message = "Acknowledged by user: " + event.user.username;
|
||||||
|
}
|
||||||
|
else if (event.eventType === 201 && event.alert.statusCode === 4) {
|
||||||
|
|
||||||
|
Logger.writeLog(fnName, `=== Alert was resolved...`);
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Alert was resolved
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
// Updata Zabbix status
|
||||||
|
actionCode = 2;
|
||||||
|
message = "Closed by user: " + event.user.username;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (event.eventType === 203) {
|
||||||
|
|
||||||
|
Logger.writeLog(fnName, `=== Alert was annotated...`);
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Alert annotated
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
// Updata status
|
||||||
|
actionCode = 3;
|
||||||
|
//message = event.user.username + ": " + event.annotation.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actionCode > 0) {
|
||||||
|
|
||||||
|
// Forward status update
|
||||||
|
//
|
||||||
|
//sendStatusUpdate(eventId, actionCode, event.user.username, message);
|
||||||
|
|
||||||
|
var currentConfigWebook=getWebhookConfig(actionCode);
|
||||||
|
if(currentConfigWebook)
|
||||||
|
sendBhome(bhom_event_id, {event: event, config: currentConfigWebook});
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
Logger.writeLog(fnName, `Error on handling subscription event: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Logger.writeLog(fnName, 'onSubscriptionEvent end');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onDispose() {
|
||||||
|
let fnName = onDispose.name;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Logger.writeLog(fnName, 'onDispose start');
|
||||||
|
Logger.writeLog(fnName, 'onDispose end');
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
Logger.writeLog(fnName, `Unexpected error on dispose: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendBhome(eventId, context) {
|
||||||
|
|
||||||
|
//console.log("callback config access: " + currentConfigWebook);
|
||||||
|
authenticate(callbackSendRequest);
|
||||||
|
|
||||||
|
|
||||||
|
function callbackSendRequest(authHeaderValue) {
|
||||||
|
|
||||||
|
let replacedBodyString = Mustache.render(JSON.stringify(context.config.body), context.event);
|
||||||
|
|
||||||
|
let data = JSON.parse(replacedBodyString);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//var url = appContext.config.targetUrl+"/events-service/api/v1.0/events/" + eventId;
|
||||||
|
var url = appContext.config.targetUrl+Mustache.render(context.config.endpoint, context.event);
|
||||||
|
console.log(url);
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
//method: "PATCH",
|
||||||
|
body: data,
|
||||||
|
json: true,
|
||||||
|
url: url,
|
||||||
|
headers: {'Authorization': authHeaderValue}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("request authheadervalue: "+ authHeaderValue);
|
||||||
|
console.log("request options: "+ JSON.stringify(options));
|
||||||
|
console.log("request body: "+ JSON.stringify(data));
|
||||||
|
|
||||||
|
//request.patch(options, (error, response, body) => {
|
||||||
|
context.config.sendF(options, (error, response, body) => {
|
||||||
|
|
||||||
|
console.log("bhome respnse: \n" + JSON.stringify(response));
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.log("Error: "+ error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(response.statusCode == 200)
|
||||||
|
|
||||||
|
sendNote(authHeaderValue, context, eventId);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendNote(authHeaderValue, context, eventId) {
|
||||||
|
|
||||||
|
if(typeof context.config.sendNF == undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(!context.config.note)
|
||||||
|
return;
|
||||||
|
|
||||||
|
console.log("SEND Note: "+JSON.stringify(context));
|
||||||
|
|
||||||
|
let replacedNote= Mustache.render(context.config.note, context.event);
|
||||||
|
|
||||||
|
console.log("Replaced Note: "+ replacedNote);
|
||||||
|
|
||||||
|
var url = appContext.config.targetUrl+"/events-service/api/v1.0/events/operations/addNote";
|
||||||
|
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
"eventIds": [eventId],
|
||||||
|
"slots": {
|
||||||
|
"notes": replacedNote
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var options = {
|
||||||
|
method: 'POST',
|
||||||
|
body: data,
|
||||||
|
json: true,
|
||||||
|
url: url,
|
||||||
|
headers: {'Authorization': authHeaderValue}
|
||||||
|
};
|
||||||
|
|
||||||
|
context.config.sendNF(options, (error, response, body) => {
|
||||||
|
|
||||||
|
console.log("Add note bhome respnse: \n" + JSON.stringify(response));
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.log("Error: "+error)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(response.statusCode == 200)
|
||||||
|
console.log("note successfully added!");
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function authenticate(callbackSendRequest) {
|
||||||
|
|
||||||
|
let fnName = sendBhome.name;
|
||||||
|
Logger.writeLog(fnName, 'Sending to bhom');
|
||||||
|
|
||||||
|
|
||||||
|
if (appContext.config.authmod == "Bearer") {
|
||||||
|
var auth_data = {
|
||||||
|
"access_key": appContext.config.access_key,
|
||||||
|
"access_secret_key": appContext.config.access_secret_key
|
||||||
|
}
|
||||||
|
|
||||||
|
var auth_options = {
|
||||||
|
method: 'POST',
|
||||||
|
body: auth_data,
|
||||||
|
json: true,
|
||||||
|
url: "https://nttkub1-private-dev.at.nttdata-emea.com/ims/api/v1/access_keys/login",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
request(auth_options, (error, response, body) => {
|
||||||
|
|
||||||
|
console.log("Authentication Request status code: " + response.statusCode);
|
||||||
|
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.log("Error during authentication: " + error);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printing body
|
||||||
|
if (response.statusCode == "200") {
|
||||||
|
let auth="Bearer " + body.json_web_token;
|
||||||
|
callbackSendRequest(auth);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (appContext.config.authmod == "apiKey") {
|
||||||
|
let auth="apiKey " + appContext.config.apiKey;
|
||||||
|
callbackSendRequest(auth);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||||
|
var nodeExternals = require('webpack-node-externals');
|
||||||
|
module.exports = {
|
||||||
|
target: 'node',
|
||||||
|
//externals: [nodeExternals()],
|
||||||
|
externals: {
|
||||||
|
request: 'request'
|
||||||
|
},
|
||||||
|
externalsPresets: {
|
||||||
|
node: true // in order to ignore built-in modules like path, fs, etc.
|
||||||
|
},
|
||||||
|
mode: 'development',
|
||||||
|
entry: {
|
||||||
|
main: __dirname + '/src/index.js',
|
||||||
|
},
|
||||||
|
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
filename: 'Main.js',
|
||||||
|
library: "derdakbhom",
|
||||||
|
libraryTarget: "umd"
|
||||||
|
},
|
||||||
|
// module: {
|
||||||
|
// rules: [
|
||||||
|
// {
|
||||||
|
// test: /\.js$/,
|
||||||
|
// exclude: /node_modules/,
|
||||||
|
// loader: 'babel-loader'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// test: /\.jsx$/,
|
||||||
|
// exclude: /node_modules/,
|
||||||
|
// loader: 'babel-loader'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// plugins: [
|
||||||
|
// new BundleAnalyzerPlugin(),
|
||||||
|
// new webpack.IgnorePlugin({
|
||||||
|
// resourceRegExp: /^\.\/locale$/,
|
||||||
|
// contextRegExp: /request/,
|
||||||
|
// }),
|
||||||
|
// ]
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue