Merge branch 'ui-fixes'

This commit is contained in:
Jesús González 2019-03-24 18:31:07 +01:00
commit 4dd0857364
7 changed files with 279 additions and 226 deletions

View File

@ -14,7 +14,6 @@ import { generateMetric } from '../../utils/generate-metric';
import { TabNames } from '../../utils/tab-names';
import * as FileSaver from '../../services/file-saver';
import { TabDescription } from '../../../server/reporting/tab-description';
import d3 from 'd3';
import {
metricsAudit,
metricsVulnerability,
@ -25,7 +24,7 @@ import {
import { ConfigurationHandler } from '../../utils/config-handler';
import { timefilter } from 'ui/timefilter';
import $ from 'jquery';
import { renderScaPie } from '../../utils/d3-chart';
export class AgentsController {
/**
@ -439,159 +438,6 @@ export class AgentsController {
}
}
renderScaPie(policies) {
try {
$(function () {
// code to run on document ready
console.log(policies);
/*
var dataset = [
{ name: 'IE', percent: 39.10 },
{ name: 'Chrome', percent: 32.51 },
{ name: 'Safari', percent: 13.68 },
{ name: 'Firefox', percent: 8.71 },
{ name: 'Others', percent: 6.01 }
];
*/
let pass = 0,
fail = 0;
policies.map(policy => {
pass += policy.pass;
fail += policy.fail;
});
var dataset = [
{ name: 'Pass', value: pass },
{ name: 'Fail', value: fail }
];
var pie = d3.layout
.pie()
.value(function(d) {
return d.value;
})
.sort(null)
.padAngle(0.03);
var w = 400,
h = 400;
var outerRadius = w / 2;
var innerRadius = 130;
var color = d3.scale.category10();
var arc = d3.svg
.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius);
var svg = d3
.select('#sca_chart')
.append('svg')
.attr({
width: w,
height: h,
class: 'shadow'
})
.append('g')
.attr({
transform: 'translate(' + w / 2 + ',' + h / 2 + ')'
});
var path = svg
.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr({
d: arc,
fill: function(d, i) {
return color(d.data.name);
}
});
path
.transition()
.duration(1000)
.attrTween('d', function(d) {
var interpolate = d3.interpolate({ startAngle: 0, endAngle: 0 }, d);
return function(t) {
return arc(interpolate(t));
};
});
var restOfTheData = function() {
var text = svg
.selectAll('text')
.data(pie(dataset))
.enter()
.append('text')
.transition()
.duration(200)
.attr('transform', function(d) {
return 'translate(' + arc.centroid(d) + ')';
})
.attr('dy', '.4em')
.attr('text-anchor', 'middle')
.text(function(d) {
return d.data.value + ' checks';
})
.style({
fill: '#fff',
'font-size': '10px'
});
var legendRectSize = 20;
var legendSpacing = 7;
var legendHeight = legendRectSize + legendSpacing;
var legend = svg
.selectAll('.legend')
.data(color.domain())
.enter()
.append('g')
.attr({
class: 'legend',
transform: function(d, i) {
//Just a calculation for x & y position
return 'translate(-35,' + (i * legendHeight - 65) + ')';
}
});
legend
.append('rect')
.attr({
width: legendRectSize,
height: legendRectSize,
rx: 20,
ry: 20
})
.style({
fill: color,
stroke: color
});
legend
.append('text')
.attr({
x: 30,
y: 15
})
.text(function(d) {
return d;
})
.style({
fill: '#929DAF',
'font-size': '14px'
});
};
restOfTheData();
});
} catch (error) {
console.log(error);
}
}
/**
* Classify metrics for create the suitable one
* @param {*} tab
@ -635,7 +481,13 @@ export class AgentsController {
const localChange =
subtab === 'panels' && this.$scope.tabView === 'discover' && sameTab;
this.$scope.tabView = subtab;
if (
subtab === 'panels' &&
this.$scope.tab === 'sca' &&
(this.$scope.policies || []).length
) {
this.renderScaCharts();
}
if (
(subtab === 'panels' ||
(this.targetLocation &&
@ -670,6 +522,34 @@ export class AgentsController {
}
}
renderScaCharts() {
try {
renderScaPie(
[
{
name: 'Pass',
value: this.$scope.policies.reduce((a, { pass }) => a + pass, 0)
},
{
name: 'Fail',
value: this.$scope.policies.reduce((a, { fail }) => a + fail, 0)
}
],
`sca_chart_pass_vs_fail`
);
for (const policy of this.$scope.policies) {
const dataset = [];
policy.pass && dataset.push({ name: 'Pass', value: policy.pass });
policy.fail && dataset.push({ name: 'Fail', value: policy.fail });
renderScaPie(dataset, `sca_chart_${policy.policy_id}`);
}
} catch (error) {
this.errorHandler.handle(error);
return;
}
}
/**
* Switch tab
* @param {*} tab
@ -720,8 +600,9 @@ export class AgentsController {
`/sca/${this.$scope.agent.id}`,
{}
);
this.renderScaPie(policies.data.data.items);
this.$scope.policies = policies.data.data.items;
this.$scope.policies =
(((policies || {}).data || {}).data || {}).items || [];
} catch (error) {
this.$scope.policies = [];
}
@ -741,7 +622,14 @@ export class AgentsController {
if (this.tabHistory.length > 2)
this.tabHistory = this.tabHistory.slice(-2);
this.tabVisualizations.setTab(tab);
if (this.$scope.tab === tab && !force) return;
if (this.$scope.tab === tab && !force) {
if (tab === 'sca') {
console.log('622: TRYING TO FORCE');
this.renderScaCharts();
this.$scope.$applyAsync();
}
return;
}
const onlyAgent = this.$scope.tab === tab && force;
const sameTab = this.$scope.tab === tab;
this.$location.search('tab', tab);

View File

@ -34,8 +34,8 @@ export class TabVisualizations {
this.overview = {
welcome: 0,
general: 11,
fim: 8,
general: 6,
fim: 6,
pm: 5,
vuls: 10,
oscap: 11,

View File

@ -87,12 +87,26 @@
<span flex><i class="fa fa-fw fa-warning"></i> No scans available.</span>
</div>
</div>
<div layout="row" class="md-padding" ng-show="!load && !lookingSca">
<div class="sca-chart-widget">
<div class="sca-chart-header">Pass vs Failed</div>
<div id="sca_chart" class="sca-chart"></div>
</div>
<div layout="row" class="md-padding layout-align-center" ng-if="!load && !lookingSca && policies.length">
<md-card class="wz-md-card">
<md-card-actions layout="row" class="wz-card-actions wz-card-actions-top"
style="padding-top:14px !important">
<span class="wz-headline-title">Total</span>
</md-card-actions>
<md-card-content>
<div id="sca_chart_pass_vs_fail" class="sca-chart"></div>
</md-card-content>
</md-card>
<md-card class="wz-md-card" ng-repeat="policy in policies">
<md-card-actions layout="row" class="wz-card-actions wz-card-actions-top"
style="padding-top:14px !important">
<span class="wz-headline-title">{{policy.name}}</span>
</md-card-actions>
<md-card-content>
<div id="sca_chart_{{policy.policy_id}}" class="sca-chart"></div>
</md-card-content>
</md-card>
</div>
<div layout="row" class="wz-padding-top-0" ng-if="agent && agent.os && lookingSca">
@ -119,7 +133,8 @@
</div>
<div layout="row" class="wz-margin-top-16 wz-margin-bottom-40-inv">
<wz-table custom-columns="true" flex path="'/sca/' + agent.id + '/checks/' + lookingSca.id"
row-sizes="[13,11,9]" extra-limit="100" keys="[{value: 'id', width: '75px'},'title', 'file', 'result']">
row-sizes="[13,11,9]" extra-limit="100"
keys="[{value: 'id', width: '75px'},'title', 'file', 'result']">
</wz-table>
</div>
</md-card-content>

View File

@ -222,6 +222,6 @@
<!-- No results section -->
<!-- Loading ring -->
<div class='uil-ring-css' ng-show="load && tab !== 'configuration' && tabView === 'panels'">
<div class='uil-ring-css' ng-show="load && tab !== 'configuration' && tab !== 'sca' && tabView === 'panels'">
<div></div>
</div>

View File

@ -1,13 +1,6 @@
<div class="" layout="column" layout-align="start stretch" ng-if="mctrl.tab === 'welcome'">
<!-- Headline -->
<div layout="column" layout-padding>
<span class="font-size-18"><i class="fa fa-fw fa-server" aria-hidden="true"></i> Management</span>
</div>
<!-- End headline -->
<!-- Wazuh management card -->
<div layout="row" layout-padding>
<div class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--responsive">
<div class="euiFlexItem">
@ -15,13 +8,16 @@
<h3 class="euiTitle wzEuiTitle">Administration</h3>
<div class="euiSpacer euiSpacer--m"></div>
<div class="euiFlexGrid euiFlexGrid--gutterLarge euiFlexGrid--halves">
<wz-welcome-card class="euiFlexItem" logo="'icons/ruleset.png'" card-title="'Ruleset'" switch-tab="mctrl.switchTab('ruleset', true)"
current-tab="'rules'" description="'Manage your Wazuh cluster ruleset.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/groups.png'" card-title="'Groups'" switch-tab="mctrl.switchTab('groups', true)"
current-tab="'groups'" description="'Manage your agent groups.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/app_devtools.svg'" card-title="'Configuration'"
switch-tab="mctrl.switchTab('configuration', true)" current-tab="'configuration'"
description="'Manage your Wazuh cluster configuration.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/ruleset.png'" card-title="'Ruleset'"
switch-tab="mctrl.switchTab('ruleset', true)" current-tab="'rules'"
description="'Manage your Wazuh cluster ruleset.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/groups.png'" card-title="'Groups'"
switch-tab="mctrl.switchTab('groups', true)" current-tab="'groups'"
description="'Manage your agent groups.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/app_devtools.svg'"
card-title="'Configuration'" switch-tab="mctrl.switchTab('configuration', true)"
current-tab="'configuration'" description="'Manage your Wazuh cluster configuration.'">
</wz-welcome-card>
</div>
</div>
</div>
@ -31,13 +27,17 @@
<div class="euiSpacer euiSpacer--m"></div>
<div class="euiFlexGrid euiFlexGrid--gutterLarge euiFlexGrid--halves">
<wz-welcome-card class="euiFlexItem" logo="'icons/app_monitoring.svg'" card-title="'Status'"
switch-tab="mctrl.switchTab('status', true)" current-tab="'status'" description="'Check your Wazuh cluster status.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/app_logging.svg'" card-title="'Logs'" switch-tab="mctrl.switchTab('logs', true)"
current-tab="'logs'" description="'Logs from your Wazuh cluster.'"></wz-welcome-card>
switch-tab="mctrl.switchTab('status', true)" current-tab="'status'"
description="'Check your Wazuh cluster status.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/app_logging.svg'" card-title="'Logs'"
switch-tab="mctrl.switchTab('logs', true)" current-tab="'logs'"
description="'Logs from your Wazuh cluster.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/app_index_pattern.svg'" card-title="'Cluster'"
switch-tab="mctrl.switchTab('monitoring', true)" current-tab="'monitoring'" description="'Visualize your Wazuh cluster.'"></wz-welcome-card>
switch-tab="mctrl.switchTab('monitoring', true)" current-tab="'monitoring'"
description="'Visualize your Wazuh cluster.'"></wz-welcome-card>
<wz-welcome-card class="euiFlexItem" logo="'icons/reporting.png'" card-title="'Reporting'"
switch-tab="mctrl.switchTab('reporting', true)" current-tab="'reporting'" description="'Check your stored Wazuh reports.'"></wz-welcome-card>
switch-tab="mctrl.switchTab('reporting', true)" current-tab="'reporting'"
description="'Check your stored Wazuh reports.'"></wz-welcome-card>
</div>
</div>
</div>

View File

@ -24,25 +24,25 @@
<div layout="row" layout-align="start stretch" class="height-400">
<md-card flex class="wz-md-card" ng-class="{'fullscreen': octrl.expandArray[0]}">
<md-card-actions layout="row" class="wz-card-actions wz-card-actions-top"
style="padding-top:14px !important">
<span class="wz-headline-title">Top 10 agents by alerts number</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(0)"><i class="fa fa-fw fa-expand"></i></span>
</md-card-actions>
<md-card-content class="wazuh-column">
<div layout="row" ng-dblclick="octrl.expand(0)">
<span class="wz-headline-title">Top 10 agents by alerts number</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(0)"><i class="fa fa-fw fa-expand"></i></span>
</div>
<md-divider class="wz-margin-top-10"></md-divider>
<kbn-vis id="Wazuh-App-Overview-General-Top-10-agent-alert"
vis-id="'Wazuh-App-Overview-General-Top-10-agent-alert'"></kbn-vis>
</md-card-content>
</md-card>
<md-card flex class="wz-md-card" ng-class="{'fullscreen': octrl.expandArray[1]}">
<md-card-actions layout="row" class="wz-card-actions wz-card-actions-top"
style="padding-top:14px !important">
<span class="wz-headline-title">Alert level evolution</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(1)"><i class="fa fa-fw fa-expand"></i></span>
</md-card-actions>
<md-card-content class="wazuh-column">
<div layout="row" ng-dblclick="octrl.expand(1)">
<span class="wz-headline-title">Alert level evolution</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(1)"><i class="fa fa-fw fa-expand"></i></span>
</div>
<md-divider class="wz-margin-top-10"></md-divider>
<kbn-vis id="Wazuh-App-Overview-General-Alert-level-evolution"
vis-id="'Wazuh-App-Overview-General-Alert-level-evolution'"></kbn-vis>
</md-card-content>
@ -51,43 +51,41 @@
<div layout="row" layout-align="space-between stretch" class="height-360">
<md-card flex class="wz-md-card" ng-class="{'fullscreen': octrl.expandArray[2]}">
<md-card-actions layout="row" class="wz-card-actions wz-card-actions-top"
style="padding-top:14px !important">
<span class="wz-headline-title">Top 5 agents</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(2)"><i class="fa fa-fw fa-expand"></i></span>
</md-card-actions>
<md-card-content class="wazuh-column">
<div layout="row" ng-dblclick="octrl.expand(2)">
<span class="wz-headline-title">Top 5 agents</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(2)"><i class="fa fa-fw fa-expand"></i></span>
</div>
<md-divider class="wz-margin-top-10"></md-divider>
<kbn-vis id="Wazuh-App-Overview-General-Top-5-agents"
vis-id="'Wazuh-App-Overview-General-Top-5-agents'"></kbn-vis>
</md-card-content>
</md-card>
<md-card flex class="wz-md-card" ng-class="{'fullscreen': octrl.expandArray[3]}">
<md-card-actions layout="row" class="wz-card-actions wz-card-actions-top"
style="padding-top:14px !important">
<span class="wz-headline-title">Top 10 rule groups</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(3)"><i class="fa fa-fw fa-expand"></i></span>
</md-card-actions>
<md-card-content class="wazuh-column">
<div layout="row" ng-dblclick="octrl.expand(3)">
<span class="wz-headline-title">Top 10 rule groups</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(3)"><i class="fa fa-fw fa-expand"></i></span>
</div>
<md-divider class="wz-margin-top-10"></md-divider>
<kbn-vis id="Wazuh-App-Overview-General-Top-10-rule-groups"
vis-id="'Wazuh-App-Overview-General-Top-10-rule-groups'"></kbn-vis>
</md-card-content>
</md-card>
<md-card flex="40" class="wz-md-card" ng-class="{'fullscreen': octrl.expandArray[4]}">
<md-card-actions layout="row" class="wz-card-actions wz-card-actions-top"
style="padding-top:14px !important">
<span class="wz-headline-title">Agents status</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(4)"><i class="fa fa-fw fa-expand"></i></span>
</md-card-actions>
<md-card-content class="wazuh-column" ng-show="octrl.wzMonitoringEnabled">
<div layout="row" ng-dblclick="octrl.expand(4)">
<span class="wz-headline-title">Agents status</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(4)"><i class="fa fa-fw fa-expand"></i></span>
</div>
<md-divider class="wz-margin-top-10"></md-divider>
<kbn-vis id="Wazuh-App-Overview-General-Agents-status"
vis-id="'Wazuh-App-Overview-General-Agents-status'"></kbn-vis>
</md-card-content>
<md-card-content class="wazuh-column" ng-show="!octrl.wzMonitoringEnabled">
<span class="wz-headline-title">Agents status</span>
<md-divider class="wz-margin-top-10"></md-divider>
<div layout="row">
<div flex layout="column">
<div layout="row" class="wz-padding-top-10"></div>
@ -120,13 +118,13 @@
<div layout="row" layout-align="center stretch" class="height-300">
<md-card flex class="wz-md-card" ng-class="{'fullscreen': octrl.expandArray[5]}">
<md-card-actions layout="row" class="wz-card-actions wz-card-actions-top"
style="padding-top:14px !important">
<span class="wz-headline-title">Commonly fired rules</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(5)"><i class="fa fa-fw fa-expand"></i></span>
</md-card-actions>
<md-card-content class="wazuh-column">
<div layout="row" ng-dblclick="octrl.expand(5)">
<span class="wz-headline-title">Commonly fired rules</span>
<span flex></span>
<span class="wz-text-link" ng-click="octrl.expand(5)"><i class="fa fa-fw fa-expand"></i></span>
</div>
<md-divider class="wz-margin-top-10"></md-divider>
<kbn-vis vis-id="'Wazuh-App-Overview-General-Commonly-fired-rules'"></kbn-vis>
</md-card-content>
</md-card>

152
public/utils/d3-chart.js vendored Normal file
View File

@ -0,0 +1,152 @@
/*
* Wazuh app - Agents controller
* 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 d3 from 'd3';
import $ from 'jquery';
const render = (dataset, element) => {
try {
var pie = d3.layout
.pie()
.value(function(d) {
return d.value;
})
.sort(null)
.padAngle(0.03);
var w = 250,
h = 250;
var outerRadius = w / 2;
var innerRadius = 85;
var color = d3.scale.category10();
var arc = d3.svg
.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius);
var svg = d3
.select(`#${element}`)
.append('svg')
.attr('width', '100%')
.attr('height', '100%')
.attr('viewBox', -w / 2 + ' ' + -h / 2 + ' ' + w + ' ' + h)
.attr('preserveAspectRatio', 'xMinYMin')
.append('g');
var path = svg
.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr({
d: arc,
fill: function(d, i) {
return color(d.data.name);
}
});
path
.transition()
.duration(1000)
.attrTween('d', function(d) {
var interpolate = d3.interpolate({ startAngle: 0, endAngle: 0 }, d);
return function(t) {
return arc(interpolate(t));
};
});
var restOfTheData = function() {
var text = svg
.selectAll('text')
.data(pie(dataset))
.enter()
.append('text')
.transition()
.duration(200)
.attr('transform', function(d) {
return 'translate(' + arc.centroid(d) + ')';
})
.attr('dy', '.4em')
.attr('text-anchor', 'middle')
.text(function(d) {
return d.data.value;
})
.style({
fill: '#fff',
'font-size': '10px'
});
var legendRectSize = 20;
var legendSpacing = 7;
var legendHeight = legendRectSize + legendSpacing;
var legend = svg
.selectAll('.legend')
.data(color.domain())
.enter()
.append('g')
.attr({
class: 'legend',
transform: function(d, i) {
//Just a calculation for x & y position
return 'translate(-35,' + (i * legendHeight - 20) + ')';
}
});
legend
.append('rect')
.attr({
width: legendRectSize,
height: legendRectSize,
rx: 20,
ry: 20
})
.style({
fill: color,
stroke: color
});
legend
.append('text')
.attr({
x: 30,
y: 15
})
.text(function(d) {
return d;
})
.style({
fill: '#929DAF',
'font-size': '14px'
});
};
restOfTheData();
} catch (error) {
console.log(error);
}
};
const renderScaPie = (dataset, element) => {
const checkExist = setInterval(function() {
if ($(`#${element}`).length) {
console.log(`#${element} is ready!`);
clearInterval(checkExist);
return render(dataset, element);
}
}, 100);
};
export default {
renderScaPie
};