Initial commit

This commit is contained in:
Eugene Bujak
2018-08-30 17:25:33 +03:00
commit ed4077a969
91 changed files with 48004 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
import React from 'react';
import ReactTable from 'react-table';
import PropTypes from 'prop-types';
import map from 'lodash/map';
import Card from '../ui/Card';
const Clients = props => (
<Card title="Top blocked domains" subtitle="in the last 3 minutes" bodyType="card-table" refresh={props.refreshButton}>
<ReactTable
data={map(props.topBlockedDomains, (value, prop) => (
{ ip: prop, domain: value }
))}
columns={[{
Header: 'IP',
accessor: 'ip',
}, {
Header: 'Domain name',
accessor: 'domain',
}]}
showPagination={false}
noDataText="No domains found"
minRows={6}
className="-striped -highlight card-table-overflow"
/>
</Card>
);
Clients.propTypes = {
topBlockedDomains: PropTypes.object.isRequired,
refreshButton: PropTypes.node,
};
export default Clients;

View File

@@ -0,0 +1,34 @@
import React from 'react';
import ReactTable from 'react-table';
import PropTypes from 'prop-types';
import map from 'lodash/map';
import Card from '../ui/Card';
const Clients = props => (
<Card title="Top clients" subtitle="in the last 3 minutes" bodyType="card-table" refresh={props.refreshButton}>
<ReactTable
data={map(props.topClients, (value, prop) => (
{ ip: prop, count: value }
))}
columns={[{
Header: 'IP',
accessor: 'ip',
}, {
Header: 'Request count',
accessor: 'count',
}]}
showPagination={false}
noDataText="No clients found"
minRows={6}
className="-striped -highlight card-table-overflow"
/>
</Card>
);
Clients.propTypes = {
topClients: PropTypes.object.isRequired,
refreshButton: PropTypes.node,
};
export default Clients;

View File

@@ -0,0 +1,92 @@
import React from 'react';
import PropTypes from 'prop-types';
import Card from '../ui/Card';
import Tooltip from '../ui/Tooltip';
const Counters = props => (
<Card title="General counters" subtitle="in the last 3 minutes" bodyType="card-table" refresh={props.refreshButton}>
<table className="table card-table">
<tbody>
<tr>
<td>
DNS Queries
<Tooltip text="A number of DNS quieries processed in the last 3 minutes" />
</td>
<td className="text-right">
<span className="text-muted">
{props.dnsQueries}
</span>
</td>
</tr>
<tr>
<td>
Blocked by filters
<Tooltip text="A number of DNS requests blocked by filters" />
</td>
<td className="text-right">
<span className="text-muted">
{props.blockedFiltering}
</span>
</td>
</tr>
<tr>
<td>
Blocked malware/phishing
<Tooltip text="A number of DNS requests blocked" />
</td>
<td className="text-right">
<span className="text-muted">
{props.replacedSafebrowsing}
</span>
</td>
</tr>
<tr>
<td>
Blocked adult websites
<Tooltip text="A number of adult websites blocked" />
</td>
<td className="text-right">
<span className="text-muted">
{props.replacedParental}
</span>
</td>
</tr>
<tr>
<td>
Enforced safe search
<Tooltip text="A number of DNS requests to search engines for which Safe Search was enforced" />
</td>
<td className="text-right">
<span className="text-muted">
{props.replacedSafesearch}
</span>
</td>
</tr>
<tr>
<td>
Average processing time
<Tooltip text="Average time in milliseconds on processing a DNS request" />
</td>
<td className="text-right">
<span className="text-muted">
{props.avgProcessingTime}
</span>
</td>
</tr>
</tbody>
</table>
</Card>
);
Counters.propTypes = {
dnsQueries: PropTypes.number.isRequired,
blockedFiltering: PropTypes.number.isRequired,
replacedSafebrowsing: PropTypes.number.isRequired,
replacedParental: PropTypes.number.isRequired,
replacedSafesearch: PropTypes.number.isRequired,
avgProcessingTime: PropTypes.number.isRequired,
refreshButton: PropTypes.node,
};
export default Counters;

View File

@@ -0,0 +1,34 @@
import React from 'react';
import ReactTable from 'react-table';
import PropTypes from 'prop-types';
import map from 'lodash/map';
import Card from '../ui/Card';
const QueriedDomains = props => (
<Card title="Top queried domains" subtitle="in the last 3 minutes" bodyType="card-table" refresh={props.refreshButton}>
<ReactTable
data={map(props.topQueriedDomains, (value, prop) => (
{ ip: prop, count: value }
))}
columns={[{
Header: 'IP',
accessor: 'ip',
}, {
Header: 'Request count',
accessor: 'count',
}]}
showPagination={false}
noDataText="No domains found"
minRows={6}
className="-striped -highlight card-table-overflow"
/>
</Card>
);
QueriedDomains.propTypes = {
topQueriedDomains: PropTypes.object.isRequired,
refreshButton: PropTypes.node,
};
export default QueriedDomains;

