mirror of
https://github.com/valitydev/wazuh-kibana-app.git
synced 2024-11-07 10:18:57 +00:00
Register new agents interactive guide (#1504)
This commit is contained in:
parent
dfffd839b9
commit
0571154ebb
@ -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"
|
||||
]
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
}`,
|
||||
''
|
||||
);
|
||||
|
207
public/controllers/agent/components/register-agent.js
Normal file
207
public/controllers/agent/components/register-agent.js
Normal 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
|
||||
};
|
20
public/controllers/agent/components/register-guide-defs.js
Normal file
20
public/controllers/agent/components/register-guide-defs.js
Normal 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'
|
||||
};
|
@ -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);
|
||||
|
@ -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';
|
||||
|
@ -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', {
|
||||
|
@ -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>
|
@ -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());
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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>
|
Loading…
Reference in New Issue
Block a user