Skip to content

Commit

Permalink
Merge pull request #238 from wazuh/3.6-inventory
Browse files Browse the repository at this point in the history
3.6 Inventory section
  • Loading branch information
Jesús Ángel authored Sep 14, 2018
2 parents 8c0c02b + 1509820 commit 28d8120
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 28 deletions.
8 changes: 8 additions & 0 deletions SplunkAppForWazuh/appserver/static/css/styles/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,14 @@ kbn-vis .vis-container {
height: 16px;
}

.euiIcon--warning {
fill: #E5830E !important;
}

.euiIcon--success {
fill: #017F75 !important;
}

.euiIcon {
display: inline-block;
vertical-align: middle;
Expand Down
30 changes: 30 additions & 0 deletions SplunkAppForWazuh/appserver/static/js/config/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,36 @@ define(['./module'], function (module) {
}
})

// agents/:id
.state('ag-inventory', {
templateUrl: '/static/app/SplunkAppForWazuh/views/agents/inventory/inventory.html',
onEnter: ($navigationService) => { $navigationService.storeRoute('ag-inventory') },
controller: 'inventoryCtrl',
controllerAs: 'aic',
params: { id: null },
resolve: {
syscollector: ['$requestService', '$stateParams', '$currentDataService', ($requestService, $stateParams, $currentDataService) => {
const id = $stateParams.id || $currentDataService.getCurrentAgent() || '000'
return Promise.all([
$requestService.apiReq(`/syscollector/${id}/hardware`),
$requestService.apiReq(`/syscollector/${id}/os`),
$requestService.apiReq(`/syscollector/${id}/netiface`),
$requestService.apiReq(`/syscollector/${id}/ports`, { limit: 1 }),
$requestService.apiReq(`/syscollector/${id}/packages`, { limit: 1, select: 'scan_time' }),
$requestService.apiReq(`/agents/${id}`)
])
.then(function (response) {
return response
}, function (response) {
return response
})
.catch(err => {
console.error('Error route: ', err)
})
}]
}
})