View File

@@ -0,0 +1,61 @@
import React from 'react';
import { ResponsiveLine } from '@nivo/line';
import PropTypes from 'prop-types';
import Card from '../ui/Card';
const Statistics = props => (
<Card title="Statistics" subtitle="Today" bodyType="card-graph" refresh={props.refreshButton}>
{props.history ?
<ResponsiveLine
data={props.history}
margin={{
top: 50,
right: 40,
bottom: 80,
left: 80,
}}
minY="auto"
stacked={false}
curve='monotoneX'
axisBottom={{
orient: 'bottom',
tickSize: 5,
tickPadding: 5,
tickRotation: -45,
legend: 'time',
legendOffset: 50,
legendPosition: 'center',
}}
axisLeft={{
orient: 'left',
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: 'count',
legendOffset: -40,
legendPosition: 'center',
}}
enableArea={true}
dotSize={10}
dotColor="inherit:darker(0.3)"
dotBorderWidth={2}
dotBorderColor="#ffffff"
dotLabel="y"
dotLabelYOffset={-12}
animate={true}
motionStiffness={90}
motionDamping={15}
/>
:
<h2 className="text-muted">Empty data</h2>
}
</Card>
);
Statistics.propTypes = {
history: PropTypes.array.isRequired,
refreshButton: PropTypes.node,
};
export default Statistics;

View File

@@ -0,0 +1,103 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import 'whatwg-fetch';
import Statistics from './Statistics';
import Counters from './Counters';
import Clients from './Clients';
import QueriedDomains from './QueriedDomains';
import BlockedDomains from './BlockedDomains';
import PageTitle from '../ui/PageTitle';
import Loading from '../ui/Loading';
class Dashboard extends Component {
componentDidMount() {
this.props.getStats();
this.props.getStatsHistory();
this.props.getTopStats();
}
render() {
const { dashboard } = this.props;
const dashboardProcessing =
dashboard.processing ||
dashboard.processingStats ||
dashboard.processingStatsHistory ||
dashboard.processingTopStats;
const disableButton = <button type="button" className="btn btn-outline-secondary btn-sm mr-2" onClick={() => this.props.disableDns()}>Disable DNS</button>;
const refreshFullButton = <button type="button" className="btn btn-outline-primary btn-sm" onClick={() => this.props.getStats()}>Refresh statistics</button>;
const refreshButton = <button type="button" className="btn btn-outline-primary btn-sm card-refresh" onClick={() => this.props.getStats()}></button>;
return (
<Fragment>
<PageTitle title="Dashboard">
<div className="page-title__actions">
{disableButton}
{refreshFullButton}
</div>
</PageTitle>
{dashboardProcessing && <Loading />}
{!dashboardProcessing &&
<div className="row row-cards">
{dashboard.statsHistory &&
<div className="col-lg-12">
<Statistics
history={dashboard.statsHistory}
refreshButton={refreshButton}
/>
</div>
}
<div className="col-lg-6">
{dashboard.stats &&
<Counters
refreshButton={refreshButton}
dnsQueries={dashboard.stats.dns_queries}
blockedFiltering={dashboard.stats.blocked_filtering}
replacedSafebrowsing={dashboard.stats.replaced_safebrowsing}
replacedParental={dashboard.stats.replaced_parental}
replacedSafesearch={dashboard.stats.replaced_safesearch}
avgProcessingTime={dashboard.stats.avg_processing_time}
/>
}
</div>
{dashboard.topStats &&
<Fragment>
<div className="col-lg-6">
<Clients
refreshButton={refreshButton}
topClients={dashboard.topStats.top_clients}
/>
</div>
<div className="col-lg-6">
<QueriedDomains
refreshButton={refreshButton}
topQueriedDomains={dashboard.topStats.top_queried_domains}
/>
</div>
<div className="col-lg-6">
<BlockedDomains
refreshButton={refreshButton}
topBlockedDomains={dashboard.topStats.top_blocked_domains}
/>
</div>
</Fragment>
}
</div>
}
</Fragment>
);
}
}
Dashboard.propTypes = {
getStats: PropTypes.func,
getStatsHistory: PropTypes.func,
getTopStats: PropTypes.func,
disableDns: PropTypes.func,
dashboard: PropTypes.object,
isCoreRunning: PropTypes.bool,
};
export default Dashboard;