Skip to content

Commit

Permalink
Replace discover Vulnerability (#6275)
Browse files Browse the repository at this point in the history
* Replace discover

* Add explore agent

* Add changelog

* Fix events view with agent

* Fix changelog.md

---------

Co-authored-by: Federico Rodriguez <[email protected]>
  • Loading branch information
yenienserrano and asteriscos authored Jan 10, 2024
1 parent 5382600 commit c42fce2
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 72 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ All notable changes to the Wazuh app project will be documented in this file.

### Changed

- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287)
- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287)
- Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227)
- Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250)

Expand Down
13 changes: 11 additions & 2 deletions plugins/main/public/components/common/modules/modules-defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ import { OfficePanel } from '../../overview/office-panel';
import { GitHubPanel } from '../../overview/github-panel';
import { DashboardVuls, InventoryVuls } from '../../overview/vulnerabilities';
import { withModuleNotForAgent } from '../hocs';
import WazuhDiscover from '../wazuh-discover/wz-discover';
import { WazuhDiscover } from '../wazuh-discover/wz-discover';
import { threatHuntingColumns } from '../wazuh-discover/config/data-grid-columns';
import { vulnerabilitiesColumns } from '../../overview/vulnerabilities/events/vulnerabilities-columns';
import { DashboardFim } from '../../overview/fim/dashboard/dashboard';
import { InventoryFim } from '../../overview/fim/inventory/inventory';
import React from 'react';
Expand Down Expand Up @@ -186,7 +187,15 @@ export const ModulesDefaults = {
name: 'Inventory',
component: withModuleNotForAgent(InventoryVuls),
},
EventsTab,
{
...renderDiscoverTab(ALERTS_INDEX_PATTERN, vulnerabilitiesColumns),
component: withModuleNotForAgent(() => (
<WazuhDiscover
indexPatternName={DEFAULT_INDEX_PATTERN}
tableColumns={vulnerabilitiesColumns}
/>
)),
},
],
buttons: ['settings'],
availableFor: ['manager'],
Expand Down
195 changes: 126 additions & 69 deletions plugins/main/public/components/common/wazuh-discover/wz-discover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,48 +16,63 @@ import {
EuiPanel,
} from '@elastic/eui';
import { IntlProvider } from 'react-intl';
import { Filter, IndexPattern } from '../../../../../../src/plugins/data/common';
import {
Filter,
IndexPattern,
} from '../../../../../../src/plugins/data/common';
import { SearchResponse } from '../../../../../../src/core/server';
import { useDocViewer } from '../doc-viewer';
import DocViewer from '../doc-viewer/doc-viewer';
import { DiscoverNoResults } from '../../overview/vulnerabilities/common/components/no_results';
import { LoadingSpinner } from '../../overview/vulnerabilities/common/components/loading_spinner';
import { useDataGrid, tDataGridColumn, exportSearchToCSV } from '../data-grid';
import { ErrorHandler, ErrorFactory, HttpError } from '../../../react-services/error-management';
import {
ErrorHandler,
ErrorFactory,
HttpError,
} from '../../../react-services/error-management';
import { HitsCounter } from '../../../kibana-integrations/discover/application/components/hits_counter';
import { formatNumWithCommas } from '../../../kibana-integrations/discover/application/helpers';
import useSearchBar from '../search-bar/use-search-bar';
import { search } from '../search-bar';
import { getPlugins } from '../../../kibana-services';
import { histogramChartInput } from './config/histogram-chart';
import { useDockedSideNav } from '../hooks/useDockedSideNav'
const DashboardByRenderer = getPlugins().dashboard.DashboardContainerByValueRenderer;
import { useDockedSideNav } from '../hooks/useDockedSideNav';
const DashboardByRenderer =
getPlugins().dashboard.DashboardContainerByValueRenderer;
import './discover.scss';
import { withErrorBoundary } from '../hocs';

export const MAX_ENTRIES_PER_QUERY = 10000;

type WazuhDiscoverProps = {
indexPatternName: string;
tableColumns: tDataGridColumn[];
}
};

