Register new agents interactive guide (#1504)

This commit is contained in:
Juanka Rodríguez 2019-06-05 15:06:28 +02:00 committed by Jesús Ángel
parent dfffd839b9
commit 0571154ebb
14 changed files with 426 additions and 698 deletions

View File

@ -1,31 +1,35 @@
{
"env": {
"node": true,
"es6": true,
"mocha": true,
"jquery": true
},
"parserOptions": {
"ecmaVersion": 7,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"globals": {
"XPACK_RBAC_ENABLED": true
},
"parser": "babel-eslint",
"rules": {
"node/exports-style": ["error", "module.exports"],
"no-console": "warn",
"semi": "off",
"no-process-exit": "error",
"no-extra-boolean-cast": "off",
"node/no-unpublished-require": 0,
"node/no-unsupported-features": 0,
"node/no-unsupported-features/es-syntax": 0
},
"plugins": ["node", "async-await"],
"extends": ["eslint:recommended", "plugin:node/recommended"]
"env": {
"node": true,
"es6": true,
"mocha": true,
"jquery": true
},
"parserOptions": {
"ecmaVersion": 7,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"globals": {
"XPACK_RBAC_ENABLED": true
},
"parser": "babel-eslint",
"rules": {
"node/exports-style": ["error", "module.exports"],
"no-console": "warn",
"semi": "off",
"no-process-exit": "error",
"no-extra-boolean-cast": "off",
"node/no-unpublished-require": 0,
"node/no-unsupported-features": 0,
"node/no-unsupported-features/es-syntax": 0
},
"plugins": ["node", "async-await"],
"extends": [
"eslint:recommended",
"plugin:node/recommended",
"plugin:react/recommended"
]
}

View File

@ -58,6 +58,7 @@
"eslint-plugin-async-await": "^0.0.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-node": "^7.0.1",
"eslint-plugin-react": "^7.13.0",
"mocha": "^5.2.0",
"prettier": "^1.14.2",
"tslint": "^5.11.0",

View File

@ -90,10 +90,12 @@ export class AgentsPreviewController {
this.$scope.$on('wazuhFetched', (ev, parameters) => {
ev.stopPropagation();
this.$scope.showNoAgents =
!parameters.items.length > 0 && !parameters.filters.length;
});
this.registerAgentsProps = {
addNewAgent: flag => this.addNewAgent(flag)
};
this.init = false;
//Load
this.load();
@ -199,6 +201,9 @@ export class AgentsPreviewController {
this.versions = unique.versions.map(item => ({ id: item }));
this.osPlatforms = unique.osPlatforms;
this.lastAgent = unique.lastAgent;
if (!this.lastAgent || !this.lastAgent.id) {
this.addNewAgent(true);
}
this.agentsCountActive = unique.summary.agentsCountActive;
this.agentsCountDisconnected = unique.summary.agentsCountDisconnected;
this.agentsCountNeverConnected = unique.summary.agentsCountNeverConnected;
@ -228,8 +233,8 @@ export class AgentsPreviewController {
return;
}
registerNewAgent(flag) {
this.$scope.registerNewAgent = flag;
addNewAgent(flag) {
this.addingNewAgent = flag;
}
reloadList() {

View File

@ -270,7 +270,8 @@ export class AgentsController {
this.$scope.isString = item => typeof item === 'string';
this.$scope.hasSize = obj =>
obj && typeof obj === 'object' && Object.keys(obj).length;
this.$scope.offsetTimestamp = (text, time) => this.offsetTimestamp(text, time);
this.$scope.offsetTimestamp = (text, time) =>
this.offsetTimestamp(text, time);
this.$scope.switchConfigTab = (
configurationTab,
sections,
@ -552,7 +553,7 @@ export class AgentsController {
(((agentInfo || {}).data || {}).data || {}).status ||
this.$scope.agent.status;
}
} catch (error) { } // eslint-disable-line
} catch (error) {} // eslint-disable-line
try {
this.$scope.showSyscheckFiles = false;
@ -599,7 +600,7 @@ export class AgentsController {
if (tab === 'syscollector')
try {
await this.loadSyscollector(this.$scope.agent.id);
} catch (error) { } // eslint-disable-line
} catch (error) {} // eslint-disable-line
if (tab === 'configuration') {
this.$scope.switchConfigurationTab('welcome');
} else {
@ -727,7 +728,7 @@ export class AgentsController {
{}
);
netifaceResponse = ((resultNetiface || {}).data || {}).data || false;
} catch (error) { } // eslint-disable-line
} catch (error) {} // eslint-disable-line
// This API call may fail so we put it out of Promise.all
let netaddrResponse = false;
@ -739,7 +740,7 @@ export class AgentsController {
);
netaddrResponse =
((resultNetaddrResponse || {}).data || {}).data || false;
} catch (error) { } // eslint-disable-line
} catch (error) {} // eslint-disable-line
// Before proceeding, syscollector data is an empty object
this.$scope.syscollector = {};
@ -755,7 +756,7 @@ export class AgentsController {
this.$scope.syscollector = {
hardware:
typeof hardwareResponse === 'object' &&
Object.keys(hardwareResponse).length
Object.keys(hardwareResponse).length
? { ...hardwareResponse }
: false,
os:
@ -798,7 +799,7 @@ export class AgentsController {
try {
data[0] = await this.apiReq.request('GET', `/agents/${id}`, {});
} catch (error) { } //eslint-disable-line
} catch (error) {} //eslint-disable-line
try {
data[1] = await this.apiReq.request(
@ -806,7 +807,7 @@ export class AgentsController {
`/syscheck/${id}/last_scan`,
{}
);
} catch (error) { } //eslint-disable-line
} catch (error) {} //eslint-disable-line
try {
data[2] = await this.apiReq.request(
@ -814,7 +815,7 @@ export class AgentsController {
`/rootcheck/${id}/last_scan`,
{}
);
} catch (error) { } //eslint-disable-line
} catch (error) {} //eslint-disable-line
const result = data.map(item => ((item || {}).data || {}).data || false);
@ -912,17 +913,17 @@ export class AgentsController {
}
/**
* This adds timezone offset to a given date
* @param {String} binding_text
* @param {String} date
*/
* This adds timezone offset to a given date
* @param {String} binding_text
* @param {String} date
*/
offsetTimestamp = (text, time) => {
try {
return text + this.timeService.offset(time);
} catch (error) {
return time !== '-' ? `${text}${time} (UTC)` : time;
}
}
};
/**
* Navigate to the groups of an agent
@ -997,7 +998,7 @@ export class AgentsController {
);
this.errorHandler.info(
`Policy monitoring scan launched successfully on agent ${
this.$scope.agent.id
this.$scope.agent.id
}`,
''
);

View File

@ -0,0 +1,207 @@
import React, { Component, Fragment } from 'react';
import {
EuiSteps,
EuiFlexGroup,
EuiFlexItem,
EuiPanel,
EuiButtonToggle,
EuiFieldText,
EuiText,
EuiCodeBlock,
EuiTitle,
EuiButtonIcon,
EuiButtonEmpty,
EuiCopy,
EuiPage,
EuiPageBody
} from '@elastic/eui';
import { RegisterGuideDefs } from './register-guide-defs';
import PropTypes from 'prop-types';
export class RegisterAgent extends Component {
constructor(props) {
super(props);
this.state = {
status: 'incomplete',
selectedOS: '',
serverAddress: '',
osSteps: {
rpm: 2,
deb: 4,
win: 1,
macos: 1
}
};
}
selectOS(os) {
this.setState({ selectedOS: os });
}
setServerAddress(event) {
this.setState({ serverAddress: event.target.value });
}
render() {
const rpmButton = (
<EuiButtonToggle
label="Red Hat / CentOS"
onChange={() => this.selectOS('rpm')}
fill={this.state.selectedOS === 'rpm'}
/>
);
const debButton = (
<EuiButtonToggle
label="Debian / Ubuntu"
onChange={() => this.selectOS('deb')}
fill={this.state.selectedOS === 'deb'}
/>
);
const windowsButton = (
<EuiButtonToggle
label="Windows"
onChange={() => this.selectOS('win')}
fill={this.state.selectedOS === 'win'}
/>
);
const macOSButton = (
<EuiButtonToggle
label="MacOS"
onChange={() => this.selectOS('macos')}
fill={this.state.selectedOS === 'macos'}
/>
);
const ipInput = (
<EuiFieldText
placeholder="Server address..."
value={this.state.serverAddress}
onChange={this.setServerAddress}
/>
);
const copyButton = {
position: 'relative',
float: 'right',
zIndex: '1000',
right: '8px',
top: '16px'
};
const codeBlock = {
zIndex: '100'
};
const customTexts = {
rpmText2: `WAZUH_MANAGER_IP='${
this.state.serverAddress
}' yum install wazuh-agent`,
debText4: `WAZUH_MANAGER_IP='${
this.state.serverAddress
}' apt-get install wazuh-agent`,
macosText1: `launchctl setenv WAZUH_MANAGER_IP '${
this.state.serverAddress
}' && installer -pkg wazuh-agent-.pkg -target /`,
winText1: `wazuh-agent-3.9.1-1.msi /q ADDRESS='${
this.state.serverAddress
}' AUTHD_SERVER='${this.state.serverAddress}'`
};
let text = '';
for (let i = 0; i < this.state.osSteps[this.state.selectedOS]; i++) {
const field = `${this.state.selectedOS}Text${i + 1}`;
text = text.concat(`${RegisterGuideDefs[field] || customTexts[field]}\n`);
}
const guide = (
<div>
{(this.state.selectedOS) && (
<EuiText>
<div style={copyButton}>
<EuiCopy textToCopy={text}>
{copy => (
<EuiButtonIcon
onClick={copy}
iconType="copy"
aria-label="Copy"
/>
)}
</EuiCopy>
</div>
<EuiCodeBlock style={codeBlock} language="js">
{text}
</EuiCodeBlock>
</EuiText>
)}
</div>
);
const steps = [
{
title: 'Choose your OS',
children: (
<Fragment>
{rpmButton} {debButton} {windowsButton} {macOSButton}
</Fragment>
)
},
{
title: 'Wazuh server address',
children: <Fragment>{ipInput}</Fragment>
},
{
title: 'Complete the installation',
children: (
<div>
<Fragment>
<div>{guide}</div>
</Fragment>
</div>
)
}
];
return (
<div>
<EuiPage restrictWidth="1000px">
<EuiPageBody>
<EuiFlexGroup>
<EuiFlexItem>
<EuiTitle>
<h2>Add a new agent</h2>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
size="s"
onClick={() => this.props.addNewAgent(false)}
iconType="cross"
>
close
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup>
<EuiFlexItem>
<EuiPanel>
<EuiFlexItem>
<EuiSteps steps={steps} />
</EuiFlexItem>
</EuiPanel>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPageBody>
</EuiPage>
</div>
);
}
}
RegisterAgent.propTypes = {
addNewAgent: PropTypes.func
};

View File

@ -0,0 +1,20 @@
/*
* Wazuh app - Wazuh Register Agents Component steps texts
* Copyright (C) 2015-2019 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.
*/
export const RegisterGuideDefs = {
rpmText1:
'rpm --import http://packages.wazuh.com/key/GPG-KEY-WAZUH\ncat > /etc/yum.repos.d/wazuh.repo <<EOF\n[wazuh_repo]\ngpgcheck=1\ngpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH\nenabled=1\nname=Wazuh repository\nbaseurl=https://packages.wazuh.com/3.x/yum/\nprotect=1\nEOF',
debText1: 'apt-get install curl apt-transport-https lsb-release',
debText2:
'curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | apt-key add -',
debText3:
'echo "deb https://packages.wazuh.com/3.x/apt/ stable main" | tee /etc/apt/sources.list.d/wazuh.list\napt-get update'
};

View File

@ -12,9 +12,11 @@
import { uiModules } from 'ui/modules';
import { AgentsPreviewController } from './agents-preview';
import { AgentsController } from './agents';
import { RegisterAgent } from './components/register-agent';
const app = uiModules.get('app/wazuh', []);
app
.controller('agentsController', AgentsController)
.controller('agentsPreviewController', AgentsPreviewController);
.controller('agentsPreviewController', AgentsPreviewController)
.value('RegisterAgent', RegisterAgent);

View File

@ -29,7 +29,5 @@ import './wz-multiple-selector/wz-multiple-selector';
import './wz-multiple-selector/wz-multiple-selector.less';
import './wz-list-manage/wz-list-manage';
import './wz-kbn-switch/wz-kbn-switch';
import './wz-register-agents/wz-register-agents';
import './wz-register-agents/wz-register-agents.less';
import './wz-add-filter-chip/wz-add-filter-chip';
import './wz-add-filter-chip/wz-add-filter-chip.less';

View File

@ -69,12 +69,12 @@ class WzConfigViewer {
bindXmlListener();
};
$(window).on('resize', function () {
$(window).on('resize', function() {
dynamicHeight();
});
const dynamicHeight = () => {
setTimeout(function () {
setTimeout(function() {
const editorContainer = $('.configViewer');
const windows = $(window).height();
const offsetTop = getPosition(editorContainer[0]).y;
@ -90,7 +90,7 @@ class WzConfigViewer {
}
if ($scope.jsoncontent != false) {
$scope.jsonCodeBox.setValue($scope.jsoncontent.replace(/\\\\/g, '\\'));
setTimeout(function () {
setTimeout(function() {
$scope.jsonCodeBox.refresh();
$scope.$applyAsync();
window.dispatchEvent(new Event('resize')); // eslint-disable-line
@ -106,12 +106,12 @@ class WzConfigViewer {
}
if ($scope.xmlcontent != false) {
$scope.xmlCodeBox.setValue($scope.xmlcontent);
setTimeout(function () {
setTimeout(function() {
$scope.xmlCodeBox.refresh();
$scope.$applyAsync();
$scope.isLogs
? dynamicHeight()
: window.dispatchEvent(new Event('resize'));
: window.dispatchEvent(new Event('resize')); // eslint-disable-line
}, 200);
}
};
@ -130,7 +130,7 @@ class WzConfigViewer {
const bindXmlListener = () => {
var scrollElement = $scope.xmlCodeBox.getScrollerElement();
$(scrollElement).bind('scroll', function (e) {
$(scrollElement).bind('scroll', function(e) {
var element = $(e.currentTarget)[0];
if (element.scrollHeight - element.scrollTop === element.clientHeight) {
$scope.$emit('scrolledToBottom', {

View File

@ -1,221 +0,0 @@
<div class="tutorial">
<md-nav-bar class="wz-nav-bar nav-bar-white-bg tutorial-nav-bar" md-selected-nav-item="registerObj.selectedSystemTab"
nav-bar-aria-label="System" class="wz-margin-bottom-25">
<md-nav-item class="wz-nav-item" md-nav-click="setSystem('linux')" name="linux"><i class="fa fa-linux"></i>
Linux</md-nav-item>
<md-nav-item class="wz-nav-item" md-nav-click="setSystem('windows')" name="windows"><i class="fa fa-windows"></i>
Windows</md-nav-item>
<md-nav-item class="wz-nav-item" md-nav-click="setSystem('osx')" name="osx"><i class="fa fa-apple"></i>
OSX</md-nav-item>
</md-nav-bar>
<!-- Linux -->
<div ng-if="registerObj.selectedSystem === 0">
<div class="tutorial-step" ng-class="{'active' : registerObj.currentStep === 0, 'completed' : registerObj.currentStep > 0 }">
<div layout="row" class="tutorial-header">
<div class="step-number">
<p>1</p>
</div>
<h3 class="step-title">{{registerObj.systems[0].steps[0].title}}</h3>
</div>
<div class="tutorial-body">
<div layout="row">
<div class="wz-padding-right-16">
<label class="euiFormLabel">Agent name</label>
<div class="euiFormControlLayout wz-margin-top-4">
<div class="euiFormControlLayout__childrenWrapper">
<input type="text" class="euiFieldText" aria-label="default columns" ng-model="registerObj.systems[0].steps[0].agentName">
</div>
</div>
</div>
<div class="wz-padding-right-16">
<label class="euiFormLabel">Agent IP</label>
<div class="euiFormControlLayout wz-margin-top-4">
<div class="euiFormControlLayout__childrenWrapper">
<input type="text" class="euiFieldText" aria-label="default columns" ng-model="registerObj.systems[0].steps[0].agentIP">
</div>
</div>
</div>
<md-button ng-disabled="!registerObj.systems[0].steps[0].agentName || !registerObj.systems[0].steps[0].agentIP || addingAgent"
class="wz-button btn height-40" ng-click="addAgent()"><i class="fa fa-plus" ng-class="addingAgent ? 'fa-spin fa-spinner' : ''"></i>
Add agent
</md-button>
</div>
</div>
</div>
<div class="tutorial-step" ng-class="{'active' : registerObj.currentStep === 1, 'completed' : registerObj.currentStep > 1, 'disabled' : registerObj.currentStep < 1 }">
<div layout="row" class="tutorial-header">
<div class="step-number">
<p>2</p>
</div>
<h3 class="step-title">{{registerObj.systems[0].steps[1].title}}</h3>
</div>
<div class="tutorial-body">
<p class="tutorial-exit">Please execute the following command:</p>
<div class="wz-code-viewer">{{registerObj.systems[0].steps[1].code}}</div>
<md-button class="wz-button btn height-40 next-btn" ng-click="nextStep()"><i class="fa fa-success"></i>
Next
</md-button>
</div>
</div>
<div class="tutorial-step" ng-class="{'active' : registerObj.currentStep === 2, 'completed' : registerObj.currentStep > 2, 'disabled' : registerObj.currentStep < 2 }">
<div layout="row" class="tutorial-header">
<div class="step-number">
<p>3</p>
</div>
<h3 class="step-title">{{registerObj.systems[0].steps[2].title}}</h3>
</div>
<div class="tutorial-body">
<div class="wz-margin-bottom-10">
<label class="euiFormLabel">Manager IP</label>
<div class="euiFormControlLayout wz-margin-top-4">
<div class="euiFormControlLayout__childrenWrapper">
<input type="text" class="euiFieldText" aria-label="default columns" ng-model="registerObj.systems[0].steps[2].managerIp">
</div>
</div>
</div>
<p class="tutorial-exit" ng-show="registerObj.systems[0].steps[2].managerIp">Please execute the
following
command:</p>
<div ng-show="registerObj.systems[0].steps[2].managerIp" class="wz-code-viewer">
sed -i 's/MANAGER_IP/{{registerObj.systems[0].steps[2].managerIp}}/g' /var/ossec/etc/ossec.conf
</div>
<md-button ng-show="registerObj.systems[0].steps[2].managerIp" class="wz-button btn height-40 next-btn"
ng-click="nextStep()"><i class="fa fa-success"></i> Next
</md-button>
</div>
</div>
<div class="tutorial-step" ng-class="{'active' : registerObj.currentStep === 3, 'completed' : registerObj.currentStep > 3, 'disabled' : registerObj.currentStep < 3 }">
<div layout="row" class="tutorial-header">
<div class="step-number">
<p>4</p>
</div>
<h3 class="step-title">{{registerObj.systems[0].steps[3].title}}</h3>
</div>
<div class="tutorial-body">
<md-button class="wz-button wz-no-margin height-40" ng-click="restartAgent()"><i class="fa fa-refresh"
ng-class="restartingAgent ? 'fa-spin fa-spinner' : ''"></i>
Restart agent
</md-button>
</div>
</div>
</div>
<!-- Windows -->
<div ng-if="registerObj.selectedSystem === 1">
<div class="tutorial-step" ng-class="{'active' : registerObj.currentStep === 0, 'completed' : registerObj.currentStep > 0, 'disabled' : registerObj.currentStep < 0 }">
<div layout="row" class="tutorial-header">
<div class="step-number">
<p>1</p>
</div>
<h3 class="step-title">{{registerObj.systems[1].steps[0].title}}</h3>
</div>
<div class="tutorial-body">
<div layout="row" class="wz-margin-bottom-10">
<div class="wz-padding-right-16">
<label class="euiFormLabel">Agent name</label>
<div class="euiFormControlLayout wz-margin-top-4">
<div class="euiFormControlLayout__childrenWrapper">
<input type="text" class="euiFieldText" aria-label="default columns" ng-model="registerObj.systems[1].steps[0].agentName">
</div>
</div>
</div>
<div class="wz-padding-right-16">
<label class="euiFormLabel">Manager IP</label>
<div class="euiFormControlLayout wz-margin-top-4">
<div class="euiFormControlLayout__childrenWrapper">
<input type="text" class="euiFieldText" aria-label="default columns" ng-model="registerObj.systems[1].steps[0].managerIP">
</div>
</div>
</div>
<div class="wz-padding-right-16">
<label class="euiFormLabel">Authd service IP</label>
<div class="euiFormControlLayout wz-margin-top-4">
<div class="euiFormControlLayout__childrenWrapper">
<input type="text" class="euiFieldText" aria-label="default columns" ng-model="registerObj.systems[1].steps[0].authdIP">
</div>
</div>
</div>
</div>
<p class="tutorial-exit" ng-show="registerObj.systems[1].steps[0].agentName && registerObj.systems[1].steps[0].managerIP &&
registerObj.systems[1].steps[0].authdIP">Please
execute the following command:</p>
<div ng-show="registerObj.systems[1].steps[0].agentName && registerObj.systems[1].steps[0].managerIP &&
registerObj.systems[1].steps[0].authdIP"
class="wz-code-viewer">
wazuh-agent-3.8.2-1.msi /q ADDRESS="{{registerObj.systems[1].steps[0].managerIP}}"
AUTHD_SERVER="{{registerObj.systems[1].steps[0].authdIP}}"
AGENT_NAME="{{registerObj.systems[1].steps[0].agentName}}"
</div>
<md-button ng-show="registerObj.systems[1].steps[0].agentName && registerObj.systems[1].steps[0].managerIP &&
registerObj.systems[1].steps[0].authdIP"
class="wz-button btn height-40 next-btn" ng-click="nextStep()"><i class="fa fa-success"></i>
Next
</md-button>
</div>
</div>
</div>
<!-- OSX -->
<div ng-if="registerObj.selectedSystem === 2">
<div class="tutorial-step" ng-class="{'active' : registerObj.currentStep === 0, 'completed' : registerObj.currentStep > 0, 'disabled' : registerObj.currentStep < 0 }">
<div layout="row" class="tutorial-header">
<div class="step-number">
<p>1</p>
</div>
<h3 class="step-title">{{registerObj.systems[2].steps[0].title}}</h3>
</div>
<div class="tutorial-body">
<div class="wz-margin-bottom-10">
<label class="euiFormLabel">Manager IP</label>
<div class="euiFormControlLayout wz-margin-top-4">
<div class="euiFormControlLayout__childrenWrapper">
<input type="text" class="euiFieldText" aria-label="default columns" ng-model="registerObj.systems[2].steps[0].managerIp">
</div>
</div>
</div>
<p class="tutorial-exit" ng-show="registerObj.systems[2].steps[0].managerIp">Please execute the
following
command:</p>
<div ng-show="registerObj.systems[2].steps[0].managerIp" class="wz-code-viewer">
/Library/Ossec/bin/agent-auth -m {{registerObj.systems[2].steps[0].managerIp}}
</div>
<md-button ng-show="registerObj.systems[2].steps[0].managerIp" class="wz-button btn height-40 next-btn"
ng-click="nextStep()"><i class="fa fa-success"></i> Next
</md-button>
</div>
</div>
<div class="tutorial-step" ng-class="{'active' : registerObj.currentStep === 1, 'completed' : registerObj.currentStep > 1, 'disabled' : registerObj.currentStep < 1 }">
<div layout="row" class="tutorial-header">
<div class="step-number">
<p>2</p>
</div>
<h3 class="step-title">{{registerObj.systems[2].steps[1].title}}</h3>
</div>
<div class="tutorial-body">
<p class="tutorial-exit">Please execute the following command:</p>
<div class="wz-code-viewer">sed -i '' -e 's/MANAGER_IP/{{registerObj.systems[2].steps[0].managerIp}}/g'
/Library/Ossec/etc/ossec.conf</div>
<md-button class="wz-button btn height-40 next-btn" ng-click="nextStep()"><i class="fa fa-success"></i>
Next
</md-button>
</div>
</div>
<div class="tutorial-step" ng-class="{'active' : registerObj.currentStep === 2, 'completed' : registerObj.currentStep > 2, 'disabled' : registerObj.currentStep < 2 }">
<div layout="row" class="tutorial-header">
<div class="step-number">
<p>3</p>
</div>
<h3 class="step-title">{{registerObj.systems[2].steps[2].title}}</h3>
</div>
<div class="tutorial-body">
<p class="tutorial-exit">Please execute the following command:</p>
<div class="wz-code-viewer">
{{registerObj.systems[2].steps[2].code}}
</div>
<md-button class="wz-button btn height-40 next-btn" ng-click="nextStep()"><i class="fa fa-success"></i>
Next
</md-button>
</div>
</div>
</div>
</div>

View File

@ -1,181 +0,0 @@
/*
* Wazuh app - Wazuh register agents
* Copyright (C) 2015-2019 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 template from './wz-register-agents.html';
import { uiModules } from 'ui/modules';
const app = uiModules.get('app/wazuh', []);
class WzRegisterAgents {
/**
* Class constructor
*/
constructor() {
this.template = template;
this.restrict = 'E';
this.scope = {
reload: '&'
};
}
controller($scope, wazuhConfig, errorHandler, apiReq) {
const configuration = wazuhConfig.getConfig();
$scope.adminMode = !!(configuration || {}).admin;
const load = async () => {
$scope.registerObj = {
selectedSystem: 0,
selectedSystemTab: 'linux',
currentStep: 0,
systems: [
{
/* Linux */
steps: [
{
title: 'Add the agent to the manager'
},
{
title: 'Import the key to the agent',
code: '/var/ossec/bin/manage_agents -i '
},
{
title:
'Edit the Wazuh agent configuration to add the Wazuh manager IP'
},
{
title: 'Restart the agent'
}
]
},
{
/* Windows */
steps: [
{
title: 'Register the agent'
}
]
},
{
/* OSX */
steps: [
{
title: 'Register the agent'
},
{
title:
'Edit the Wazuh agent configuration to add the Wazuh manager IP'
},
{
title: 'Restart the agent',
code: '/Library/Ossec/bin/ossec-control restart'
}
]
}
]
};
};
load();
$scope.nextStep = () => {
$scope.registerObj.currentStep++;
if (
$scope.registerObj.currentStep >=
$scope.registerObj.systems[$scope.registerObj.selectedSystem].steps
.length
) {
$scope.restartingAgent = false;
$scope.reload();
load();
}
$scope.$applyAsync();
};
$scope.addAgent = async () => {
try {
$scope.addingAgent = true;
const data = await apiReq.request('POST', '/agents', {
name:
$scope.registerObj.systems[$scope.registerObj.selectedSystem]
.steps[0].agentName,
ip:
$scope.registerObj.systems[$scope.registerObj.selectedSystem]
.steps[0].agentIP
});
if (!(((data || {}).data || {}).data || {}).key) {
throw new Error('No agent key received');
} else {
$scope.registerObj.systems[
$scope.registerObj.selectedSystem
].steps[1].key = data.data.data.key;
$scope.registerObj.systems[
$scope.registerObj.selectedSystem
].steps[1].code += data.data.data.key;
$scope.registerObj.systems[
$scope.registerObj.selectedSystem
].steps[3].id = data.data.data.id;
}
$scope.addingAgent = false;
$scope.nextStep();
} catch (error) {
$scope.addingAgent = false;
errorHandler.handle(error.message || error);
}
$scope.$applyAsync();
return;
};
$scope.restartAgent = async () => {
$scope.restartingAgent = true;
try {
const data = await apiReq.request(
'PUT',
`/agents/${
$scope.registerObj.systems[$scope.registerObj.selectedSystem]
.steps[3].id
}/restart`,
{}
);
const result = ((data || {}).data || {}).data || false;
if (!result) {
throw new Error('Unexpected error restarting agent');
}
errorHandler.info(
`Success. Agent ${
$scope.registerObj.systems[$scope.registerObj.selectedSystem]
.steps[0].agentName
} has been registered.`
);
$scope.nextStep();
} catch (error) {
errorHandler.handle(error.message || error);
$scope.restartingAgent = false;
}
$scope.$applyAsync();
};
$scope.setSystem = system => {
$scope.registerObj.currentStep = 0;
load();
$scope.registerObj.selectedSystemTab = system;
switch (system) {
case 'linux':
$scope.registerObj.selectedSystem = 0;
break;
case 'windows':
$scope.registerObj.selectedSystem = 1;
break;
case 'osx':
$scope.registerObj.selectedSystem = 2;
break;
}
};
}
}
app.directive('wzRegisterAgents', () => new WzRegisterAgents());

View File

@ -1,112 +0,0 @@
/*
* Wazuh app - Wazuh register agents stylesheet
* Copyright (C) 2015-2019 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.
*/
/* -------------------------------------------------------------------------- */
/* ------------------ Wazuh register agents stylesheet ---------------------- */
/* -------------------------------------------------------------------------- */
.tutorial{
margin: 0 12%;
}
.registerNewAgent .tutorial{
margin: 0 !important;
}
.tutorial-nav-bar .md-nav-bar{
margin-bottom: 25px;
}
.tutorial-nav-bar .md-nav-bar ._md-nav-button{
padding: 15px 20px!important;
}
.tutorial-step{
margin-bottom: 15px;
}
.tutorial .tutorial-step:not(:last-child){
border-bottom: 2px dashed #e9e9e9;
}
.tutorial-header {
padding-bottom: 15px;
}
.tutorial-body {
padding: 0px 0px 15px 40px;
}
.tutorial-body button{
width: 150px;
}
.tutorial-body .layout-row button, .next-btn{
margin: 18px 0 0 0!important;
}
.tutorial-step.disabled .tutorial-body, .tutorial-step.completed .tutorial-body{
display: none;
}
.step-number{
width: 30px;
height: 30px;
border-radius: 50%;
color: white;
line-height: 30px;
font-size: 20px;
text-align: center;
}
.tutorial-step.active .step-number{
background: #007ba4;
}
.tutorial-step.disabled .step-number{
background: #c6c6c6;
}
.tutorial-step.completed .step-number{
background: #70ba56;
}
.step-title{
font-size: 17px;
line-height: 30px;
padding-left: 8px;
}
.tutorial-step.active .step-title{
color: #005571;
}
.tutorial-step.disabled .step-title{
color: #c6c6c6;
}
.tutorial-step.completed .step-title{
color: #70ba56;
}
.tutorial .wz-code-viewer{
text-align: left;
font-size: 12px!important;
padding: 5px;
height: auto;
}
.tutorial-exit{
font-family: monospace;
text-align: left;
padding: 8px 0 5px 0;
font-size: 12px;
}

View File

@ -990,4 +990,10 @@ wz-xml-file-editor {
discover-app-w .container-fluid {
background: #fff;
}
.registerAgent{
min-height: calc(~'100vh - 100px');
background: #fafbfd;
padding-top: 25px;
}

View File

@ -1,5 +1,4 @@
<div ng-if="!ctrl.init && !ctrl.loading && ctrl.errorInit" class="wz-margin-top-16" layout="column"
layout-align="start space-around">
<div ng-if="!ctrl.init && !ctrl.loading && ctrl.errorInit" class="wz-margin-top-16" layout="column" layout-align="start space-around">
<div flex layout="row" layout-align="center center">
<md-card flex="50" class="wz-md-card" flex>
<md-card-content class="wz-text-center">
@ -23,134 +22,133 @@
</div>
<div ng-if="!ctrl.init && !ctrl.loading && !ctrl.errorInit" layout="column" layout-align="start space-around">
<div class="md-padding euiFlexGroup--wrap layout-row">
<div class="layout-column md-padding">
<span class="wz-headline-title">
<react-component name="EuiIcon" props="{type:'node'}" /> Status
</span>
<md-divider class="wz-margin-top-10"></md-divider>
<canvas id="bar" ng-if="ctrl.lastAgent && ctrl.lastAgent.id" class="wz-margin-top-16 chart chart-doughnut"
chart-data="[ctrl.agentsCountActive,ctrl.agentsCountDisconnected,ctrl.agentsCountNeverConnected]"
chart-labels="['Active','Disconnected', 'Never connected']"
chart-colors="['#00a69b', '#ff645c', '#eff0f1']"
chart-options="{cutoutPercentage: 75, legend: {display: true,position: 'right',},responsive: false, maintainAspectRatio: false}" />
<div layout="row" class="wz-margin-top-16 layout-align-center-center"
ng-if="!ctrl.lastAgent || !ctrl.lastAgent.id">
There are no agents yet.
</div>
<div layout="row" class="wz-margin-top-16 layout-align-center-center"
ng-if="!ctrl.lastAgent || !ctrl.lastAgent.id">
<button class="kuiButton kuiButton--success" ng-click="ctrl.openRegistrationDocs()">
<react-component name="EuiIcon" props="{type: 'help'}" /> How to
</button>
</div>
</div>
<div flex class="layout-column md-padding">
<span class="wz-headline-title">
<react-component name="EuiIcon" props="{type:'visHeatmap'}" /> Details
</span>
<md-divider class="wz-margin-top-10"></md-divider>
<div
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow euiFlexGroup--responsive wz-margin-top-4">
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Active</p>
</div>
<p class="euiTitle euiTitle--small euiStat__title">{{ctrl.agentsCountActive}}</p>
</div>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Disconnected</p>
</div>
<p class="euiTitle euiTitle--small euiStat__title">{{ctrl.agentsCountDisconnected}}</p>
</div>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Never connected</p>
</div>
<p class="euiTitle euiTitle--small euiStat__title">{{ctrl.agentsCountNeverConnected}}</p>
</div>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Agents coverage</p>
</div>
<p class="euiTitle euiTitle--small euiStat__title">{{(ctrl.agentsCoverity | number:2)}}%</p>
</div>
</div>
</div>
<div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow euiFlexGroup--responsive">
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Last registered agent</p>
</div>
<p ng-if="ctrl.lastAgent && ctrl.lastAgent.id && ctrl.lastAgent.id !== '000'"
ng-click="ctrl.showAgent(ctrl.lastAgent)"
class="euiTitle euiTitle--small euiStat__title wz-text-link cursor-pointer">
{{ctrl.lastAgent.name}}</p>
<p ng-if="!ctrl.lastAgent || !ctrl.lastAgent.id"
class="euiTitle euiTitle--small euiStat__title">
-</p>
</div>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Most active agent</p>
</div>
<p ng-if="ctrl.lastAgent && ctrl.lastAgent.id && ctrl.mostActiveAgent.id !== '000'"
ng-click="ctrl.showAgent(ctrl.mostActiveAgent)"
class="euiTitle euiTitle--small euiStat__title wz-text-link cursor-pointer">
{{ctrl.mostActiveAgent.name}}</p>
<p ng-if="!ctrl.lastAgent || !ctrl.lastAgent.id"
class="euiTitle euiTitle--small euiStat__title">
-</p>
</div>
</div>
</div>
</div>
<div class="registerAgent" ng-show="ctrl.addingNewAgent">
<react-component name="RegisterAgent" props="ctrl.registerAgentsProps" />
</div>
<div layout="row" class="md-padding">
<wz-tag-filter flex path="'/agents'" query-fn="ctrl.query(q, search)" fields-model="ctrl.searchBarModel">
</wz-tag-filter>
<md-button class="agents-prev-btn btn btn-info" style="height: 48px;margin: 0px 0 0 8px!important;"
ng-click="ctrl.reloadList()">
<react-component name="EuiIcon" props="{type:'refresh'}" /> Refresh</md-button>
</div>
<div layout="row">
<md-card flex class="wz-md-card _md flex md-margin-h">
<md-card-content>
<div layout="row">
<wz-table custom-columns="true" flex path="'/agents'"
keys="[{value: 'id', width: '75px'},'name','ip','status','group','os.name','os.version','version', {value: 'dateAdd', offset: true}, {value: 'lastKeepAlive', offset: true}]"
allow-click="true" row-sizes="[17,15,13]"></wz-table>
<div ng-show="!ctrl.addingNewAgent">
<div class="md-padding euiFlexGroup--wrap layout-row">
<div class="layout-column md-padding">
<span class="wz-headline-title">
<react-component name="EuiIcon" props="{type:'node'}" /> Status
</span>
<md-divider class="wz-margin-top-10"></md-divider>
<canvas id="bar" ng-if="ctrl.lastAgent && ctrl.lastAgent.id" class="wz-margin-top-16 chart chart-doughnut"
chart-data="[ctrl.agentsCountActive,ctrl.agentsCountDisconnected,ctrl.agentsCountNeverConnected]"
chart-labels="['Active','Disconnected', 'Never connected']" chart-colors="['#00a69b', '#ff645c', '#eff0f1']"
chart-options="{cutoutPercentage: 75, legend: {display: true,position: 'right',},responsive: false, maintainAspectRatio: false}" />
<div layout="row" class="wz-margin-top-16 layout-align-center-center" ng-if="!ctrl.lastAgent || !ctrl.lastAgent.id">
There are no agents yet.
</div>
<div layout="row" layout-align="end center">
<button type="button" ng-click="ctrl.downloadCsv()"
class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--small">
<span class="euiButtonEmpty__content">
<react-component name="EuiIcon" props="{type:'importAction'}" />
<span class="euiButtonEmpty__text">Formatted</span>
</span>
<div layout="row" class="wz-margin-top-16 layout-align-center-center" ng-if="!ctrl.lastAgent || !ctrl.lastAgent.id">
<button class="kuiButton kuiButton--success" ng-click="ctrl.openRegistrationDocs()">
<react-component name="EuiIcon" props="{type: 'help'}" /> How to
</button>
</div>
</md-card-content>
</md-card>
</div>
<div flex class="layout-column md-padding">
<span class="wz-headline-title">
<react-component name="EuiIcon" props="{type:'visHeatmap'}" /> Details
</span>
<md-divider class="wz-margin-top-10"></md-divider>
<div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow euiFlexGroup--responsive wz-margin-top-4">
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Active</p>
</div>
<p class="euiTitle euiTitle--small euiStat__title">{{ctrl.agentsCountActive}}</p>
</div>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Disconnected</p>
</div>
<p class="euiTitle euiTitle--small euiStat__title">{{ctrl.agentsCountDisconnected}}</p>
</div>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Never connected</p>
</div>
<p class="euiTitle euiTitle--small euiStat__title">{{ctrl.agentsCountNeverConnected}}</p>
</div>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Agents coverage</p>
</div>
<p class="euiTitle euiTitle--small euiStat__title">{{(ctrl.agentsCoverity | number:2)}}%</p>
</div>
</div>
</div>
<div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--directionRow euiFlexGroup--responsive">
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Last registered agent</p>
</div>
<p ng-if="ctrl.lastAgent && ctrl.lastAgent.id && ctrl.lastAgent.id !== '000'" ng-click="ctrl.showAgent(ctrl.lastAgent)"
class="euiTitle euiTitle--small euiStat__title wz-text-link cursor-pointer">
{{ctrl.lastAgent.name}}</p>
<p ng-if="!ctrl.lastAgent || !ctrl.lastAgent.id" class="euiTitle euiTitle--small euiStat__title">
-</p>
</div>
</div>
<div class="euiFlexItem euiFlexItem--flexGrowZero">
<div class="euiStat">
<div class="euiText euiText--small euiStat__description">
<p>Most active agent</p>
</div>
<p ng-if="ctrl.lastAgent && ctrl.lastAgent.id && ctrl.mostActiveAgent.id !== '000'"
ng-click="ctrl.showAgent(ctrl.mostActiveAgent)" class="euiTitle euiTitle--small euiStat__title wz-text-link cursor-pointer">
{{ctrl.mostActiveAgent.name}}</p>
<p ng-if="!ctrl.lastAgent || !ctrl.lastAgent.id" class="euiTitle euiTitle--small euiStat__title">
-</p>
</div>
</div>
</div>
</div>
</div>
<div layout="row" class="md-padding">
<wz-tag-filter flex path="'/agents'" query-fn="ctrl.query(q, search)" fields-model="ctrl.searchBarModel">
</wz-tag-filter>
<md-button class="agents-prev-btn btn btn-info" style="height: 48px;margin: 0px 0 0 8px!important;"
ng-click="ctrl.reloadList()">
<react-component name="EuiIcon" props="{type:'refresh'}" /> Refresh</md-button>
</div>
<div layout="row">
<md-card flex class="wz-md-card _md flex md-margin-h">
<md-card-actions ng-if="adminMode" layout="row" layout-align="end center" class="wz-card-actions wz-card-actions-top">
<a ng-click="ctrl.addNewAgent(true)">
<react-component name="EuiIcon" props="{type:'plusInCircle'}" /> Add new agent </a>
<span flex></span>
</md-card-actions>
<md-card-content>
<div layout="row">
<wz-table custom-columns="true" flex path="'/agents'" keys="[{value: 'id', width: '75px'},'name','ip','status','group','os.name','os.version','version', {value: 'dateAdd', offset: true}, {value: 'lastKeepAlive', offset: true}]"
allow-click="true" row-sizes="[17,15,13]"></wz-table>
</div>
<div layout="row" layout-align="end center">
<button type="button" ng-click="ctrl.downloadCsv()" class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--small">
<span class="euiButtonEmpty__content">
<react-component name="EuiIcon" props="{type:'importAction'}" />
<span class="euiButtonEmpty__text">Formatted</span>
</span>
</button>
</div>
</md-card-content>
</md-card>
</div>
</div>
</div>