Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Remove discover] Implement embeddable dashboard on Virustotal module #6525

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2c0bd7d
Migrated visualizations, added loadings and messages
jbiset Mar 15, 2024
068f85a
Merge branch '4.9.0' into 6511-remove_discover_implement_embeddable_d…
jbiset Mar 15, 2024
27c0866
Fixed warning for expected a single ReactElement
jbiset Mar 20, 2024
627324a
Merge branch '4.9.0' into 6511-remove_discover_implement_embeddable_d…
jbiset Apr 15, 2024
60e38f7
Added new virustotal data source. Changed NoResults and LoadingSpinne…
jbiset Apr 15, 2024
6b060cf
Fixed Events tab
jbiset Apr 17, 2024
8010132
Merge branch '4.9.0' into 6511-remove_discover_implement_embeddable_d…
jbiset Apr 17, 2024
bd2a3fe
Integrated pinned agent functionality based on data source
jbiset Apr 17, 2024
ddcc3f9
Added timeRange to dashboard useEffect dependencies and changed the w…
jbiset Apr 18, 2024
aced1de
Deleted unused component
jbiset Apr 19, 2024
e0899ca
Merge branch '4.9.0' into 6511-remove_discover_implement_embeddable_d…
jbiset Apr 22, 2024
e726750
Merge branch '4.9.0' into 6511-remove_discover_implement_embeddable_d…
jbiset Apr 23, 2024
8fa4bd0
Merge branch '4.9.0' into 6511-remove_discover_implement_embeddable_d…
jbiset Apr 24, 2024
cdec2ef
Changed AlertsVirustotalDataSource import in modules-defaults
jbiset Apr 24, 2024
3d724de
Fixed error message
jbiset Apr 24, 2024
03334ab
DashboardByRenderer timeRange params replaced by searchBarProps decon…
jbiset Apr 24, 2024
28a97e9
Added wz-discover hide-filter-control classes to hide the button that…
jbiset Apr 24, 2024
172c1a1
Removed unnecessary virus total in Filters tab in common data to remo…
jbiset Apr 24, 2024
05fe91d
Removed unused getImplicitPinnedAgent in modules-helper
jbiset Apr 24, 2024
8034905
Added dateRange param to fetchData in dashboard useEffect
jbiset Apr 24, 2024
c8e7073
Improved AlertsVirustotalDataSource import in modules-defaults and de…
jbiset Apr 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions plugins/main/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,8 @@ export const DATA_SOURCE_FILTER_CONTROLLED_PINNED_AGENT = 'pinned-agent';
export const DATA_SOURCE_FILTER_CONTROLLED_CLUSTER_MANAGER = 'cluster-manager';
export const DATA_SOURCE_FILTER_CONTROLLED_VULNERABILITIES_RULE_GROUP =
'vulnerabilities-rule-group';
export const DATA_SOURCE_FILTER_CONTROLLED_VIRUSTOTAL_RULE_GROUP =
'virustotal-rule-group';

// Wazuh links
export const WAZUH_LINK_GITHUB = 'https://github.com/wazuh';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { tFilter } from '../../../index';
import { DATA_SOURCE_FILTER_CONTROLLED_VIRUSTOTAL_RULE_GROUP } from '../../../../../../../common/constants';
import { AlertsDataSource } from '../alerts-data-source';

const VIRUSTOTAL_GROUP_KEY = 'rule.groups';
const VIRUSTOTAL_GROUP_VALUE = 'virustotal';