const WazuhDiscover = (props: WazuhDiscoverProps) => {
const { indexPatternName, tableColumns: defaultTableColumns } = props
const [sidebarDocked, setSidebarDocked] = useState<boolean>(false);
const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => {
const { indexPatternName, tableColumns: defaultTableColumns } = props;
const SearchBar = getPlugins().data.ui.SearchBar;
const [results, setResults] = useState<SearchResponse>({} as SearchResponse);
const [inspectedHit, setInspectedHit] = useState<any>(undefined);
const [indexPattern, setIndexPattern] = useState<IndexPattern | undefined>(undefined);
const [indexPattern, setIndexPattern] = useState<IndexPattern | undefined>(
undefined,
);
const [isSearching, setIsSearching] = useState<boolean>(false);
const [isExporting, setIsExporting] = useState<boolean>(false);
const sideNavDocked = useDockedSideNav();

const onClickInspectDoc = useMemo(() => (index: number) => {
const rowClicked = results.hits.hits[index];
setInspectedHit(rowClicked);
}, [results]);
const onClickInspectDoc = useMemo(
() => (index: number) => {
const rowClicked = results.hits.hits[index];
setInspectedHit(rowClicked);
},
[results],
);

const DocViewInspectButton = ({ rowIndex }: EuiDataGridCellValueElementProps) => {
const DocViewInspectButton = ({
rowIndex,
}: EuiDataGridCellValueElementProps) => {
const inspectHintMsg = 'Inspect document details';
return (
<EuiToolTip content={inspectHintMsg}>
Expand All @@ -72,8 +87,15 @@ const WazuhDiscover = (props: WazuhDiscoverProps) => {

const { searchBarProps } = useSearchBar({
defaultIndexPatternID: indexPatternName,
})
const { isLoading, filters, query, indexPatterns, dateRangeFrom, dateRangeTo } = searchBarProps;
});
const {
isLoading,
filters,
query,
indexPatterns,
dateRangeFrom,
dateRangeTo,
} = searchBarProps;

const dataGridProps = useDataGrid({
ariaLabelledBy: 'Discover events table',
Expand All @@ -85,15 +107,15 @@ const WazuhDiscover = (props: WazuhDiscoverProps) => {
pageIndex: 0,
pageSize: 15,
pageSizeOptions: [15, 25, 50, 100],
}
})
},
});

const { pagination, sorting, columnVisibility } = dataGridProps;

const docViewerProps = useDocViewer({
doc: inspectedHit,
indexPattern: indexPattern as IndexPattern,
})
});

useEffect(() => {
if (!isLoading) {
Expand All @@ -108,22 +130,30 @@ const WazuhDiscover = (props: WazuhDiscoverProps) => {
dateRange: {
from: dateRangeFrom,
to: dateRangeTo,
}
}).then((results) => {
setResults(results);
setIsSearching(false);
}).catch((error) => {
const searchError = ErrorFactory.create(HttpError, { error, message: 'Error fetching data' })
ErrorHandler.handleError(searchError);
setIsSearching(false);
},
})
.then(results => {
setResults(results);
setIsSearching(false);
})
.catch(error => {
const searchError = ErrorFactory.create(HttpError, {
error,
message: 'Error fetching data',
});
ErrorHandler.handleError(searchError);
setIsSearching(false);
});
}
},
[JSON.stringify(searchBarProps),
}, [
JSON.stringify(searchBarProps),
JSON.stringify(pagination),
JSON.stringify(sorting)]);
JSON.stringify(sorting),
]);

const timeField = indexPattern?.timeFieldName ? indexPattern.timeFieldName : undefined;
const timeField = indexPattern?.timeFieldName
? indexPattern.timeFieldName
: undefined;

const onClickExportResults = async () => {
const params = {
Expand All @@ -133,52 +163,69 @@ const WazuhDiscover = (props: WazuhDiscoverProps) => {
fields: columnVisibility.visibleColumns,
pagination: {
pageIndex: 0,
pageSize: results.hits.total
pageSize: results.hits.total,
},
sorting
}
sorting,
};
try {
setIsExporting(true);
await exportSearchToCSV(params);
} catch (error) {
const searchError = ErrorFactory.create(HttpError, { error, message: 'Error downloading csv report' })
const searchError = ErrorFactory.create(HttpError, {
error,
message: 'Error downloading csv report',
});
ErrorHandler.handleError(searchError);
} finally {
setIsExporting(false);
}
}
};

