2017-12-03 14:30:47 +00:00
|
|
|
const importAppObjects = require('../initialize');
|
|
|
|
|
2017-10-27 08:10:17 +00:00
|
|
|
module.exports = (server, options) => {
|
|
|
|
|
|
|
|
// Elastic JS Client
|
|
|
|
const elasticRequest = server.plugins.elasticsearch.getCluster('data');
|
2017-08-13 19:54:56 +00:00
|
|
|
|
2018-03-11 11:16:29 +00:00
|
|
|
const getTimeStamp = async (req,reply) => {
|
|
|
|
try {
|
2018-03-12 15:34:58 +00:00
|
|
|
|
2018-03-11 11:16:29 +00:00
|
|
|
const data = await elasticRequest.callWithInternalUser('search', {
|
|
|
|
index: '.wazuh-version',
|
2018-03-12 15:34:58 +00:00
|
|
|
type : 'wazuh-version'
|
2018-03-11 11:16:29 +00:00
|
|
|
})
|
2018-03-12 15:34:58 +00:00
|
|
|
|
|
|
|
if(data.hits &&
|
|
|
|
data.hits.hits[0] &&
|
|
|
|
data.hits.hits[0]._source &&
|
|
|
|
data.hits.hits[0]._source.installationDate &&
|
|
|
|
data.hits.hits[0]._source.lastRestart){
|
|
|
|
|
|
|
|
return reply({
|
|
|
|
installationDate: data.hits.hits[0]._source.installationDate,
|
|
|
|
lastRestart : data.hits.hits[0]._source.lastRestart
|
|
|
|
});
|
|
|
|
|
2018-03-11 11:16:29 +00:00
|
|
|
} else {
|
|
|
|
throw new Error('Could not fetch .wazuh-version index');
|
|
|
|
}
|
2018-03-12 15:34:58 +00:00
|
|
|
|
2018-03-11 11:16:29 +00:00
|
|
|
} catch (err) {
|
2018-03-22 12:35:58 +00:00
|
|
|
return reply({
|
|
|
|
statusCode: 500,
|
|
|
|
error : 99,
|
|
|
|
message : err.message || 'Could not fetch .wazuh-version index'
|
2018-03-11 11:16:29 +00:00
|
|
|
}).code(500);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-11 20:42:06 +00:00
|
|
|
//Handlers
|
2018-03-22 12:35:58 +00:00
|
|
|
const fetchElastic = async (req, payload) => {
|
|
|
|
try {
|
|
|
|
const data = await elasticRequest.callWithInternalUser('search', {
|
|
|
|
index: 'wazuh-alerts-3.x-*',
|
|
|
|
type: 'wazuh',
|
|
|
|
body: payload
|
|
|
|
});
|
|
|
|
|
|
|
|
return data;
|
|
|
|
} catch (error) {
|
|
|
|
return Promise.reject(error);
|
|
|
|
}
|
2016-11-09 19:11:15 +00:00
|
|
|
};
|
2017-08-13 19:54:56 +00:00
|
|
|
|
2018-03-22 12:35:58 +00:00
|
|
|
const getConfig = async (id, callback) => {
|
|
|
|
try {
|
|
|
|
const data = await elasticRequest.callWithInternalUser('get', {
|
|
|
|
index: '.wazuh',
|
|
|
|
type : 'wazuh-configuration',
|
|
|
|
id
|
2017-12-12 16:59:19 +00:00
|
|
|
});
|
2018-03-22 12:35:58 +00:00
|
|
|
|
|
|
|
return callback({
|
|
|
|
user : data._source.api_user,
|
|
|
|
password : Buffer.from(data._source.api_password, 'base64').toString("ascii"),
|
|
|
|
url : data._source.url,
|
|
|
|
port : data._source.api_port,
|
|
|
|
insecure : data._source.insecure,
|
|
|
|
cluster_info: data._source.cluster_info,
|
|
|
|
extensions : data._source.extensions
|
2017-10-20 18:53:56 +00:00
|
|
|
});
|
2018-03-22 12:35:58 +00:00
|
|
|
|
|
|
|
} catch (error){
|
|
|
|
return callback({ error: 'no elasticsearch', error_code: 2 });
|
|
|
|
}
|
2017-10-20 18:53:56 +00:00
|
|
|
};
|
|
|
|
|
2017-12-03 14:30:47 +00:00
|
|
|
// Updating Wazuh app visualizations and dashboards
|
2018-03-22 12:35:58 +00:00
|
|
|
const updateAppObjects = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
await elasticRequest.callWithInternalUser('deleteByQuery', {
|
|
|
|
index: '.kibana',
|
|
|
|
body : {
|
|
|
|
query: {
|
|
|
|
bool: {
|
|
|
|
must: { match: { 'visualization.title': 'Wazuh App*' } },
|
|
|
|
must_not: { match: { 'visualization.title': 'Wazuh App Overview General Agents status' } }
|
2017-10-27 08:10:17 +00:00
|
|
|
}
|
|
|
|
}
|
2018-03-22 12:35:58 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2017-12-03 14:30:47 +00:00
|
|
|
// Update the pattern in the configuration
|
2017-12-12 16:59:19 +00:00
|
|
|
importAppObjects(req.params.pattern);
|
2018-03-22 12:35:58 +00:00
|
|
|
|
|
|
|
return reply({ statusCode: 200, data: 'Index pattern updated' });
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
return reply({
|
|
|
|
statusCode: 500,
|
|
|
|
error : 9,
|
|
|
|
message : `Could not delete visualizations due to ${error.message || error}`
|
2017-10-27 08:10:17 +00:00
|
|
|
}).code(500);
|
2018-03-22 12:35:58 +00:00
|
|
|
}
|
2017-02-10 21:33:49 +00:00
|
|
|
};
|
2017-08-13 19:54:56 +00:00
|
|
|
|
2018-03-22 12:35:58 +00:00
|
|
|
const getTemplate = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
const data = await elasticRequest.callWithInternalUser('cat.templates', {})
|
|
|
|
|
2018-01-12 15:00:50 +00:00
|
|
|
if (req.params.pattern == "wazuh-alerts-3.x-*" && data.includes("wazuh-alerts-3.*")) {
|
2018-03-22 12:35:58 +00:00
|
|
|
return reply({
|
|
|
|
statusCode: 200,
|
|
|
|
status : true,
|
|
|
|
data : `Template found for ${req.params.pattern}`
|
2018-01-12 15:00:50 +00:00
|
|
|
});
|
2018-01-11 18:41:50 +00:00
|
|
|
} else {
|
2018-03-22 12:35:58 +00:00
|
|
|
|
|
|
|
const lastChar = req.params.pattern[req.params.pattern.length -1];
|
|
|
|
const array = data.match(/[^\s]+/g);
|
2018-01-18 11:44:58 +00:00
|
|
|
|
|
|
|
let pattern = req.params.pattern;
|
|
|
|
if (lastChar === '*') { // Remove last character if it is a '*'
|
|
|
|
pattern = pattern.slice(0, -1);
|
|
|
|
}
|
|
|
|
|
2018-01-14 13:05:54 +00:00
|
|
|
for (let i = 1; i < array.length; i++) {
|
2018-01-18 11:44:58 +00:00
|
|
|
if (array[i].includes(pattern) && array[i-1] == `wazuh`) {
|
2018-03-22 12:35:58 +00:00
|
|
|
return reply({
|
|
|
|
statusCode: 200,
|
|
|
|
status : true,
|
|
|
|
data : `Template found for ${req.params.pattern}`
|
2018-01-14 13:05:54 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2018-03-22 12:35:58 +00:00
|
|
|
|
|
|
|
return reply({
|
|
|
|
statusCode: 200,
|
|
|
|
status : false,
|
|
|
|
data : `No template found for ${req.params.pattern}`
|
|
|
|
});
|
2018-01-10 17:00:06 +00:00
|
|
|
}
|
2018-03-22 12:35:58 +00:00
|
|
|
|
|
|
|
} catch (error){
|
|
|
|
return reply({
|
|
|
|
statusCode: 500,
|
|
|
|
error : 10000,
|
|
|
|
message : `Could not retrieve templates from Elasticsearch due to ${error.message || error}`
|
2018-01-11 18:41:50 +00:00
|
|
|
}).code(500);
|
2018-03-22 12:35:58 +00:00
|
|
|
}
|
2018-01-10 17:00:06 +00:00
|
|
|
};
|
|
|
|
|
2018-03-22 12:35:58 +00:00
|
|
|
const checkPattern = async (req, reply) => {
|
|
|
|
try {
|
|
|
|
const response = await elasticRequest.callWithInternalUser('search', {
|
|
|
|
index: '.kibana',
|
|
|
|
body : { query: { bool: { must: { match: { type: 'index-pattern' } } } } }
|
|
|
|
})
|
|
|
|
|
|
|
|
const filtered = response.hits.hits.filter(item => item._source['index-pattern'].title === req.params.pattern);
|
|
|
|
|
|
|
|
return filtered.length >= 1 ?
|
|
|
|
reply({ statusCode: 200, status: true, data: 'Index pattern found' }) :
|
|
|
|
reply({ statusCode: 200, status: false, data: 'Index pattern not found' });
|
|
|
|
|
|
|
|
} catch (error) {
|
2018-01-11 18:41:50 +00:00
|
|
|
return reply({
|
2018-03-22 12:35:58 +00:00
|
|
|
statusCode: 500,
|
|
|
|
error : 10000,
|
|
|
|
message : `Something went wrong retrieving index-patterns from Elasticsearch due to ${error.message || error}`
|
2018-01-11 18:41:50 +00:00
|
|
|
}).code(500);
|
2018-03-22 12:35:58 +00:00
|
|
|
}
|
2018-01-11 18:41:50 +00:00
|
|
|
};
|
|
|
|
|
2018-03-22 12:35:58 +00:00
|
|
|
const getFieldTop = async (req, reply) => {
|
|
|
|
try{
|
|
|
|
// Top field payload
|
|
|
|
let payload = {
|
|
|
|
size: 1,
|
|
|
|
query: {
|
|
|
|
bool: {
|
|
|
|
must : [],
|
|
|
|
filter: { range: { '@timestamp': {} } }
|
2017-10-27 08:10:17 +00:00
|
|
|
}
|
2018-03-22 12:35:58 +00:00
|
|
|
},
|
|
|
|
aggs: {
|
|
|
|
'2': {
|
|
|
|
terms: {
|
|
|
|
field: '',
|
|
|
|
size : 1,
|
|
|
|
order: { _count: 'desc' }
|
2017-10-27 08:10:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-03-22 12:35:58 +00:00
|
|
|
};
|
2017-08-13 19:54:56 +00:00
|
|
|
|
2018-03-22 12:35:58 +00:00
|
|
|
// Set up time interval, default to Last 24h
|
|
|
|
const timeGTE = 'now-1d';
|
|
|
|
const timeLT = 'now';
|
|
|
|
payload.query.bool.filter.range['@timestamp']['gte'] = timeGTE;
|
|
|
|
payload.query.bool.filter.range['@timestamp']['lt'] = timeLT;
|
2017-10-27 08:10:17 +00:00
|
|
|
|
2017-12-03 14:30:47 +00:00
|
|
|
// Set up match for default cluster name
|
2018-03-22 12:35:58 +00:00
|
|
|
payload.query.bool.must.push(
|
|
|
|
req.params.mode === 'cluster' ?
|
|
|
|
{ match: { 'cluster.name': req.params.cluster } } :
|
|
|
|
{ match: { 'manager.name': req.params.cluster } }
|
|
|
|
);
|
|
|
|
|
|
|
|
payload.aggs['2'].terms.field = req.params.field;
|
2017-12-03 14:30:47 +00:00
|
|
|
|
2018-03-22 12:35:58 +00:00
|
|
|
const data = await fetchElastic(req, payload);
|
2016-11-09 19:11:15 +00:00
|
|
|
|
2018-03-22 12:35:58 +00:00
|
|
|
return (data.hits.total === 0 || typeof data.aggregations['2'].buckets[0] === 'undefined') ?
|
|
|
|
reply({ statusCode: 200, data: '' }) :
|
|
|
|
reply({ statusCode: 200, data: data.aggregations['2'].buckets[0].key });
|
2016-11-09 19:11:15 +00:00
|
|
|
|
2018-03-22 12:35:58 +00:00
|
|
|
} catch (error) {
|
|
|
|
return reply({
|
|
|
|
statusCode: 500,
|
|
|
|
error : 9,
|
|
|
|
message : error.message || error
|
2017-10-27 08:10:17 +00:00
|
|
|
}).code(500);
|
2018-03-22 12:35:58 +00:00
|
|
|
}
|
2016-11-09 19:11:15 +00:00
|
|
|
};
|
|
|
|
|
2017-10-27 08:19:16 +00:00
|
|
|
const getSetupInfo = (req, reply) => {
|
|
|
|
elasticRequest
|
2017-11-17 08:56:59 +00:00
|
|
|
.callWithInternalUser('search', {
|
2017-10-27 08:10:17 +00:00
|
|
|
index: '.wazuh-version',
|
|
|
|
type: 'wazuh-version'
|
2017-10-27 08:19:16 +00:00
|
|
|
})
|
2018-03-11 16:58:57 +00:00
|
|
|
.then(data => {
|
2017-10-27 08:19:16 +00:00
|
|
|
if (data.hits.total === 0) {
|
2017-10-27 08:10:17 +00:00
|
|
|
reply({
|
2017-10-27 08:19:16 +00:00
|
|
|
'statusCode': 200,
|
|
|
|
'data': ''
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
reply({
|
|
|
|
'statusCode': 200,
|
|
|
|
'data': data.hits.hits[0]._source
|
|
|
|
});
|
|
|
|
}
|
|
|
|
})
|
2018-03-11 16:58:57 +00:00
|
|
|
.catch(error => {
|
2017-10-27 08:19:16 +00:00
|
|
|
reply({
|
|
|
|
'statusCode': 500,
|
|
|
|
'error': 9,
|
|
|
|
'message': 'Could not get data from elasticsearch'
|
|
|
|
}).code(500);
|
|
|
|
});
|
2017-07-25 15:30:19 +00:00
|
|
|
};
|
2017-08-13 19:54:56 +00:00
|
|
|
|
2018-01-18 16:17:54 +00:00
|
|
|
const getCurrentlyAppliedPattern = (req, reply) => {
|
|
|
|
// We search for the currently applied pattern in the visualizations
|
|
|
|
elasticRequest .callWithInternalUser('search', {
|
|
|
|
index: '.kibana',
|
|
|
|
type: 'doc',
|
|
|
|
q: `visualization.title:"Wazuh App Overview General Metric alerts"`
|
|
|
|
})
|
2018-02-21 12:54:07 +00:00
|
|
|
.then(data => {
|
|
|
|
if(data && data.hits && data.hits.hits && data.hits.hits[0] && data.hits.hits[0]._source){
|
|
|
|
return reply({
|
|
|
|
statusCode: 200,
|
|
|
|
data: JSON.parse(data.hits.hits[0]._source.visualization.kibanaSavedObjectMeta.searchSourceJSON).index
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
throw Error('no_visualization');
|
|
|
|
}
|
2018-01-18 16:17:54 +00:00
|
|
|
})
|
2018-02-21 12:54:07 +00:00
|
|
|
.catch(error => {
|
|
|
|
if(error && error.message && error.message === 'no_visualization'){
|
|
|
|
return reply('kibana_index_pattern_error').code(500);
|
|
|
|
}
|
|
|
|
|
|
|
|
return reply('elasticsearch_down').code(500);
|
2018-01-18 16:17:54 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2017-10-20 18:53:56 +00:00
|
|
|
module.exports = getConfig;
|
|
|
|
|
2018-03-21 14:48:05 +00:00
|
|
|
const getAllowedIndices = async roles => {
|
|
|
|
try {
|
|
|
|
const xpacksec = await elasticRequest
|
|
|
|
.callWithInternalUser('search', {
|
|
|
|
index: '.security-6',
|
|
|
|
type: 'doc'
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
let allowedIndices = [];
|
|
|
|
for(const rol of roles){
|
|
|
|
const myIndices = xpacksec.hits.hits.filter(item => item._id === `role-${rol}`);
|
|
|
|
for(let set of myIndices){
|
|
|
|
if(set && set._source && set._source.indices){
|
|
|
|
for(let index of set._source.indices){
|
|
|
|
if(index.privileges.includes('read')){
|
|
|
|
for(let name of index.names){
|
|
|
|
allowedIndices.push(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return allowedIndices;
|
|
|
|
} catch (error) {
|
|
|
|
return Promise.reject(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const filterAllowedIndexPatternList = (allowedIndices,list) => {
|
|
|
|
let finalList = [];
|
|
|
|
for(let allowed of allowedIndices){
|
|
|
|
let sanitized = allowed[allowed.length-1] === '*' ? allowed.split('*')[0] : allowed;
|
|
|
|
for(let item of list){
|
|
|
|
if(item.title.includes(sanitized)){
|
|
|
|
finalList.push(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return finalList;
|
|
|
|
}
|
2018-03-17 11:33:07 +00:00
|
|
|
|
|
|
|
const getlist = async (req,res) => {
|
|
|
|
try {
|
2018-03-21 14:48:05 +00:00
|
|
|
const xpack = await elasticRequest.callWithInternalUser('cat.plugins', { });
|
|
|
|
const isXpackEnabled = typeof xpack === 'string' && xpack.includes('x-pack');
|
|
|
|
const isSuperUser = isXpackEnabled && req.auth.credentials.roles.includes('superuser');
|
|
|
|
const allowedIndices = isXpackEnabled && !isSuperUser ? await getAllowedIndices(req.auth.credentials.roles) : false;
|
2018-03-22 10:24:40 +00:00
|
|
|
|
2018-03-17 11:33:07 +00:00
|
|
|
const data = await elasticRequest
|
|
|
|
.callWithInternalUser('search', {
|
|
|
|
index: '.kibana',
|
|
|
|
type: 'doc',
|
|
|
|
body: {
|
|
|
|
"query":{
|
|
|
|
"match":{
|
|
|
|
"type": "index-pattern"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
2018-03-19 08:50:26 +00:00
|
|
|
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');
|
2018-03-19 11:42:35 +00:00
|
|
|
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));
|
2018-03-19 08:50:26 +00:00
|
|
|
if(valid.length === 4){
|
|
|
|
list.push({
|
|
|
|
id: index._id.split('index-pattern:')[1],
|
|
|
|
title: index._source['index-pattern'].title
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-03-17 11:33:07 +00:00
|
|
|
}
|
2018-03-21 14:48:05 +00:00
|
|
|
return res({data: isXpackEnabled && !isSuperUser ? filterAllowedIndexPatternList(allowedIndices,list) : list});
|
2018-03-17 11:33:07 +00:00
|
|
|
}
|
|
|
|
|
2018-03-19 08:50:26 +00:00
|
|
|
throw new Error('The Elasticsearch request didn\'t fetch the expected data');
|
2018-03-17 11:33:07 +00:00
|
|
|
|
|
|
|
} catch(error){
|
2018-03-22 10:24:40 +00:00
|
|
|
return res({error: error.message || error}).code(500)
|
2018-03-17 11:33:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get index patterns list
|
|
|
|
server.route({
|
|
|
|
method: 'GET',
|
|
|
|
path: '/get-list',
|
|
|
|
handler: getlist
|
|
|
|
});
|
2017-08-13 19:54:56 +00:00
|
|
|
//Server routes
|
2016-11-09 19:11:15 +00:00
|
|
|
|
2018-01-18 16:17:54 +00:00
|
|
|
/*
|
|
|
|
* GET /api/wazuh-elastic/current-pattern
|
|
|
|
* Returns the currently applied pattern
|
|
|
|
*
|
|
|
|
**/
|
|
|
|
server.route({
|
|
|
|
method: 'GET',
|
|
|
|
path: '/api/wazuh-elastic/current-pattern',
|
|
|
|
handler: getCurrentlyAppliedPattern
|
|
|
|
});
|
|
|
|
|
2018-01-10 17:00:06 +00:00
|
|
|
/*
|
|
|
|
* GET /api/wazuh-elastic/template/{pattern}
|
|
|
|
* Returns whether a correct template is being applied for the index-pattern
|
|
|
|
*
|
|
|
|
**/
|
|
|
|
server.route({
|
|
|
|
method: 'GET',
|
|
|
|
path: '/api/wazuh-elastic/template/{pattern}',
|
|
|
|
handler: getTemplate
|
|
|
|
});
|
|
|
|
|
2018-01-11 18:41:50 +00:00
|
|
|
/*
|
|
|
|
* GET /api/wazuh-elastic/pattern/{pattern}
|
2018-01-18 16:17:54 +00:00
|
|
|
* Returns whether the pattern exists or not
|
2018-01-11 18:41:50 +00:00
|
|
|
*
|
|
|
|
**/
|
|
|
|
server.route({
|
|
|
|
method: 'GET',
|
|
|
|
path: '/api/wazuh-elastic/pattern/{pattern}',
|
|
|
|
handler: checkPattern
|
|
|
|
});
|
|
|
|
|
2018-01-18 16:17:54 +00:00
|
|
|
|
|
|
|
|
2016-11-09 19:11:15 +00:00
|
|
|
/*
|
2017-10-27 08:10:17 +00:00
|
|
|
* GET /api/wazuh-elastic/top/{cluster}/{field}/{time?}
|
|
|
|
* Returns the agent with most alerts
|
|
|
|
*
|
|
|
|
**/
|
2016-11-09 19:11:15 +00:00
|
|
|
server.route({
|
|
|
|
method: 'GET',
|
2017-12-03 14:30:47 +00:00
|
|
|
path: '/api/wazuh-elastic/top/{mode}/{cluster}/{field}',
|
2016-11-09 19:11:15 +00:00
|
|
|
handler: getFieldTop
|
|
|
|
});
|
|
|
|
|
2017-10-27 08:10:17 +00:00
|
|
|
/*
|
2017-12-03 14:30:47 +00:00
|
|
|
* GET /api/wazuh-elastic/setup
|
|
|
|
* Return Wazuh Appsetup info
|
2017-10-27 08:10:17 +00:00
|
|
|
*
|
|
|
|
**/
|
2017-01-16 18:27:53 +00:00
|
|
|
server.route({
|
|
|
|
method: 'GET',
|
2017-12-03 14:30:47 +00:00
|
|
|
path: '/api/wazuh-elastic/setup',
|
|
|
|
handler: getSetupInfo
|
2017-08-13 19:54:56 +00:00
|
|
|
});
|
|
|
|
|
2017-10-27 08:10:17 +00:00
|
|
|
/*
|
2017-12-03 14:30:47 +00:00
|
|
|
* POST /api/wazuh-elastic/updatePattern
|
|
|
|
* Update the index pattern in the app visualizations
|
2017-10-27 08:10:17 +00:00
|
|
|
*
|
|
|
|
**/
|
2017-07-25 15:30:19 +00:00
|
|
|
server.route({
|
|
|
|
method: 'GET',
|
2017-12-03 14:30:47 +00:00
|
|
|
path: '/api/wazuh-elastic/updatePattern/{pattern}',
|
|
|
|
handler: updateAppObjects
|
2017-07-25 15:30:19 +00:00
|
|
|
});
|
2018-03-11 11:16:29 +00:00
|
|
|
|
|
|
|
server.route({
|
|
|
|
method: 'GET',
|
|
|
|
path: '/api/wazuh-elastic/timestamp',
|
|
|
|
handler: getTimeStamp
|
|
|
|
});
|
2017-10-27 08:10:17 +00:00
|
|
|
};
|