// agents - General
.state('ag-general', {
templateUrl: 'static/app/SplunkAppForWazuh/views/agents/general/agents-general.html',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Wazuh app - Dev tools controller
* 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.
*/

define(['../../module'], function (module) {
'use strict'
class Inventory {
constructor($requestService, syscollector, $rootScope, $notificationService, $scope) {
this.vm = this
this.$scope = $scope
this.data = syscollector
this.httpReq = $requestService.httpReq
this.root = $rootScope
this.toast = $notificationService.showSimpleToast
}

/**
* Filters by a term in table
* @param {String} term
* @param {String} specificPath
*/
search(term, specificPath) { this.$scope.$broadcast('wazuhSearch', { term, specificPath }) }

/**
* Initialize
*/
$onInit() {
try {
this.vm.search = this.search
this.vm.agent = this.data[5].data.data
this.vm.getAgentStatusClass = agentStatus => agentStatus === "Active" ? "teal" : "red";
this.vm.formatAgentStatus = agentStatus => {
return ['Active', 'Disconnected'].includes(agentStatus) ? agentStatus : 'Never connected';
}
if (
!this.data[0] ||
!this.data[0].data ||
!this.data[0].data.data ||
typeof this.data[0].data.data !== 'object' ||
!Object.keys(this.data[0].data.data).length ||
!this.data[1] ||
!this.data[1].data ||
!this.data[1].data.data ||
typeof this.data[1].data.data !== 'object' ||
!Object.keys(this.data[1].data.data).length
) {
this.vm.syscollector = null
} else {
const netiface = {}
const ports = {}
const packagesDate = {}
if (this.data[2] && this.data[2].data && this.data[2].data.data)
Object.assign(netiface, this.data[2].data.data)
if (this.data[3] && this.data[3].data && this.data[3].data.data)
Object.assign(ports, this.data[3].data.data)
if (this.data[4] && this.data[4].data && this.data[4].data.data)
Object.assign(packagesDate, this.data[4].data.data)
this.vm.syscollector = {
hardware: this.data[0].data.data,
os: this.data[1].data.data,
netiface: netiface,
ports: ports,
packagesDate:
packagesDate && packagesDate.items && packagesDate.items.length
? packagesDate.items[0].scan_time
: 'Unknown'
}
}
return
} catch (error) {
this.toast(error.message || error)
}
}
}
// Logs controller
module.controller('inventoryCtrl', Inventory)
})
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ define(['../../module'], function (controllers) {

'use strict'

controllers.controller('agentsOverviewCtrl', function ($stateParams, agent) {
controllers.controller('agentsOverviewCtrl', function ($stateParams, $state, agent) {
const vm = this
vm.agent = agent[0].data.data
vm.agentOS = `${vm.agent.os.name} ${vm.agent.os.codename} ${vm.agent.os.version}`
vm.syscheck = agent[1].data.data
vm.id = $stateParams.id
vm.rootcheck = agent[2].data.data
try {
vm.agent = agent[0].data.data
vm.agentOS = `${vm.agent.os.name} ${vm.agent.os.codename} ${vm.agent.os.version}`
vm.syscheck = agent[1].data.data
vm.id = $stateParams.id
vm.rootcheck = agent[2].data.data
} catch (err) {
$state.go('agents')
}


vm.goGroups = async (group) => {
try {
const groupInfo = await $requestService.apiReq(`/groups`, { name: group })
Expand Down
1 change: 1 addition & 0 deletions SplunkAppForWazuh/appserver/static/js/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ define([
'./agents/pcidss/agentsPciCtrl',
'./agents/gdpr/agentsGdprCtrl',
'./agents/configuration/agentConfigCtrl',
'./agents/inventory/inventoryCtrl',
'./dev-tools/devToolsCtrl',
'./main/mainCtrl'
], function () {})
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ define(['../module', 'underscore'], function (directives, _) {
$scope.$emit('loadedTable')
if (!$scope.$$phase) $scope.$digest()
} catch (error) {
console.error('error ',error)
$notificationService.showSimpleToast(`Error while init table. ${error.message || error}`)
}
return
Expand Down Expand Up @@ -305,20 +306,34 @@ define(['../module', 'underscore'], function (directives, _) {
})

$scope.nonDecoderValue = (key, item) => {
return key === 'os.name' ?
(item.os && item.os.name ? item.os.name : false) || '---' :
key === 'os.version' ?
(item.os && item.os.version ? item.os.version : false) || '---' :
checkIfArray(item[key.value || key]) || '---'
return key.value === 'local.ip'
? (item.local && item.local.ip
? `${item.local.ip}:${item.local.port}`
: false) || '---'
: key === 'remote.ip'
? (item.remote && item.remote.ip
? `${item.remote.ip}:${item.remote.port}`
: false) || '---'
: key === 'os.name'
? (item.os && item.os.name ? item.os.name : false) || '---'
: key === 'os.version'
? (item.os && item.os.version ? item.os.version : false) ||
'---'
: checkIfArray(item[key.value || key]) || '---'
}

$scope.decoderValue = (key, item) => {
return key === 'details.program_name' || key.value === 'details.program_name' ?
(item.details && item.details.program_name ? item.details.program_name : false) || '---' :
key === 'details.order' || key.value === 'details.order' ?
(item.details && item.details.order ? item.details.order : false) || '---' :
checkIfArray(item[key.value || key]) || '---'
};
return key === 'details.program_name' ||
key.value === 'details.program_name'
? (item.details && item.details.program_name
? item.details.program_name
: false) || '---'
: key === 'details.order' || key.value === 'details.order'
? (item.details && item.details.order
? item.details.order
: false) || '---'
: checkIfArray(item[key.value || key]) || '---'
}

},
templateUrl: '/static/app/SplunkAppForWazuh/js/directives/wz-table/wz-table.html'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ define(['../module'], function (module) {
description: 'Description',
tag: 'Tag',
level: 'Level',
mergedSum: 'MD5 agent.conf',
hash: 'MD5 agent.conf',
configSum: 'Group MD5',
conf_sum: 'Group MD5 sum',
merged_sum: '"agent.conf" MD5 sum',
hash: 'MD5 sum',
filename: 'File',
file: 'File',
gdpr: 'GDPR',
Expand All @@ -40,17 +40,26 @@ define(['../module'], function (module) {
path: 'Path',
details: 'Details',
position: 'Position',
configSum: 'Group MD5',
mergedSum: 'MD5 agent.conf',
configSum: 'Group MD5 sum',
mergedSum: '"agent.conf" MD5 sum',
key: 'Key',
scan_id: 'Scan ID',
format: 'Format',
scan_time: 'Scan date'
scan_time: 'Scan date',
state: 'State',
mac: 'MAC',
gateway: 'Gateway',
dhcp: 'DHCP',
iface: 'Interface',
broadcast: 'Broadcast',
proto: 'Protocol',
address: 'Address',
protocol: 'Protocol',
'local.ip': 'Local',
'remote.ip': 'Remote'
}
},

}

return service
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<md-content layout="column">
<!-- Breadcrumbs -->
<div layout="row" layout-padding>
<div>
<a class="wz-text-link cursor-pointer" ui-sref='agents'>Agents</a>
<span> / </span>
<span ui-sref='agent-overview({id:aic.agent.id})' class="wz-text-link cursor-pointer">{{aic.agent.name}} ({{aic.agent.id}})</span>
<span> / </span>
<span>Inventory data</span>
</div>
<div ng-if="aic.agent.status">
<span class="wz-agent-status-indicator small" ng-class="aic.getAgentStatusClass(aic.agent.status)" aria-label="Agent status indicator">{{aic.formatAgentStatus(aic.agent.status)}}</span>
</div>
</div>

<div layout="row" layout-align="layout-padding" ng-if="!aic.syscollector">
<md-card flex class="wz-md-card" flex>
<md-card-content class="wz-text-center">
<i class="fa fa-fw fa-info-circle" aria-hidden="true"></i> <span class="wz-headline-title">Inventory disabled</span>
<md-divider class="wz-margin-top-10"></md-divider>
<div layout="column" class="wz-padding-top-10">
<p>Inventory (syscollector) is disabled for this agent. Visit the documentation on <a target="_blank" href="https://documentation.wazuh.com/current/user-manual/reference/ossec-conf/wodle-syscollector.html">this
link
</a> to learn about how to enable it.
</p>
</div>
</md-card-content>
</md-card>
</div>

<div layout="row" class="inventory-metrics" ng-if="aic.syscollector">
<md-card flex class="wz-metric-color wz-md-card">
<md-card-content layout="row" class="wz-padding-metric">
<div flex="10">Cores: <span class="wz-text-bold">{{ aic.syscollector.hardware.cpu.cores }}</span></div>
<div flex="15">Memory: <span class="wz-text-bold">{{ (aic.syscollector.hardware.ram.total / 1024) | number: 2 }}
MB
</span></div>
<div flex="10">Arch: <span class="wz-text-bold">{{ aic.syscollector.os.architecture }}</span></div>
<div flex>OS: <span class="wz-text-bold">{{ aic.syscollector.os.os.name }} {{ aic.syscollector.os.os.version }}</span></div>
<div flex>CPU: <span class="wz-text-bold">{{ aic.syscollector.hardware.cpu.name }}</span></div>
</md-card-content>
</md-card>
</div>

<div layout="row" class="layout-padding wz-padding-bottom-0" ng-if="aic.syscollector">
<md-card flex class="wz-md-card">
<md-card-content>
<span class="wz-headline-title"><i class="fa fa-fw fa-sitemap"></i> Network interfaces</span>
<span class="color-grey pull-right">Last scan: {{aic.syscollector.netiface.items[0].scan.time}}</span>
<md-divider class="wz-margin-top-10"></md-divider>

<table class="table table-striped table-condensed table-layout-fixed">
<thead class="wz-text-bold">
<th class="wz-text-left">Name</th>
<th class="wz-text-left">Mac</th>
<th class="wz-text-left">State</th>
<th class="wz-text-left">MTU</th>
<th class="wz-text-left">Type</th>
</thead>
<tbody>
<tr class="wz-word-wrap" ng-repeat="interface in aic.syscollector.netiface.items">
<td>{{interface.name}}</td>
<td>{{interface.mac}}</td>
<td>
<svg ng-if="interface.state !== 'up'" class="euiIcon euiIcon--medium euiIcon--warning" focusable="false" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16"><defs>
<circle id="dot-a" cx="8" cy="8" r="4"></circle>
</defs>
<use xlink:href="#dot-a"></use></svg>
<svg ng-if="interface.state === 'up'" class="euiIcon euiIcon--medium euiIcon--success" focusable="false" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16"><defs>
<circle id="dot-a" cx="8" cy="8" r="4"></circle>
</defs>
<use xlink:href="#dot-a"></use></svg>
{{interface.state}}
</td>
<td>{{interface.mtu}}</td>
<td>{{interface.type}}</td>
</tr>
</tbody>
</table>
</md-card-content>
</md-card>
<md-card flex class="wz-md-card">
<md-card-content class="wz-margin-bottom-40-inv">
<span class="wz-headline-title"><i class="fa fa-fw fa-exchange"></i> Network ports</span>
<span class="color-grey pull-right">Last scan: {{aic.syscollector.ports.items[0].scan.time}}</span>
<md-divider class="wz-margin-top-10"></md-divider>
<wazuh-table flex path="'/syscollector/' + aic.agent.id + '/ports'" row-sizes="[4]" keys="[{value:'local.ip',nosortable:true},{value:'remote.ip',nosortable:true},'state','protocol']">
</wazuh-table>
</md-card-content>
</md-card>
</div>

<div layout="row" class="layout-padding wz-padding-top-0" ng-if="aic.syscollector">
<md-card flex class="wz-md-card">
<md-card-content>
<span class="wz-headline-title"><i class="fa fa-fw fa-cubes"></i> Packages</span>
<span class="color-grey pull-right">Last scan: {{aic.syscollector.packagesDate}}</span>
<md-divider class="wz-margin-top-10"></md-divider>
<div layout="row" class="wz-margin-top-10">
<input flex placeholder="Filter packages..." ng-model="aic.packageSearch" type="text" class="kuiLocalSearchInput ng-empty ng-pristine ng-scope ng-touched ng-valid height-30"
aria-invalid="false" wz-enter="aic.search(aic.packageSearch,'packages')">
<button type="submit" aria-label="Search" class="kuiLocalSearchButton height-30" ng-click="aic.search(aic.packageSearch,'packages')">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</div>

<div layout="row" ng-if="aic.agent.id && aic.syscollector" class="wz-margin-top-10 wz-margin-bottom-40-inv">
<wazuh-table flex path="'/syscollector/' + aic.agent.id + '/packages'" row-sizes="[6,4,3,3]" extra-limit="true" keys="[{value:'name',size:2},'architecture','version',{value:'vendor',size:2},{value:'description',size:3}]">
</wazuh-table>
</div>
</md-card-content>
</md-card>
</div>
</md-content>
Loading

0 comments on commit 28d8120

Please sign in to comment.