mirror of
https://github.com/valitydev/wazuh-kibana-app.git
synced 2024-11-06 18:05:20 +00:00
Update config.yml from app
This commit is contained in:
parent
e6b2203130
commit
3274c1dfe3
@ -63,6 +63,7 @@ export class SettingsController {
|
|||||||
this.addManagerContainer = false;
|
this.addManagerContainer = false;
|
||||||
this.showEditForm = {};
|
this.showEditForm = {};
|
||||||
this.formUpdate = {};
|
this.formUpdate = {};
|
||||||
|
this.editingKey = { 'key': false, 'type': '' };
|
||||||
|
|
||||||
this.userRegEx = new RegExp(/^.{3,100}$/);
|
this.userRegEx = new RegExp(/^.{3,100}$/);
|
||||||
this.passRegEx = new RegExp(/^.{3,100}$/);
|
this.passRegEx = new RegExp(/^.{3,100}$/);
|
||||||
@ -75,6 +76,10 @@ export class SettingsController {
|
|||||||
// Tab names
|
// Tab names
|
||||||
this.tabNames = TabNames;
|
this.tabNames = TabNames;
|
||||||
this.configuration = wazuhConfig.getConfig();
|
this.configuration = wazuhConfig.getConfig();
|
||||||
|
this.configurationTypes = [];
|
||||||
|
for (var key in this.configuration) {
|
||||||
|
this.configurationTypes[key] = typeof (this.configuration[key])
|
||||||
|
}
|
||||||
this.indexPatterns = [];
|
this.indexPatterns = [];
|
||||||
this.apiEntries = [];
|
this.apiEntries = [];
|
||||||
|
|
||||||
@ -187,7 +192,7 @@ export class SettingsController {
|
|||||||
|
|
||||||
this.errorHandler.info(
|
this.errorHandler.info(
|
||||||
`API ${
|
`API ${
|
||||||
this.apiEntries[index]._source.cluster_info.manager
|
this.apiEntries[index]._source.cluster_info.manager
|
||||||
} set as default`,
|
} set as default`,
|
||||||
'Settings'
|
'Settings'
|
||||||
);
|
);
|
||||||
@ -207,6 +212,21 @@ export class SettingsController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get configuration file
|
||||||
|
async setValueConfigurationFile(key, value) {
|
||||||
|
const data = {
|
||||||
|
key: key,
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
const config = await this.genericReq.request('PUT', '/utils/updateconfiguration', data);
|
||||||
|
return config;
|
||||||
|
} catch (error) {
|
||||||
|
this.errorHandler.handle('Error fetching configuration file');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get settings function
|
// Get settings function
|
||||||
async getSettings() {
|
async getSettings() {
|
||||||
try {
|
try {
|
||||||
@ -703,4 +723,26 @@ export class SettingsController {
|
|||||||
configEquivalence(key) {
|
configEquivalence(key) {
|
||||||
return configEquivalences[key] || '-';
|
return configEquivalences[key] || '-';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel edition of a configuration entry
|
||||||
|
*/
|
||||||
|
cancelEditKey() {
|
||||||
|
this.editingKey = { 'key': false, 'type': '' };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change value for a given configuration key
|
||||||
|
* @param {String} key Configuration key
|
||||||
|
* @param {String} newValue new configuration value for key
|
||||||
|
*/
|
||||||
|
editKey(key, newValue) {
|
||||||
|
this.setValueConfigurationFile(key, newValue).then(response => this.configurationFile = response.data);
|
||||||
|
//this.setValueConfigurationFile(key, newValue);
|
||||||
|
this.errorHandler.handle(
|
||||||
|
'You must restart kibana for the changes to take effect', '', true
|
||||||
|
);
|
||||||
|
this.configuration[key] = newValue;
|
||||||
|
this.editingKey = { 'key': false, 'type': '' };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,6 +310,17 @@ div.uil-ring-css {
|
|||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wz-input-text{
|
||||||
|
padding: 5px;
|
||||||
|
width: 100%;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-family: monospace;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 1px solid #D9D9D9;
|
||||||
|
-webkit-box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1);
|
||||||
|
box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Styles to override outline on components but avoid hidden shadow on focus */
|
/* Styles to override outline on components but avoid hidden shadow on focus */
|
||||||
/* These are really important fixex and should not be deleted */
|
/* These are really important fixex and should not be deleted */
|
||||||
|
|
||||||
|
@ -203,6 +203,10 @@
|
|||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-vertical-align-middle tr td{
|
||||||
|
vertical-align: middle!important;
|
||||||
|
}
|
||||||
|
|
||||||
.table-layout-fixed {
|
.table-layout-fixed {
|
||||||
table-layout: fixed !important;
|
table-layout: fixed !important;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
<div layout="column" layout-align="start stretch" ng-if="ctrl.tab === 'configuration' && !ctrl.load">
|
<div layout="column" layout-align="start stretch" ng-if="ctrl.tab === 'configuration' && !ctrl.load">
|
||||||
<!-- Headline -->
|
<!-- Headline -->
|
||||||
<div layout="column" layout-padding>
|
<div layout="column" layout-padding>
|
||||||
<span class="font-size-18"><i class="fa fa-fw fa-wrench" aria-hidden="true"></i> Wazuh Kibana plugin configuration settings</span>
|
<span class="font-size-18"><i class="fa fa-fw fa-wrench" aria-hidden="true"></i> Wazuh Kibana plugin
|
||||||
|
configuration settings</span>
|
||||||
<span class="md-subheader">Configuration file located at <span class="wz-text-monospace">/usr/share/kibana/plugins/wazuh/config.yml</span></span>
|
<span class="md-subheader">Configuration file located at <span class="wz-text-monospace">/usr/share/kibana/plugins/wazuh/config.yml</span></span>
|
||||||
</div>
|
</div>
|
||||||
<!-- End headline -->
|
<!-- End headline -->
|
||||||
@ -10,25 +11,43 @@
|
|||||||
<md-card-content>
|
<md-card-content>
|
||||||
<div layout="row">
|
<div layout="row">
|
||||||
<i class="fa fa-fw fa-file-o" aria-hidden="true"></i>
|
<i class="fa fa-fw fa-file-o" aria-hidden="true"></i>
|
||||||
<span class="wz-headline-title">Current configuration</span>
|
<span class="wz-headline-title">Current configuration</span>
|
||||||
<span flex></span>
|
<span flex></span>
|
||||||
<a tooltip="About and help" target="_blank" tooltip-placement="left" href="https://documentation.wazuh.com/current/user-manual/kibana-app/reference/config-file.html" aria-label="Link to open app about section">
|
<a tooltip="About and help" target="_blank" tooltip-placement="left" href="https://documentation.wazuh.com/current/user-manual/kibana-app/reference/config-file.html"
|
||||||
<i class="fa fa-fw fa-question-circle-o ng-scope" aria-hidden="true"></i>
|
aria-label="Link to open app about section">
|
||||||
</a>
|
<i class="fa fa-fw fa-question-circle-o ng-scope" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<md-divider class="wz-margin-top-10"></md-divider>
|
<md-divider class="wz-margin-top-10"></md-divider>
|
||||||
<div layout="row" class="wz-padding-top-10" >
|
<div layout="row" class="wz-padding-top-10">
|
||||||
<table class="table table-striped table-condensed table-layout-fixed">
|
<table class="table table-striped table-condensed table-layout-fixed table-vertical-align-middle">
|
||||||
<thead class="wz-text-bold">
|
<thead class="wz-text-bold">
|
||||||
<th class="wz-text-left col-lg-2">Setting</th>
|
<th class="wz-text-left col-lg-2">Setting</th>
|
||||||
<th class="wz-text-left col-lg-2">Value</th>
|
<th class="wz-text-left col-lg-2">Value</th>
|
||||||
<th class="wz-text-left">Description</th>
|
<th class="wz-text-left">Description</th>
|
||||||
|
<th class="wz-text-left">Actions</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="wz-word-wrap" ng-repeat="(key,value) in ctrl.configuration">
|
<tr class="wz-word-wrap" ng-repeat="(key,value) in ctrl.configuration" ng-style="ctrl.editingKey === key && {'background': '#e2f7ff'}">
|
||||||
<td>{{key}}</td>
|
<td>{{key}}</td>
|
||||||
<td>{{value}}</td>
|
<td>
|
||||||
|
<input id="input-{{key}}" class="wz-input-text" ng-show="ctrl.editingKey === key && ctrl.configurationTypes[key] === 'string'"
|
||||||
|
ng-model="newValue" ng-init="newValue = value"></input>
|
||||||
|
<!-- <input id="input-{{key}}" type="number" class="wz-input-text" ng-show="ctrl.editingKey === key && ctrl.configurationTypes[key] === 'number'"
|
||||||
|
ng-model="newValue" ng-init="newValue = value" min=0></input> -->
|
||||||
|
<select id="input-{{key}}" class="wz-input-text wz-width-100" ng-show="ctrl.editingKey === key && ctrl.configurationTypes[key] === 'boolean'"
|
||||||
|
ng-model="newValue" ng-init="newValue = value" ng-options="o as o for o in [true, false]"></select>
|
||||||
|
<span ng-show="!ctrl.editingKey || ctrl.editingKey !== key">{{value}}</span>
|
||||||
|
</td>
|
||||||
<td>{{ctrl.configEquivalence(key)}}</td>
|
<td>{{ctrl.configEquivalence(key)}}</td>
|
||||||
|
<td>
|
||||||
|
<span ng-show="!ctrl.editingKey || ctrl.editingKey !== key" tooltip="Edit" ng-click="ctrl.editingKey = key; ctrl.focusOnKey(key)"
|
||||||
|
class="fa fa-fw fa-pencil cursor-pointer"></span>
|
||||||
|
<span ng-show="ctrl.editingKey === key" tooltip="Cancel" class="fa fa-fw fa-times cursor-pointer"
|
||||||
|
ng-click="ctrl.cancelEditKey(); newValue = value"></span>
|
||||||
|
<span ng-show="ctrl.editingKey === key" tooltip="Apply" class="fa fa-fw fa-success cursor-pointer"
|
||||||
|
ng-click="ctrl.editKey(key, newValue)"></span>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -36,4 +55,4 @@
|
|||||||
</md-card-content>
|
</md-card-content>
|
||||||
</md-card>
|
</md-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -193,7 +193,7 @@ export class WazuhApiCtrl {
|
|||||||
req.idChanged = api._id;
|
req.idChanged = api._id;
|
||||||
return this.checkStoredAPI(req, reply);
|
return this.checkStoredAPI(req, reply);
|
||||||
}
|
}
|
||||||
} catch (error) {} // eslint-disable-line
|
} catch (error) { } // eslint-disable-line
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('POST /api/check-stored-api', error.message || error);
|
log('POST /api/check-stored-api', error.message || error);
|
||||||
@ -558,9 +558,9 @@ export class WazuhApiCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw response &&
|
throw response &&
|
||||||
response.body &&
|
response.body &&
|
||||||
response.body.error &&
|
response.body.error &&
|
||||||
response.body.message
|
response.body.message
|
||||||
? { message: response.body.message, code: response.body.error }
|
? { message: response.body.message, code: response.body.error }
|
||||||
: new Error('Unexpected error fetching data from the Wazuh API');
|
: new Error('Unexpected error fetching data from the Wazuh API');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -612,9 +612,9 @@ export class WazuhApiCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw response &&
|
throw response &&
|
||||||
response.body &&
|
response.body &&
|
||||||
response.body.error &&
|
response.body.error &&
|
||||||
response.body.message
|
response.body.message
|
||||||
? { message: response.body.message, code: response.body.error }
|
? { message: response.body.message, code: response.body.error }
|
||||||
: new Error('Unexpected error fetching data from the Wazuh API');
|
: new Error('Unexpected error fetching data from the Wazuh API');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -772,18 +772,18 @@ export class WazuhApiCtrl {
|
|||||||
) {
|
) {
|
||||||
const fields = req.payload.path.includes('/agents')
|
const fields = req.payload.path.includes('/agents')
|
||||||
? [
|
? [
|
||||||
'id',
|
'id',
|
||||||
'status',
|
'status',
|
||||||
'name',
|
'name',
|
||||||
'ip',
|
'ip',
|
||||||
'group',
|
'group',
|
||||||
'manager',
|
'manager',
|
||||||
'node_name',
|
'node_name',
|
||||||
'dateAdd',
|
'dateAdd',
|
||||||
'version',
|
'version',
|
||||||
'lastKeepAlive',
|
'lastKeepAlive',
|
||||||
'os'
|
'os'
|
||||||
]
|
]
|
||||||
: Object.keys(output.body.data.items[0]);
|
: Object.keys(output.body.data.items[0]);
|
||||||
|
|
||||||
const json2csvParser = new Parser({ fields });
|
const json2csvParser = new Parser({ fields });
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
// Require some libraries
|
// Require some libraries
|
||||||
import { ErrorResponse } from './error-response';
|
import { ErrorResponse } from './error-response';
|
||||||
import { getConfiguration } from '../lib/get-configuration';
|
import { getConfiguration} from '../lib/get-configuration';
|
||||||
|
import { updateConfigurationFile} from '../lib/update-configuration';
|
||||||
import { totalmem } from 'os';
|
import { totalmem } from 'os';
|
||||||
import simpleTail from 'simple-tail';
|
import simpleTail from 'simple-tail';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@ -43,6 +44,26 @@ export class WazuhUtilsCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the config.yml file in raw
|
||||||
|
* @param {Object} req
|
||||||
|
* @param {Object} reply
|
||||||
|
* @returns {Object} Configuration File or ErrorResponse
|
||||||
|
*/
|
||||||
|
updateConfigurationFile(req, reply) {
|
||||||
|
try {
|
||||||
|
const configFile = updateConfigurationFile(req);
|
||||||
|
|
||||||
|
return reply({
|
||||||
|
statusCode: 200,
|
||||||
|
error: 0,
|
||||||
|
data: configFile || {}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return ErrorResponse(error.message || error, 3019, 500, reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns total RAM available from the current machine where Kibana is being executed
|
* Returns total RAM available from the current machine where Kibana is being executed
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
|
@ -22,4 +22,4 @@ export function getConfiguration() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
53
server/lib/update-configuration.js
Normal file
53
server/lib/update-configuration.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Wazuh app - Module to update the configuration file
|
||||||
|
* Copyright (C) 2018 Wazuh, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Find more information about this on the LICENSE file.
|
||||||
|
*/
|
||||||
|
import fs from 'fs';
|
||||||
|
import readline from 'readline';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export function updateConfigurationFile(req) {
|
||||||
|
try {
|
||||||
|
const customPath = path.join(__dirname, '../../config.yml');
|
||||||
|
const data = fs.createReadStream(customPath);
|
||||||
|
const raw = fs.readFileSync(customPath, { encoding: 'utf-8' });
|
||||||
|
const rd = readline.createInterface({ input: data, console: false });
|
||||||
|
let notFound = true;
|
||||||
|
let findedLine = '';
|
||||||
|
rd.on('line', function (line) {
|
||||||
|
const trimLine = line.replace(/ /g, '');
|
||||||
|
if ((trimLine.indexOf(req.payload.key + ':') >= 0
|
||||||
|
|| trimLine.indexOf('#' + req.payload.key + ':') >= 0)
|
||||||
|
&& trimLine.indexOf('.' + req.payload.key + ':') === -1) {
|
||||||
|
notFound = false;
|
||||||
|
findedLine = line.replace(/(\r\n\t|\n|\r\t)/gm, '').trim();
|
||||||
|
}
|
||||||
|
}).on('close', () => {
|
||||||
|
if (notFound) {
|
||||||
|
fs.appendFile(customPath, '\r\n' + req.payload.key + ':' + req.payload.value, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const result = raw.replace(findedLine, req.payload.key + ' : ' + req.payload.value);
|
||||||
|
fs.writeFile(customPath, result, 'utf8', function (err) {
|
||||||
|
if (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,6 +23,15 @@ export function WazuhUtilsRoutes(server) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Returns the config.yml file in raw
|
||||||
|
server.route({
|
||||||
|
method: 'PUT',
|
||||||
|
path: '/utils/updateconfiguration',
|
||||||
|
handler(req, reply) {
|
||||||
|
return ctrl.updateConfigurationFile(req, reply);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Returns total RAM available from the current machine where Kibana is being executed
|
// Returns total RAM available from the current machine where Kibana is being executed
|
||||||
server.route({
|
server.route({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
Loading…
Reference in New Issue
Block a user