Merge branch '3.2' into 3.2-dev-new-menu

This commit is contained in:
Juanjo Jiménez 2018-03-20 12:52:22 +01:00
commit 37b9b367f1
10 changed files with 414 additions and 331 deletions

View File

@ -34,6 +34,14 @@ All notable changes to the Wazuh app project will be documented in this file.
- Now every index-pattern is **dynamically formatted** (for example, to enable the URLs in the *Vulnerabilities* tab).
- Several **code refactoring** for a better handling of possible use cases.
- And the best thing, **it's no longer needed to insert the sample alert**!
- **Improvements and changes to index-patterns** ([#320](https://github.com/wazuh/wazuh-kibana-app/pull/320)):
- There's a new route, `/get-list`, to fetch the index pattern list.
- We've removed and changes several functions for a proper management of index-patterns.
- We've improved the compatibility with user-created index-patterns, known to have unpredictable IDs.
- **Improvements to monitoring module** ([#322](https://github.com/wazuh/wazuh-kibana-app/pull/322)):
- We don't need the monitoring template insertion step anymore.
- Minor refactor to the whole module.
- Regenerate the index pattern if it's missing.
- Now the app healthcheck system only checks if the API and app **have the same `major.minor` version** ([#311](https://github.com/wazuh/wazuh-kibana-app/pull/311)):
- Previously, the API and app had to be on the same `major.minor.patch` version.
- Adjusted space between title and value in some cards showing Manager or Agent configurations ([#315](https://github.com/wazuh/wazuh-kibana-app/pull/315)).

View File

@ -42,27 +42,7 @@ app.controller('settingsController', function ($scope, $rootScope, $http, $route
const portRegEx = new RegExp(/^[0-9]{2,5}$/);
$scope.indexPatterns = [];
// Getting the index pattern list into the scope, but selecting only "valid" ones
for (let i = 0; i < $route.current.locals.ips.list.length; i ++) {
courier.indexPatterns.get($route.current.locals.ips.list[i].id)
.then((data) => {
let minimum = ["@timestamp", "full_log", "manager.name", "agent.id"];
let minimumCount = 0;
for (let j = 0; j < data.fields.length; j++) {
if (minimum.includes(data.fields[j].name)) {
minimumCount++;
}
}
if (minimumCount == minimum.length) {
$scope.indexPatterns.push($route.current.locals.ips.list[i]);
}
});
}
$scope.apiEntries = [];
if ($routeParams.tab){
$scope.submenuNavItem = $routeParams.tab;
}
@ -147,6 +127,8 @@ app.controller('settingsController', function ($scope, $rootScope, $http, $route
// Get settings function
const getSettings = async () => {
try {
const patternList = await genericReq.request('GET','/get-list',{});
$scope.indexPatterns = patternList.data.data;
const data = await genericReq.request('GET', '/api/wazuh-api/apiEntries');
for(const entry of data.data) $scope.showEditForm[entry._id] = false;
@ -259,7 +241,7 @@ app.controller('settingsController', function ($scope, $rootScope, $http, $route
extensions : tmpData.extensions
}
};
console.log($scope.apiEntries)
$scope.apiEntries.push(newEntry);
$scope.apiEntries = $scope.apiEntries.sort(sortByTimestamp);

View File

@ -51,7 +51,7 @@
<!-- Case 2b - There's pattern and there's only one-->
<span ng-if="showSelector" ng-show="theresPattern && patternList && patternList.length === 1" tooltip="Selected index pattern" tooltip-placement="bottom">
{{patternList[0].attributes.title}}
{{patternList[0].title}}
</span>
<!-- Settings tab button -->

View File

@ -3,25 +3,8 @@ require('ui/modules').get('app/wazuh', [])
return {
getPatternList: async () => {
try {
let patternList = [];
// Getting the index pattern list into the array,
// but selecting only "valid" ones
const len = $route.current.locals.ips.list.length;
let data;
for (let i = 0; i < len; i ++) {
data = await courier.indexPatterns.get($route.current.locals.ips.list[i].id)
let minimum = ["@timestamp", "full_log", "manager.name", "agent.id"];
let minimumCount = 0;
data.fields.filter(element => minimumCount += (minimum.includes(element.name)) ? 1 : 0);
if (minimumCount === minimum.length) {
patternList.push($route.current.locals.ips.list[i]);
}
}
return patternList;
const patternList = await genericReq.request('GET','/get-list',{});
return patternList.data.data;
} catch (error) {
errorHandler.handle(error,'Pattern Handler (getPatternList)');
if(!$rootScope.$$phase) $rootScope.$digest();

View File

@ -239,49 +239,6 @@ const getIp = (Promise, courier, config, $q, $rootScope, $window, $location, Pri
};
const getAllIp = (Promise, $q, $window, $rootScope, courier, config, $location, Private) => {
if (healthCheck($window, $rootScope) && !$location.path().includes("/settings")) {
let deferred = $q.defer();
$location.path('/health-check');
deferred.reject();
return deferred.promise;
} else {
const State = Private(StateProvider);
const savedObjectsClient = Private(SavedObjectsClientProvider);
return savedObjectsClient.find({
type: 'index-pattern',
fields: ['title'],
perPage: 10000
})
.then(({ savedObjects }) => {
/**
* In making the indexPattern modifiable it was placed in appState. Unfortunately,
* the load order of AppState conflicts with the load order of many other things
* so in order to get the name of the index we should use, and to switch to the
* default if necessary, we parse the appState with a temporary State object and
* then destroy it immediatly after we're done
*
* @type {State}
*/
const state = new State('_a', {});
const specified = !!state.index;
const exists = _.findIndex(savedObjects, o => o.id === state.index) > -1;
const id = exists ? state.index : config.get('defaultIndex');
state.destroy();
return Promise.props({
list: savedObjects,
loaded: courier.indexPatterns.get(id),
stateVal: state.index,
stateValFound: specified && exists
});
});
}
};
const getSavedSearch = (courier, $q, $window, $rootScope, savedSearches, $route) => {
if (healthCheck($window, $rootScope)) {
let deferred = $q.defer();
@ -311,15 +268,13 @@ routes
resolve: {
"checkAPI": settingsWizard,
"ip": getIp,
"ips": getAllIp,
"savedSearch": getSavedSearch
}
})
.when('/agents-preview', {
template: require('plugins/wazuh/templates/agents-prev/agents-prev.jade'),
resolve: {
"checkAPI": settingsWizard,
"ips": getAllIp
"checkAPI": settingsWizard
}
})
.when('/manager/:tab?/', {
@ -327,7 +282,6 @@ routes
resolve: {
"checkAPI": settingsWizard,
"ip": getIp,
"ips": getAllIp,
"savedSearch": getSavedSearch
}
})
@ -336,7 +290,6 @@ routes
resolve: {
"checkAPI": settingsWizard,
"ip": getIp,
"ips": getAllIp,
"savedSearch": getSavedSearch
}
})
@ -345,15 +298,11 @@ routes
resolve: {
"checkAPI": settingsWizard,
"ip": getIp,
"ips": getAllIp,
"savedSearch": getSavedSearch
}
})
.when('/settings/:tab?/', {
template: require('plugins/wazuh/templates/settings/settings.html'),
resolve: {
"ips": getAllIp
}
})
.when('/visualize/create?', {
redirectTo: function () {},

View File

@ -284,7 +284,7 @@
<div flex="20" layout="column" class="height-41 md-block wz-margin-top-17 wz-margin-right-15 wz-select-input">
<select flex class="kuiSelect wz-border-none cursor-pointer" ng-model="selectedIndexPattern" ng-change="changeIndexPattern(selectedIndexPattern)" aria-label="Select index pattern">
<option ng-repeat="indexPattern in indexPatterns" value="{{indexPattern.id}}">{{indexPattern.attributes.title}}</option>
<option ng-repeat="indexPattern in indexPatterns" value="{{indexPattern.id}}">{{indexPattern.title}}</option>
</select>
</div>
</md-card-content>

View File

@ -329,6 +329,59 @@ module.exports = (server, options) => {
module.exports = getConfig;
const getlist = async (req,res) => {
try {
const data = await elasticRequest
.callWithInternalUser('search', {
index: '.kibana',
type: 'doc',
body: {
"query":{
"match":{
"type": "index-pattern"
}
}
}
});
if(data && data.hits && data.hits.hits){
const minimum = ["@timestamp", "full_log", "manager.name", "agent.id"];
let list = [];
if(data.hits.hits.length === 0) throw new Error('There is no index pattern');
for(const index of data.hits.hits){
let valid, parsed;
try{
parsed = JSON.parse(index._source['index-pattern'].fields)
} catch (error){
continue;
}
valid = parsed.filter(item => minimum.includes(item.name));
if(valid.length === 4){
list.push({
id: index._id.split('index-pattern:')[1],
title: index._source['index-pattern'].title
})
}
}
return res({data: list});
}
throw new Error('The Elasticsearch request didn\'t fetch the expected data');
} catch(error){
return res({error: error.message}).code(500)
}
}
// Get index patterns list
server.route({
method: 'GET',
path: '/get-list',
handler: getlist
});
//Server routes
/*

View File

@ -147,7 +147,13 @@ module.exports = (server, options) => {
.callWithInternalUser('search', {
index: '.kibana',
type: 'doc',
q: `index-pattern.title:"${id}"`
body: {
"query": {
"match": {
"_id":"index-pattern:" + id
}
}
}
});
return data;
} catch (error) {

View File

@ -0,0 +1,32 @@
module.exports = {
"order": 0,
"template": "wazuh-monitoring*",
"settings": {
"index.refresh_interval": "5s"
},
"mappings": {
"wazuh-agent": {
"properties": {
"@timestamp": {
"type": "date",
"format": "dateOptionalTime"
},
"status": {
"type": "keyword"
},
"ip": {
"type": "keyword"
},
"host": {
"type": "keyword"
},
"name": {
"type": "keyword"
},
"id": {
"type": "keyword"
}
}
}
}
};

View File

@ -33,324 +33,394 @@ module.exports = (server, options) => {
}
// Check status and get agent status array
const checkStatus = (apiEntry, maxSize, offset) => {
if (!maxSize) {
log('monitoring.js', 'You must provide a max size');
server.log([blueWazuh, 'monitoring', 'error'], 'You must provide a max size');
}
const checkStatus = async (apiEntry, maxSize, offset) => {
try {
if (!maxSize) {
throw new Error('You must provide a max size')
}
const payload = {
offset: offset ? offset: 0,
limit : (250 < maxSize) ? 250 : maxSize
};
const options = {
headers: {
'wazuh-app-version': packageJSON.version
},
username: apiEntry.user,
password: apiEntry.password,
rejectUnauthorized: !apiEntry.insecure
};
const response = await needle('get', `${getPath(apiEntry)}/agents`, payload, options);
let payload = {
'offset': offset ? offset: 0,
'limit': (250 < maxSize) ? 250 : maxSize
};
let options = {
headers: {
'wazuh-app-version': packageJSON.version
},
username: apiEntry.user,
password: apiEntry.password,
rejectUnauthorized: !apiEntry.insecure
};
needle.request('get', `${getPath(apiEntry)}/agents`, payload, options, (error, response) => {
if (!error && !response.error && response.body.data.items) {
if (!response.error && response.body.data.items) {
agentsArray = agentsArray.concat(response.body.data.items);
if ((payload.limit + payload.offset) < maxSize) {
checkStatus(apiEntry, response.body.data.totalItems, payload.limit + payload.offset);
return checkStatus(apiEntry, response.body.data.totalItems, payload.limit + payload.offset);
} else {
saveStatus();
await saveStatus();
}
} else {
log('monitoring.js', 'Can not access Wazuh API');
server.log([blueWazuh, 'monitoring', 'error'], 'Can not access Wazuh API');
throw new Error('Can not access Wazuh API')
}
});
return;
} catch (error) {
log('monitoring.js', 'Can not access Wazuh API ' + error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], 'Can not access Wazuh API ' + error.message || error);
}
};
// Check API status twice and get agents total items
const checkAndSaveStatus = (apiEntry) => {
let payload = {
'offset': 0,
'limit': 1
};
let options = {
headers: {
'wazuh-app-version': packageJSON.version
},
username: apiEntry.user,
password: apiEntry.password,
rejectUnauthorized: !apiEntry.insecure
};
needle('get', `${getPath(apiEntry)}/agents`, payload, options)
.then((response) => {
const checkAndSaveStatus = async apiEntry => {
try{
const payload = {
'offset': 0,
'limit': 1
};
const options = {
headers: {
'wazuh-app-version': packageJSON.version
},
username: apiEntry.user,
password: apiEntry.password,
rejectUnauthorized: !apiEntry.insecure
};
const response = await needle('get', `${getPath(apiEntry)}/agents`, payload, options)
if (!response.error && response.body.data && response.body.data.totalItems) {
checkStatus(apiEntry, response.body.data.totalItems);
} else {
log('monitoring.js', 'Wazuh API credentials not found or are not correct. Open the app in your browser and configure it to start monitoring agents.');
server.log([blueWazuh, 'monitoring', 'error'], 'Wazuh API credentials not found or are not correct. Open the app in your browser and configure it to start monitoring agents.');
}
});
return;
} catch(error){
log('monitoring.js',error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], error.message || error);
}
};
// Load Wazuh API credentials from Elasticsearch document
const loadCredentials = (apiEntries) => {
if (typeof apiEntries === 'undefined' || !('hits' in apiEntries)) return;
const loadCredentials = async apiEntries => {
try {
if (typeof apiEntries === 'undefined' || !('hits' in apiEntries)) return;
const filteredApis = apiEntries.hits.filter((element, index, self) =>
index === self.findIndex((t) => (
t._source.api_user === element._source.api_user &&
t._source.api_password === element._source.api_password &&
t._source.url === element._source.url &&
t._source.api_port === element._source.api_port
))
);
for(let element of filteredApis) {
let apiEntry = {
'user': element._source.api_user,
'password': Buffer.from(element._source.api_password, 'base64').toString("ascii"),
'url': element._source.url,
'port': element._source.api_port,
'insecure': element._source.insecure
};
if (apiEntry.error) {
log('monitoring.js loadCredentials', apiEntry.error || apiEntry);
server.log([blueWazuh, 'monitoring', 'error'], `Error getting wazuh-api data: ${apiEntry.error}`);
break;
const filteredApis = apiEntries.hits.filter((element, index, self) =>
index === self.findIndex((t) => (
t._source.api_user === element._source.api_user &&
t._source.api_password === element._source.api_password &&
t._source.url === element._source.url &&
t._source.api_port === element._source.api_port
))
);
for(let element of filteredApis) {
let apiEntry = {
'user': element._source.api_user,
'password': Buffer.from(element._source.api_password, 'base64').toString("ascii"),
'url': element._source.url,
'port': element._source.api_port,
'insecure': element._source.insecure
};
if (apiEntry.error) {
log('monitoring.js loadCredentials', apiEntry.error || apiEntry);
server.log([blueWazuh, 'monitoring', 'error'], `Error getting wazuh-api data: ${apiEntry.error}`);
break;
}
await checkAndSaveStatus(apiEntry);
}
checkAndSaveStatus(apiEntry);
} catch(error){
log('monitoring.js',error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], error.message || error);
}
};
// Get API configuration from elastic and callback to loadCredentials
const getConfig = (callback) => {
elasticRequest.callWithInternalUser('search', {
index: '.wazuh',
type: 'wazuh-configuration'
})
.then(data => {
const getConfig = async callback => {
try {
const data = await elasticRequest.callWithInternalUser('search', {
index: '.wazuh',
type: 'wazuh-configuration'
})
if (data.hits.total > 0) {
callback(data.hits);
} else {
log('monitoring.js getConfig','no credentials');
callback({
'error': 'no credentials',
'error_code': 1
});
return callback(data.hits);
}
})
.catch(error => {
log('monitoring.js getConfig','no credentials');
return callback({
'error': 'no credentials',
'error_code': 1
});
} catch (error){
log('monitoring.js getConfig',error.message || error);
callback({
return callback({
'error': 'no elasticsearch',
'error_code': 2
});
});
}
};
// Importing Wazuh app visualizations and dashboards
const importAppObjects = (id) => {
log('monitoring.js importAppObjects','Importing Wazuh app visualizations...','info');
server.log([blueWazuh, 'monitoring', 'info'], 'Importing Wazuh app visualizations...');
const importAppObjects = async id => {
try {
app_objects = require(APP_OBJECTS_FILE);
} catch (error) {
log('monitoring.js importAppObjects', error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], 'Could not read the objects file.');
server.log([blueWazuh, 'monitoring', 'error'], 'Path: ' + APP_OBJECTS_FILE);
server.log([blueWazuh, 'monitoring', 'error'], 'Exception: ' + error.message || error);
}
let body = '';
for(let element of app_objects){
body += '{ "index": { "_index": ".kibana", "_type": "doc", ' +
'"_id": "' + element._type + ':' + element._id + '" } }\n';
let temp = {};
let aux = JSON.stringify(element._source);
aux = aux.replace("wazuh-monitoring", id);
aux = JSON.parse(aux);
temp[element._type] = aux;
if (temp[element._type].kibanaSavedObjectMeta.searchSourceJSON.index) {
temp[element._type].kibanaSavedObjectMeta.searchSourceJSON.index = id;
log('monitoring.js importAppObjects','Importing Wazuh app visualizations...','info');
server.log([blueWazuh, 'monitoring', 'info'], 'Importing Wazuh app visualizations...');
try {
app_objects = require(APP_OBJECTS_FILE);
} catch (error) {
log('monitoring.js importAppObjects', error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], 'Could not read the objects file.');
server.log([blueWazuh, 'monitoring', 'error'], 'Path: ' + APP_OBJECTS_FILE);
server.log([blueWazuh, 'monitoring', 'error'], 'Exception: ' + error.message || error);
}
temp["type"] = element._type;
body += JSON.stringify(temp) + "\n";
}
let body = '';
for(let element of app_objects){
body += '{ "index": { "_index": ".kibana", "_type": "doc", ' +
'"_id": "' + element._type + ':' + element._id + '" } }\n';
let temp = {};
let aux = JSON.stringify(element._source);
aux = aux.replace("wazuh-monitoring", id);
aux = JSON.parse(aux);
temp[element._type] = aux;
if (temp[element._type].kibanaSavedObjectMeta.searchSourceJSON.index) {
temp[element._type].kibanaSavedObjectMeta.searchSourceJSON.index = id;
}
temp["type"] = element._type;
body += JSON.stringify(temp) + "\n";
}
await elasticRequest.callWithInternalUser('bulk', {
index: '.kibana',
body: body
})
elasticRequest.callWithInternalUser('bulk', {
index: '.kibana',
body: body
})
.then(() => elasticRequest.callWithInternalUser('indices.refresh', {
index: ['.kibana', index_pattern]
}))
.then(() => {
await elasticRequest.callWithInternalUser('indices.refresh', {
index: ['.kibana', index_pattern]
})
log('monitoring.js importAppObjects', 'Wazuh app visualizations were successfully installed. App ready to be used.', 'info');
server.log([blueWazuh, 'monitoring', 'info'], 'Wazuh app visualizations were successfully installed. App ready to be used.');
})
.catch(error => {
return;
} catch (error) {
log('monitoring.js importAppObjects',error.message || error);
server.log([blueWazuh, 'server', 'error'], 'Error importing objects into elasticsearch. Bulk request failed.');
});
server.log([blueWazuh, 'server', 'error'], 'Error importing objects into elasticsearch. Bulk request failed.' + error.message || error);
}
};
// fetchAgents on demand
const fetchAgents = () => getConfig(loadCredentials);
// Configure Kibana patterns.
const configureKibana = () => {
log('monitoring.js configureKibana', `Creating index pattern: ${index_pattern}`, 'info');
server.log([blueWazuh, 'monitoring', 'info'], `Creating index pattern: ${index_pattern}`);
let patternId = 'index-pattern:' + index_pattern;
elasticRequest.callWithInternalUser('create', {
index: '.kibana',
type: 'doc',
id: patternId,
body: {
"type": 'index-pattern',
"index-pattern": {
"title": index_pattern,
"timeFieldName": '@timestamp'
const configureKibana = async () => {
try {
log('monitoring.js configureKibana', `Creating index pattern: ${index_pattern}`, 'info');
server.log([blueWazuh, 'monitoring', 'info'], `Creating index pattern: ${index_pattern}`);
let patternId = 'index-pattern:' + index_pattern;
await elasticRequest.callWithInternalUser('create', {
index: '.kibana',
type: 'doc',
id: patternId,
body: {
"type": 'index-pattern',
"index-pattern": {
"title": index_pattern,
"timeFieldName": '@timestamp'
}
}
}
})
.then(resp => {
})
log('monitoring.js configureKibana', `Created index pattern: ${index_pattern}`, 'info');
server.log([blueWazuh, 'monitoring', 'info'], `Created index pattern: ${index_pattern}`);
importAppObjects(index_pattern);
})
.catch(error => {
await importAppObjects(index_pattern);
return;
} catch(error) {
log('monitoring.js configureKibana',error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], 'Error creating index-pattern due to ' + error);
});
}
};
// Creating wazuh-monitoring index
const createIndex = (todayIndex) => {
elasticRequest.callWithInternalUser('indices.create', { index: todayIndex })
.then(() => {
const createIndex = async todayIndex => {
try {
await elasticRequest.callWithInternalUser('indices.create', { index: todayIndex });
log('monitoring.js createIndex', 'Successfully created today index.', 'info');
server.log([blueWazuh, 'monitoring', 'info'], 'Successfully created today index.');
insertDocument(todayIndex);
})
.catch(error => {
await insertDocument(todayIndex);
return;
} catch (error) {
log('monitoring.js createIndex', error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], `Could not create ${todayIndex} index on elasticsearch due to ` + error);
});
server.log([blueWazuh, 'monitoring', 'error'], `Could not create ${todayIndex} index on elasticsearch due to ` + error.message || error);
}
};
// Inserting one document per agent into Elastic. Bulk.
const insertDocument = (todayIndex) => {
let body = '';
if (agentsArray.length > 0) {
let managerName = agentsArray[0].name;
const insertDocument = async todayIndex => {
try {
let body = '';
if (agentsArray.length > 0) {
let managerName = agentsArray[0].name;
for(let element of agentsArray) {
body += '{ "index": { "_index": "' + todayIndex + '", "_type": "wazuh-agent" } }\n';
let date = new Date(Date.now()).toISOString();
element["@timestamp"] = date;
element["host"] = managerName;
body += JSON.stringify(element) + "\n";
}
if (body === '') return;
const response = await elasticRequest.callWithInternalUser('bulk', {
index: todayIndex,
type: 'agent',
body: body
})
for(let element of agentsArray) {
body += '{ "index": { "_index": "' + todayIndex + '", "_type": "wazuh-agent" } }\n';
let date = new Date(Date.now()).toISOString();
element["@timestamp"] = date;
element["host"] = managerName;
body += JSON.stringify(element) + "\n";
agentsArray.length = 0;
}
if (body === '') return;
elasticRequest.callWithInternalUser('bulk', {
index: todayIndex,
type: 'agent',
body: body
})
.then((response) => agentsArray.length = 0)
.catch(error => {
log('monitoring.js insertDocument', error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], 'Error inserting agent data into elasticsearch. Bulk request failed due to ' + error);
});
return;
} catch (error) {
log('monitoring.js insertDocument', error.message || error);
server.log([blueWazuh, 'monitoring', 'error'], 'Error inserting agent data into elasticsearch. Bulk request failed due to ' + error.message || error);
}
};
// Save agent status into elasticsearch, create index and/or insert document
const saveStatus = () => {
fDate = new Date().toISOString().replace(/T/, '-').replace(/\..+/, '').replace(/-/g, '.').replace(/:/g, '').slice(0, -7);
todayIndex = index_prefix + fDate;
const saveStatus = async () => {
try {
fDate = new Date().toISOString().replace(/T/, '-').replace(/\..+/, '').replace(/-/g, '.').replace(/:/g, '').slice(0, -7);
todayIndex = index_prefix + fDate;
const result = await elasticRequest.callWithInternalUser('indices.exists', { index: todayIndex })
result ? await insertDocument(todayIndex) : await createIndex(todayIndex);
elasticRequest.callWithInternalUser('indices.exists', { index: todayIndex })
.then((result) => {
if (result) insertDocument(todayIndex);
else createIndex(todayIndex);
})
.catch(error => {
return;
} catch (error) {
log('monitoring.js saveStatus', `Could not check if the index ${todayIndex} exists due to ${error.message || error}`);
server.log([blueWazuh, 'monitoring', 'error'], `Could not check if the index ${todayIndex} exists due to ` + error);
});
}
};
// Main. First execution when installing / loading App.
const init = () => {
log('monitoring.js init', 'Creating today index...', 'info');
server.log([blueWazuh, 'monitoring', 'info'], 'Creating today index...');
saveStatus();
let patternId = 'index-pattern:' + index_pattern;
elasticRequest.callWithInternalUser('get', {
index: '.kibana',
type: 'doc',
id: patternId
})
.then(data => {
log('monitoring.js init', 'Skipping index-pattern creation. Already exists.', 'info');
server.log([blueWazuh, 'monitoring', 'info'], 'Skipping index-pattern creation. Already exists.');
})
.catch(error => {
log('monitoring.js init', 'Didn\'t find wazuh-monitoring pattern for Kibana v6.x. Proceeding to create it...');
server.log([blueWazuh, 'monitoring', 'info'], "Didn't find wazuh-monitoring pattern for Kibana v6.x. Proceeding to create it...");
elasticRequest.callWithInternalUser('delete', {
index: '.kibana',
type: 'doc',
id: 'index-pattern:wazuh-monitoring-*'
})
.then(resp => {
const createWazuhMonitoring = async () => {
try{
const patternId = 'index-pattern:' + index_pattern;
try{
await elasticRequest.callWithInternalUser('delete', {
index: '.kibana',
type: 'doc',
id: 'index-pattern:wazuh-monitoring-*'
})
log('monitoring.js init', 'Successfully deleted old wazuh-monitoring pattern.', 'info');
server.log([blueWazuh, 'monitoring', 'info'], "Successfully deleted old wazuh-monitoring pattern.");
})
.catch(error => {
log('monitoring.js init', 'Didn\'t find old wazuh-monitoring pattern. Skipping deletion.');
server.log([blueWazuh, 'monitoring', 'info'], "Didn't find old wazuh-monitoring pattern. Skipping deletion.");
} catch (error) {
log('monitoring.js init', 'No need to delete old wazuh-monitoring pattern.', 'info');
server.log([blueWazuh, 'monitoring', 'info'], "No need to delete old wazuh-monitoring pattern.");
}
await configureKibana();
return;
}catch(error){
return Promise.reject(error);
}
}
const checkTemplate = async () => {
try {
log('monitoring.js checkTemplate', 'Updating wazuh-monitoring template...', 'info');
server.log([blueWazuh, 'monitoring', 'info'], "Updating wazuh-monitoring template...");
const monitoringTemplate = require('./integration-files/monitoring-template');
const data = await elasticRequest.callWithInternalUser('indices.putTemplate', {
name : 'wazuh-agent',
body : monitoringTemplate
});
configureKibana();
});
return;
} catch(error){
log('monitoring.js checkTemplate', 'Something went wrong updating wazuh-monitoring template...' + error.message || error);
server.log([blueWazuh, 'monitoring', 'info'], "Something went wrong updating wazuh-monitoring template..." + error.message || error);
return Promise.reject(error);
}
}
// Main. First execution when installing / loading App.
const init = async () => {
try {
log('monitoring.js init', 'Creating/Updating wazuh-agent template...', 'info');
await checkTemplate();
log('monitoring.js init', 'Creating today index...', 'info');
server.log([blueWazuh, 'monitoring', 'info'], 'Creating today index...');
await saveStatus();
const patternId = 'index-pattern:' + index_pattern;
await elasticRequest.callWithInternalUser('get', {
index: '.kibana',
type: 'doc',
id: patternId
});
log('monitoring.js init', 'Skipping index-pattern creation. Already exists.', 'info');
server.log([blueWazuh, 'monitoring', 'info'], 'Skipping index-pattern creation. Already exists.');
return;
} catch (error) {
server.log([blueWazuh, 'monitoring', 'error'], error.message);
log('monitoring.js init', 'Didn\'t find wazuh-monitoring pattern for Kibana v6.x. Proceeding to create it...');
server.log([blueWazuh, 'monitoring', 'info'], "Didn't find wazuh-monitoring pattern for Kibana v6.x. Proceeding to create it...");
return createWazuhMonitoring();
}
};
// Check Elasticsearch Server status and .kibana index presence
const checkElasticsearchServer = () => {
return new Promise(function (resolve, reject) {
elasticRequest.callWithInternalUser('indices.exists', { index: ".kibana" })
.then(data => {
if (data) server.plugins.elasticsearch.waitUntilReady().then(data => { resolve(data); });
else reject(data);
})
.catch(error => {
log('monitoring.js checkElasticsearchServer',error.message || error);
reject(error);
});
})
const checkElasticsearchServer = async () => {
try {
const data = await elasticRequest.callWithInternalUser('indices.exists', { index: ".kibana" });
if (data) {
const pluginsData = await server.plugins.elasticsearch.waitUntilReady();
return pluginsData;
}
return Promise.reject(data);
} catch(error){
log('monitoring.js checkElasticsearchServer',error.message || error);
return Promise.reject(error);
}
}
// Wait until Kibana server is ready
const checkKibanaStatus = () => {
checkElasticsearchServer().then(data => { init() })
.catch(error => {
const checkKibanaStatus = async () => {
try {
log('monitoring.js checkKibanaStatus','Waiting for Kibana and Elasticsearch servers to be ready...');
server.log([blueWazuh, 'monitoring', 'info'], 'Waiting for Kibana and Elasticsearch servers to be ready...');
await checkElasticsearchServer();
await init();
return;
} catch(error) {
log('monitoring.js checkKibanaStatus',error.message || error);
server.log([blueWazuh, 'monitoring', 'info'], 'Waiting for Kibana and Elasticsearch servers to be ready...');
setTimeout(() => checkKibanaStatus(), 3000);
});
}
};
// Check Kibana index and if it is prepared, start the initialization of Wazuh App.