export class AlertsVirustotalDataSource extends AlertsDataSource {
constructor(id: string, title: string) {
super(id, title);
}

getRuleGroupsFilter() {
return super.getRuleGroupsFilter(
VIRUSTOTAL_GROUP_KEY,
VIRUSTOTAL_GROUP_VALUE,
DATA_SOURCE_FILTER_CONTROLLED_VIRUSTOTAL_RULE_GROUP,
);
}

getFixedFilters(): tFilter[] {
return [...this.getRuleGroupsFilter(), ...super.getFixedFilters()];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './alerts-virustotal-data-source';
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './alerts-vulnerabilities';
export * from './alerts-data-source-repository';
export * from './alerts-data-source';
export * from './alerts-data-source';
export * from './alerts-virustotal';
19 changes: 15 additions & 4 deletions plugins/main/public/components/common/modules/modules-defaults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from '../wazuh-discover/wz-discover';
import { threatHuntingColumns } from '../wazuh-discover/config/data-grid-columns';
import { vulnerabilitiesColumns } from '../../overview/vulnerabilities/events/vulnerabilities-columns';
import { DashboardVirustotal } from '../../overview/virustotal/dashboard/dashboard';
import React from 'react';
import { dockerColumns } from '../../overview/docker/events/docker-columns';
import { googleCloudColumns } from '../../overview/google-cloud/events/google-cloud-columns';
Expand All @@ -44,7 +45,10 @@ import { mitreAttackColumns } from '../../overview/mitre/events/mitre-attack-col
import { virustotalColumns } from '../../overview/virustotal/events/virustotal-columns';
import { malwareDetectionColumns } from '../../overview/malware-detection/events/malware-detection-columns';
import { WAZUH_VULNERABILITIES_PATTERN } from '../../../../common/constants';
import { AlertsVulnerabilitiesDataSource } from '../data-source';
import {
AlertsVulnerabilitiesDataSource,
AlertsVirustotalDataSource,
} from '../data-source';

const ALERTS_INDEX_PATTERN = 'wazuh-alerts-*';
const DEFAULT_INDEX_PATTERN = ALERTS_INDEX_PATTERN;
Expand Down Expand Up @@ -242,10 +246,17 @@ export const ModulesDefaults = {
availableFor: ['manager', 'agent'],
},
virustotal: {
init: 'dashboard',
tabs: [
DashboardTab,
renderDiscoverTab(DEFAULT_INDEX_PATTERN, virustotalColumns),
{
id: 'dashboard',
name: 'Dashboard',
buttons: [ButtonModuleExploreAgent, ButtonModuleGenerateReport],
component: DashboardVirustotal,
},
renderDiscoverTab({
tableColumns: virustotalColumns,
DataSource: AlertsVirustotalDataSource,
}),
],
availableFor: ['manager', 'agent'],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { getAngularModule, getDataPlugin } from '../../../kibana-services';
import { AppState } from '../../../react-services/app-state';
import { FilterHandler } from '../../../utils/filter-handler';
import { VULNERABILITY_IMPLICIT_CLUSTER_MODE_FILTER } from '../../../../common/constants';
import { useFilterManager } from '../hooks';
import { FilterStateStore } from '../../../../../../src/plugins/data/common';

export class ModulesHelper {
static async getDiscoverScope() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import React, { useState, useEffect } from 'react';
import { getPlugins } from '../../../../kibana-services';
import { ViewMode } from '../../../../../../../src/plugins/embeddable/public';
import { SearchResponse } from '../../../../../../../src/core/server';
import { IndexPattern } from '../../../../../../../src/plugins/data/common';
import { getDashboardPanels } from './dashboard_panels';
import { I18nProvider } from '@osd/i18n/react';
import useSearchBar from '../../../common/search-bar/use-search-bar';
import { getKPIsPanel } from './dashboard_panels_kpis';
import {
ErrorFactory,
ErrorHandler,
HttpError,
} from '../../../../react-services/error-management';
import { withErrorBoundary } from '../../../common/hocs/error-boundary/with-error-boundary';
import { SampleDataWarning } from '../../../visualize/components/sample-data-warning';
import {
AlertsDataSourceRepository,
PatternDataSource,
tParsedIndexPattern,
useDataSource,
} from '../../../common/data-source';
import { LoadingSpinner } from '../../../common/loading-spinner/loading-spinner';
import { DiscoverNoResults } from '../../../common/no-results/no-results';
import { AlertsVirustotalDataSource } from '../../../common/data-source/pattern/alerts/alerts-virustotal/alerts-virustotal-data-source';
import './virustotal_dashboard.scss';

const plugins = getPlugins();

const SearchBar = getPlugins().data.ui.SearchBar;

const DashboardByRenderer = plugins.dashboard.DashboardContainerByValueRenderer;
const DashboardVT: React.FC = () => {
const {
filters,
dataSource,
fetchFilters,
isLoading: isDataSourceLoading,
fetchData,
setFilters,
} = useDataSource<tParsedIndexPattern, PatternDataSource>({
DataSource: AlertsVirustotalDataSource,
repository: new AlertsDataSourceRepository(),
});

const [results, setResults] = useState<SearchResponse>({} as SearchResponse);

const { searchBarProps } = useSearchBar({
indexPattern: dataSource?.indexPattern as IndexPattern,
filters,
setFilters,
});
const { query, dateRangeFrom, dateRangeTo } = searchBarProps;

useEffect(() => {
if (isDataSourceLoading) {
return;
}
fetchData({
query,
dateRange: {
from: dateRangeFrom,
to: dateRangeTo,
},
})
.then(results => {
setResults(results);
})
.catch(error => {
const searchError = ErrorFactory.create(HttpError, {
error,
message: 'Error fetching alerts',
});
ErrorHandler.handleError(searchError);
});
}, [
isDataSourceLoading,
JSON.stringify(fetchFilters),
JSON.stringify(query),
dateRangeFrom,
dateRangeTo,
]);

return (
<I18nProvider>
<>
{isDataSourceLoading && !dataSource ? (
<LoadingSpinner />
) : (
<div className='wz-search-bar hide-filter-control'>
<SearchBar
appName='virustotal-searchbar'
{...searchBarProps}
showDatePicker={true}
showQueryInput={true}
showQueryBar={true}
showSaveQuery={true}
/>
</div>
)}
{!isDataSourceLoading && dataSource && results?.hits?.total > 0 ? (
<SampleDataWarning />
) : null}
{dataSource && results?.hits?.total === 0 ? (
<DiscoverNoResults />
) : null}
{!isDataSourceLoading && dataSource && results?.hits?.total > 0 ? (
<div className='virustotal-dashboard-responsive'>
<DashboardByRenderer
input={{
viewMode: ViewMode.VIEW,
panels: getKPIsPanel(dataSource?.id),
isFullScreenMode: false,
filters: fetchFilters ?? [],
useMargins: true,
id: 'kpis-virustotal-dashboard-tab',
timeRange: {
from: dateRangeFrom,
to: dateRangeTo,
},
title: 'KPIs Virustotal dashboard',
description: 'KPIs Dashboard of the Virustotal',
query: query,
refreshConfig: {
pause: false,
value: 15,
},
hidePanelTitles: true,
}}
/>
<DashboardByRenderer
input={{
viewMode: ViewMode.VIEW,
panels: getDashboardPanels(
dataSource?.id,
dataSource.getPinnedAgentFilter().length > 0,
),
isFullScreenMode: false,
filters: fetchFilters ?? [],
useMargins: true,
id: 'virustotal-dashboard-tab',
timeRange: {
from: dateRangeFrom,
to: dateRangeTo,
},
title: 'Virustotal dashboard',
description: 'Dashboard of the Virustotal',
query: query,
refreshConfig: {
pause: false,
value: 15,
},
hidePanelTitles: false,
}}
/>
</div>
) : null}
</>
</I18nProvider>
);
};

export const DashboardVirustotal = withErrorBoundary(DashboardVT);
Loading
Loading