return (
<IntlProvider locale="en">
<IntlProvider locale='en'>
<EuiPageTemplate
className="discoverContainer"
restrictWidth="100%"
className='discoverContainer'
restrictWidth='100%'
fullHeight={true}
grow
>
<>
{isLoading ?
<LoadingSpinner /> :
{isLoading ? (
<LoadingSpinner />
) : (
<SearchBar
appName='wazuh-discover-search-bar'
{...searchBarProps}
showSaveQuery={true}
/>}
{!isLoading && results?.hits?.total === 0 ?
<DiscoverNoResults timeFieldName={timeField} queryLanguage={''} /> : null}
/>
)}
{!isLoading && results?.hits?.total === 0 ? (
<DiscoverNoResults timeFieldName={timeField} queryLanguage={''} />
) : null}
{!isLoading && results?.hits?.total > 0 ? (
<>
<EuiFlexItem grow={false} className="discoverChartContainer">
<EuiPanel hasBorder={false} hasShadow={false} color="transparent" paddingSize="none">
<EuiFlexItem grow={false} className='discoverChartContainer'>
<EuiPanel
hasBorder={false}
hasShadow={false}
color='transparent'
paddingSize='none'
>
<EuiPanel>
<DashboardByRenderer
input={histogramChartInput(indexPatternName, filters, query, dateRangeFrom, dateRangeTo)}
input={histogramChartInput(
indexPatternName,
filters,
query,
dateRangeFrom,
dateRangeTo,
)}
/>
</EuiPanel>
</EuiPanel>
</EuiFlexItem>
<EuiSpacer size="m" />
<div className="discoverDataGrid">
<EuiSpacer size='m' />
<div className='discoverDataGrid'>
<EuiDataGrid
{...dataGridProps}
className={sideNavDocked ? 'dataGridDockedNav' : ''}
Expand All @@ -188,52 +235,62 @@ const WazuhDiscover = (props: WazuhDiscoverProps) => {
<HitsCounter
hits={results?.hits?.total}
showResetButton={false}
onResetQuery={() => { }}
tooltip={results?.hits?.total && results?.hits?.total > MAX_ENTRIES_PER_QUERY ? {
ariaLabel: 'Warning',
content: `The query results has exceeded the limit of 10,000 hits. To provide a better experience the table only shows the first ${formatNumWithCommas(MAX_ENTRIES_PER_QUERY)} hits.`,
iconType: 'alert',
position: 'top'
} : undefined}
onResetQuery={() => {}}
tooltip={
results?.hits?.total &&
results?.hits?.total > MAX_ENTRIES_PER_QUERY
? {
ariaLabel: 'Warning',
content: `The query results has exceeded the limit of 10,000 hits. To provide a better experience the table only shows the first ${formatNumWithCommas(
MAX_ENTRIES_PER_QUERY,
)} hits.`,
iconType: 'alert',
position: 'top',
}
: undefined
}
/>
<EuiButtonEmpty
disabled={results?.hits?.total === 0 || columnVisibility.visibleColumns.length === 0}
size="xs"
iconType="exportAction"
color="primary"
disabled={
results?.hits?.total === 0 ||
columnVisibility.visibleColumns.length === 0
}
size='xs'
iconType='exportAction'
color='primary'
isLoading={isExporting}
className="euiDataGrid__controlBtn"
onClick={onClickExportResults}>
className='euiDataGrid__controlBtn'
onClick={onClickExportResults}
>
Export Formated
</EuiButtonEmpty>
</>
)
),
}}
/>
</div>
</>
) : null}
{inspectedHit && (
<EuiFlyout onClose={() => setInspectedHit(undefined)} size="m">
<EuiFlyout onClose={() => setInspectedHit(undefined)} size='m'>
<EuiFlyoutHeader>
<EuiTitle>
<h2>Document Details</h2>
</EuiTitle>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<EuiFlexGroup direction="column">
<EuiFlexGroup direction='column'>
<EuiFlexItem>
<DocViewer
{...docViewerProps} />
<DocViewer {...docViewerProps} />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutBody>
</EuiFlyout>
)}
</>
</EuiPageTemplate>
</IntlProvider >
</IntlProvider>
);
};

export default WazuhDiscover;
export const WazuhDiscover = withErrorBoundary(WazuhDiscoverComponent);
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { tDataGridColumn } from '../../../common/data-grid';

export const vulnerabilitiesColumns: tDataGridColumn[] = [
{
id: 'agent.name',
},
{
id: 'data.vulnerability.package.name',
},
{
id: 'data.vulnerability.cve',
},
{
id: 'data.vulnerability.severity',
},
{
id: 'data.vulnerability.status',
},
];

0 comments on commit c42fce2

Please sign in to comment.