From 966f5f1c7b05d2e1c19983a500da80c47ed281f2 Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:40:53 +0200 Subject: [PATCH 01/33] Bump 4.10.0 rev 03 (#7110) chore: bump 4.10.0 rev 03 --- CHANGELOG.md | 2 +- plugins/main/opensearch_dashboards.json | 2 +- plugins/main/package.json | 2 +- plugins/wazuh-check-updates/opensearch_dashboards.json | 2 +- plugins/wazuh-check-updates/package.json | 2 +- plugins/wazuh-core/opensearch_dashboards.json | 2 +- plugins/wazuh-core/package.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbd2bb858c..3867436451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to the Wazuh app project will be documented in this file. -## Wazuh v4.10.0 - OpenSearch Dashboards 2.16.0 - Revision 02 +## Wazuh v4.10.0 - OpenSearch Dashboards 2.16.0 - Revision 03 ## Fixed diff --git a/plugins/main/opensearch_dashboards.json b/plugins/main/opensearch_dashboards.json index cd0d8939c2..ec26624f7c 100644 --- a/plugins/main/opensearch_dashboards.json +++ b/plugins/main/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuh", - "version": "4.10.0-02", + "version": "4.10.0-03", "opensearchDashboardsVersion": "opensearchDashboards", "configPath": ["wazuh"], "requiredPlugins": [ diff --git a/plugins/main/package.json b/plugins/main/package.json index 128da3d9df..b550b1aba5 100644 --- a/plugins/main/package.json +++ b/plugins/main/package.json @@ -1,7 +1,7 @@ { "name": "wazuh", "version": "4.10.0", - "revision": "02", + "revision": "03", "pluginPlatform": { "version": "2.16.0" }, diff --git a/plugins/wazuh-check-updates/opensearch_dashboards.json b/plugins/wazuh-check-updates/opensearch_dashboards.json index c30aa25ad9..e930476328 100644 --- a/plugins/wazuh-check-updates/opensearch_dashboards.json +++ b/plugins/wazuh-check-updates/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuhCheckUpdates", - "version": "4.10.0-02", + "version": "4.10.0-03", "opensearchDashboardsVersion": "opensearchDashboards", "server": true, "ui": true, diff --git a/plugins/wazuh-check-updates/package.json b/plugins/wazuh-check-updates/package.json index 022bd7e506..4fb87a0d51 100644 --- a/plugins/wazuh-check-updates/package.json +++ b/plugins/wazuh-check-updates/package.json @@ -1,7 +1,7 @@ { "name": "wazuh-check-updates", "version": "4.10.0", - "revision": "02", + "revision": "03", "pluginPlatform": { "version": "2.16.0" }, diff --git a/plugins/wazuh-core/opensearch_dashboards.json b/plugins/wazuh-core/opensearch_dashboards.json index c7d6b0ae39..03b9c6f312 100644 --- a/plugins/wazuh-core/opensearch_dashboards.json +++ b/plugins/wazuh-core/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuhCore", - "version": "4.10.0-02", + "version": "4.10.0-03", "opensearchDashboardsVersion": "opensearchDashboards", "server": true, "ui": true, diff --git a/plugins/wazuh-core/package.json b/plugins/wazuh-core/package.json index 83ebc5f414..1cca8ce2ec 100644 --- a/plugins/wazuh-core/package.json +++ b/plugins/wazuh-core/package.json @@ -1,7 +1,7 @@ { "name": "wazuh-core", "version": "4.10.0", - "revision": "02", + "revision": "03", "pluginPlatform": { "version": "2.16.0" }, From 576a4036ff3786ebd99ca90bb70141b1f8e6b9f0 Mon Sep 17 00:00:00 2001 From: JuanGarriuz Date: Mon, 21 Oct 2024 15:59:59 +0200 Subject: [PATCH 02/33] Substitute warning icon in events view (#7057) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sustitude warning icon * Update Changelog * Change to iInCircle * Solve aria-label comments and fixed icon centered with text * Solve aria-label nitpick * fix: aria-label in some buttons * fix: aria-label --------- Co-authored-by: Antonio David GutiƩrrez --- CHANGELOG.md | 1 + .../data-grid-additional-controls.tsx | 4 +- .../wazuh-discover/wz-flyout-discover.tsx | 10 +--- .../dashboards/inventory/inventory.tsx | 4 +- .../components/hits_counter/hits_counter.tsx | 58 +++++++++++++------ 5 files changed, 49 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3867436451..8c049b6273 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Changed the agents summary in overview with no results to an agent deployment help message. [#7041](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7041) - Changed malware feature description [#7036](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7036) - Changed the font size of the kpi subtitles and the features descriptions [#7033](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7033) +- Changed the warning icon in events view to a info icon [#7057](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7057) - Changed feature container margins to ensure consistent separation and uniform design. [#7034](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7034) - Changed the initial width to the default columns on each selected field [#7059](https://github.com/wazuh/wazuh-dashboard-plugins/issues/7059) diff --git a/plugins/main/public/components/common/wazuh-discover/components/data-grid-additional-controls.tsx b/plugins/main/public/components/common/wazuh-discover/components/data-grid-additional-controls.tsx index 943bc4bb43..2494628f72 100644 --- a/plugins/main/public/components/common/wazuh-discover/components/data-grid-additional-controls.tsx +++ b/plugins/main/public/components/common/wazuh-discover/components/data-grid-additional-controls.tsx @@ -41,11 +41,11 @@ const DiscoverDataGridAdditionalControls = ( tooltip={ totalHits && totalHits > maxEntriesPerQuery ? { - ariaLabel: 'Warning', + ariaLabel: 'Info', content: `The query results exceeded the limit of ${formatNumWithCommas( maxEntriesPerQuery, )} hits. Please refine your search.`, - iconType: 'alert', + iconType: 'iInCircle', position: 'top', } : undefined diff --git a/plugins/main/public/components/common/wazuh-discover/wz-flyout-discover.tsx b/plugins/main/public/components/common/wazuh-discover/wz-flyout-discover.tsx index f0e2e4199f..3a9852b723 100644 --- a/plugins/main/public/components/common/wazuh-discover/wz-flyout-discover.tsx +++ b/plugins/main/public/components/common/wazuh-discover/wz-flyout-discover.tsx @@ -228,11 +228,7 @@ const WazuhFlyoutDiscoverComponent = (props: WazuhDiscoverProps) => { render: item => ( onExpandRow(item)} - aria-label={ - itemIdToExpandedRowMap.hasOwnProperty(item[INDEX_FIELD_NAME]) - ? 'Collapse' - : 'Expand' - } + aria-label='Info' iconType={ itemIdToExpandedRowMap.hasOwnProperty(item[INDEX_FIELD_NAME]) ? 'arrowDown' @@ -318,11 +314,11 @@ const WazuhFlyoutDiscoverComponent = (props: WazuhDiscoverProps) => { results?.hits?.total && results?.hits?.total > MAX_ENTRIES_PER_QUERY ? { - ariaLabel: 'Warning', + ariaLabel: 'Info', content: `The query results exceeded the limit of ${formatNumWithCommas( MAX_ENTRIES_PER_QUERY, )} hits. Please refine your search.`, - iconType: 'alert', + iconType: 'iInCircle', position: 'top', } : undefined diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx index e4b46f97be..d77b4f2a8d 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.tsx @@ -262,13 +262,13 @@ const InventoryVulsComponent = () => { results?.hits?.total && results?.hits?.total > MAX_ENTRIES_PER_QUERY ? { - ariaLabel: 'Warning', + ariaLabel: 'Info', content: `The query results has exceeded the limit of ${formatNumWithCommas( MAX_ENTRIES_PER_QUERY, )} hits. To provide a better experience the table only shows the first ${formatNumWithCommas( MAX_ENTRIES_PER_QUERY, )} hits.`, - iconType: 'alert', + iconType: 'iInCircle', position: 'top', } : undefined diff --git a/plugins/main/public/kibana-integrations/discover/application/components/hits_counter/hits_counter.tsx b/plugins/main/public/kibana-integrations/discover/application/components/hits_counter/hits_counter.tsx index a46e0d0e3c..061cf59ea7 100644 --- a/plugins/main/public/kibana-integrations/discover/application/components/hits_counter/hits_counter.tsx +++ b/plugins/main/public/kibana-integrations/discover/application/components/hits_counter/hits_counter.tsx @@ -17,7 +17,14 @@ * under the License. */ import React from 'react'; -import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip, EuiIcon } from '@elastic/eui'; +import { + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiText, + EuiToolTip, + EuiIcon, +} from '@elastic/eui'; import { FormattedMessage, I18nProvider } from '@osd/i18n/react'; import { i18n } from '@osd/i18n'; import { formatNumWithCommas } from '../../helpers'; @@ -43,45 +50,62 @@ export interface HitsCounterProps { }; } -export function HitsCounter({ hits, showResetButton, onResetQuery, tooltip }: HitsCounterProps) { +export function HitsCounter({ + hits, + showResetButton, + onResetQuery, + tooltip, +}: HitsCounterProps) { return ( - {formatNumWithCommas(hits)}{' '} + + {formatNumWithCommas(hits)} + {' '} {' '} - {tooltip && tooltip.content && ( - - )} + {tooltip && tooltip.content && ( + + + + )} {showResetButton && ( From 5fb561b08dd0bcce71e1e4a96fd833387fd220e4 Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Wed, 23 Oct 2024 14:50:21 +0200 Subject: [PATCH 03/33] Fix scroll in vulnerabilities inventory table (#7118) * Remove fixed height in Vulnerabilities Inventory table * Add changelog --- CHANGELOG.md | 6 ++---- .../vulnerabilities/dashboards/inventory/inventory.scss | 5 ----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c049b6273..3d428a7785 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,6 @@ All notable changes to the Wazuh app project will be documented in this file. ## Wazuh v4.10.0 - OpenSearch Dashboards 2.16.0 - Revision 03 -## Fixed - -- Fixed the filter are displayed cropped on screens of 575px to 767px in vulnerability detection module [#7047](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7047) - ### Added - Support for Wazuh 4.10.0 @@ -35,6 +31,8 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed export formatted csv data with special characters from tables [#7048](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7048) - Fixed column reordering feature [#7072](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7072) - Fixed filter management to prevent hiding when adding multiple filters [#7077](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7077) +- Fixed vulnerabilities inventory table scroll [#7118](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7118) +- Fixed the filter are displayed cropped on screens of 575px to 767px in vulnerability detection module [#7047](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7047) ### Removed diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss index 4844141f13..46eab9c020 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss @@ -5,11 +5,6 @@ height: max-content !important; } - // This makes the table not generate an unnecessary scroll when filtering data from 1 page and then do another search for more pages. - .vulsInventoryDataGrid { - height: calc(100vh - 216px) !important; - } - .euiDataGrid--fullScreen { height: calc(100vh - 49px); bottom: 0; From 9157e9a9f6a6ea537b9ae617dfc1b21989c32e1b Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:22:50 +0200 Subject: [PATCH 04/33] Fix ability to filter form FIM details (#7119) * fix(fim): fix ability to filter from flyout details in FIM inventory - Fix FIM inventory flyout filters for Files and Registry tabs - Add ability to filter from Last analysis and Last modified fields from Registry details - Add ability to select the visible columns in the Files and Registry tables - Add to Files table the columns: date (hidden), md5 (hidden), sha1 (hidden), sha256 (hidden) - Add to Registry table the columns: date (hidden) - Renamed Last Modified to Last modified in the Files table * chore(changelog): add entry --- CHANGELOG.md | 3 + .../components/agents/fim/inventory.tsx | 55 ++--------- .../agents/fim/inventory/fileDetail.tsx | 16 ++-- .../agents/fim/inventory/registry-table.tsx | 63 +++++++++---- .../components/agents/fim/inventory/table.tsx | 94 ++++++++++++++----- 5 files changed, 132 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d428a7785..bc73471823 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ All notable changes to the Wazuh app project will be documented in this file. - Support for Wazuh 4.10.0 - Added sample data for YARA [#6964](https://github.com/wazuh/wazuh-dashboard-plugins/issues/6964) - Added a custom filter and visualization for vulnerability.under_evaluation field [#6968](https://github.com/wazuh/wazuh-dashboard-plugins/issues/6968) [#7044](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7044) [#7046](https://github.com/wazuh/wazuh-dashboard-plugins/issues/7046) +- Added ability to filter from File Integrity Monitoring registry inventory [#7119](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7119) +- Added new field columns and ability to select the visible fields in the File Integrity Monitoring Files and Registry tables [#7119](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7119) ### Changed @@ -33,6 +35,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed filter management to prevent hiding when adding multiple filters [#7077](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7077) - Fixed vulnerabilities inventory table scroll [#7118](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7118) - Fixed the filter are displayed cropped on screens of 575px to 767px in vulnerability detection module [#7047](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7047) +- Fixed ability to filter from files inventory details flyout of File Integrity Monitoring [#7119](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7119) ### Removed diff --git a/plugins/main/public/components/agents/fim/inventory.tsx b/plugins/main/public/components/agents/fim/inventory.tsx index fbb5d41b22..6353589cb4 100644 --- a/plugins/main/public/components/agents/fim/inventory.tsx +++ b/plugins/main/public/components/agents/fim/inventory.tsx @@ -28,7 +28,6 @@ import { InventoryTable, RegistryTable } from './inventory/'; import { WzRequest } from '../../../react-services/wz-request'; import { getToasts } from '../../../kibana-services'; import { ICustomBadges } from '../../wz-search-bar/components'; -import { filtersToObject } from '../../wz-search-bar'; import { UI_LOGGER_LEVELS } from '../../../../common/constants'; import { UI_ERROR_SEVERITIES, @@ -42,7 +41,6 @@ import { webDocumentationLink } from '../../../../common/services/web_documentat export class Inventory extends Component { _isMount = false; state: { - filters: []; selectedTabId: 'files' | 'registry'; totalItemsFile: number; totalItemsRegistry: number; @@ -57,7 +55,6 @@ export class Inventory extends Component { constructor(props) { super(props); this.state = { - filters: [], syscheck: [], selectedTabId: 'files', totalItemsFile: 0, @@ -66,7 +63,6 @@ export class Inventory extends Component { customBadges: [], isConfigured: false, }; - this.onFiltersChange.bind(this); } async componentDidMount() { @@ -135,56 +131,20 @@ export class Inventory extends Component { return auxTabs; } - getStoreFilters(props) { - const { section, selectView, agent } = props; - const filters = JSON.parse( - window.localStorage.getItem( - `wazuh-${section}-${selectView}-${ - this.state?.selectedTabId || 'files' - }-${agent['id']}`, - ) || '{}', - ); - return filters; - } - - setStoreFilters(filters) { - const { section, selectView, agent } = this.props; - window.localStorage.setItem( - `wazuh-${section}-${selectView}-${this.state?.selectedTabId || 'files'}-${ - agent['id'] - }`, - JSON.stringify(filters), - ); - } - - onFiltersChange = filters => { - this.setState({ filters }); - }; - - onTotalItemsChange = (totalItems: number) => { - this.setState({ totalItemsFile: totalItems }); - }; - onSelectedTabChanged = id => { this.setState({ selectedTabId: id }); }; - buildFilter(type) { - const filters = filtersToObject(this.state.filters); - const filter = { - ...filters, - limit: type === 'file' ? '15' : '1', - ...(type === 'registry' ? { q: 'type=registry_key' } : { type }), - ...(type === 'file' && { sort: '+file' }), - }; - return filter; - } - async getItemNumber(type: 'file' | 'registry') { try { const agentID = this.props.agent.id; const response = await WzRequest.apiReq('GET', `/syscheck/${agentID}`, { - params: this.buildFilter(type), + params: { + limit: 1, // reduce the size because only need the total items. 0 gives error + ...(type === 'registry' + ? { q: 'type=registry_key' } + : { q: 'type=file' }), + }, }); if (type === 'file') { return { @@ -257,8 +217,6 @@ export class Inventory extends Component { filters={filters} items={syscheck} totalItems={totalItemsFile} - onFiltersChange={this.onFiltersChange} - onTotalItemsChange={this.onTotalItemsChange} /> )} {selectedTabId === 'registry' && ( @@ -266,7 +224,6 @@ export class Inventory extends Component { {...this.props} filters={filters} totalItems={totalItemsRegistry} - onFiltersChange={this.onFiltersChange} /> )} diff --git a/plugins/main/public/components/agents/fim/inventory/fileDetail.tsx b/plugins/main/public/components/agents/fim/inventory/fileDetail.tsx index 0dff1a4698..ea2fe09158 100644 --- a/plugins/main/public/components/agents/fim/inventory/fileDetail.tsx +++ b/plugins/main/public/components/agents/fim/inventory/fileDetail.tsx @@ -198,6 +198,7 @@ export class FileDetails extends Component { name: 'Last analysis', grow: 2, icon: 'clock', + link: true, transformValue: formatUIDate, }, { @@ -205,6 +206,7 @@ export class FileDetails extends Component { name: 'Last modified', grow: 2, icon: 'clock', + link: true, transformValue: formatUIDate, }, ]; @@ -290,21 +292,19 @@ export class FileDetails extends Component { } addFilter(field, value) { - const { filters, onFiltersChange } = this.props; - const newBadge: ICustomBadges = { field: 'q', value: '' }; + const { onFiltersChange } = this.props; + let filterUQL = ''; if (field === 'date' || field === 'mtime') { const value_max = moment(value).add(1, 'day'); - newBadge.value = `${field}>${moment(value).format( + filterUQL = `${field}>${moment(value).format( 'YYYY-MM-DD', - )} AND ${field}<${value_max.format('YYYY-MM-DD')}`; + )};${field}<${value_max.format('YYYY-MM-DD')}`; } else { - newBadge.value = `${field}=${ + filterUQL = `${field}=${ field === 'size' ? this.props.currentFile[field] : value }`; } - !filters.some( - item => item.field === newBadge.field && item.value === newBadge.value, - ) && onFiltersChange([...filters, newBadge]); + onFiltersChange({ q: filterUQL }); this.props.closeFlyout(); } diff --git a/plugins/main/public/components/agents/fim/inventory/registry-table.tsx b/plugins/main/public/components/agents/fim/inventory/registry-table.tsx index ee96fff10c..6dfb410c46 100644 --- a/plugins/main/public/components/agents/fim/inventory/registry-table.tsx +++ b/plugins/main/public/components/agents/fim/inventory/registry-table.tsx @@ -21,18 +21,10 @@ import { withRouterSearch } from '../../../common/hocs'; import { Route, Switch } from '../../../router-search'; import NavigationService from '../../../../react-services/navigation-service'; -const searchBarWQLOptions = { - implicitQuery: { - query: 'type=registry_key', - conjunction: ';', - }, -}; - -const searchBarWQLFilters = { default: { q: 'type=registry_key' } }; - export const RegistryTable = withRouterSearch( class RegistryTable extends Component { state: { + filters: {}; syscheck: []; isFlyoutVisible: Boolean; currentFile: { @@ -51,7 +43,7 @@ export const RegistryTable = withRouterSearch( super(props); this.state = { - syscheck: [], + filters: {}, isFlyoutVisible: false, currentFile: { file: '', @@ -73,12 +65,13 @@ export const RegistryTable = withRouterSearch( name: 'Registry', sortable: true, searchable: true, + show: true, }, { field: 'mtime', name: ( - Last Modified{' '} + Last modified{' '} + Last analysis{' '} + + + ), + sortable: true, + width: '100px', + render: formatUIDate, + searchable: false, }, ]; } + onFiltersChange = filters => { + this.setState({ + filters, + }); + }; + renderRegistryTable() { const getRowProps = item => { const { file } = item; @@ -111,6 +129,8 @@ export const RegistryTable = withRouterSearch( const columns = this.columns(); + const APIendpoint = `/syscheck/${this.props.agent.id}?type=registry_key`; + return ( @@ -118,11 +138,11 @@ export const RegistryTable = withRouterSearch( title='Registry' tableColumns={columns} tableInitialSortingField='file' - endpoint={`/syscheck/${this.props.agent.id}`} + endpoint={APIendpoint} searchBarWQL={{ - options: searchBarWQLOptions, suggestions: { field: () => [ + { label: 'date', description: 'filter by analysis time' }, { label: 'file', description: 'filter by file' }, { label: 'mtime', @@ -133,7 +153,7 @@ export const RegistryTable = withRouterSearch( try { const response = await WzRequest.apiReq( 'GET', - `/syscheck/${this.props.agent.id}`, + APIendpoint, { params: { distinct: true, @@ -142,12 +162,9 @@ export const RegistryTable = withRouterSearch( sort: `+${field}`, ...(currentValue ? { - // Add the implicit query - q: `${searchBarWQLOptions.implicitQuery.query}${searchBarWQLOptions.implicitQuery.conjunction}${field}~${currentValue}`, + q: `${field}~${currentValue}`, } - : { - q: `${searchBarWQLOptions.implicitQuery.query}`, - }), + : {}), }, }, ); @@ -174,11 +191,16 @@ export const RegistryTable = withRouterSearch( }, }, }} - filters={searchBarWQLFilters} + filters={this.state.filters} showReload downloadCsv={`fim-registry-${this.props.agent.id}`} searchTable={true} rowProps={getRowProps} + saveStateStorage={{ + system: 'localStorage', + key: 'wz-fim-registry-key-table', + }} + showFieldSelector /> @@ -201,6 +223,7 @@ export const RegistryTable = withRouterSearch( view='inventory' // showViewInEvents={true} {...this.props} + onFiltersChange={this.onFiltersChange} /> )} > diff --git a/plugins/main/public/components/agents/fim/inventory/table.tsx b/plugins/main/public/components/agents/fim/inventory/table.tsx index f9021891db..80157ce30c 100644 --- a/plugins/main/public/components/agents/fim/inventory/table.tsx +++ b/plugins/main/public/components/agents/fim/inventory/table.tsx @@ -21,19 +21,10 @@ import { withRouterSearch } from '../../../common/hocs'; import { Route, Switch } from '../../../router-search'; import NavigationService from '../../../../react-services/navigation-service'; -const searchBarWQLOptions = { - implicitQuery: { - query: 'type=file', - conjunction: ';', - }, -}; - -const searchBarWQLFilters = { default: { q: 'type=file' } }; - export const InventoryTable = withRouterSearch( class InventoryTable extends Component { state: { - syscheck: []; + filters: any; isFlyoutVisible: Boolean; currentFile: { file: string; @@ -46,14 +37,13 @@ export const InventoryTable = withRouterSearch( agent: any; items: []; totalItems: number; - onTotalItemsChange: Function; }; constructor(props) { super(props); this.state = { - syscheck: props.items, + filters: {}, isFlyoutVisible: false, currentFile: { file: '', @@ -80,12 +70,13 @@ export const InventoryTable = withRouterSearch( sortable: true, width: '250px', searchable: true, + show: true, }, { field: 'mtime', name: ( - Last Modified{' '} + Last modified{' '} + Last analysis{' '} + + + ), + sortable: true, + width: '100px', + render: formatUIDate, + searchable: false, + }, + { + field: 'md5', + name: 'MD5', + searchable: true, + sortable: true, + }, + { + field: 'sha1', + name: 'SHA1', + searchable: true, + sortable: true, + }, + { + field: 'sha256', + name: 'SHA256', + searchable: true, + sortable: true, }, ]; } + onFiltersChange = filters => { + this.setState({ + filters, + }); + }; + renderFilesTable() { const getRowProps = item => { const { file } = item; @@ -155,6 +194,8 @@ export const InventoryTable = withRouterSearch( }; const columns = this.columns(); + const APIendpoint = `/syscheck/${this.props.agent.id}?type=file`; + return ( @@ -162,18 +203,24 @@ export const InventoryTable = withRouterSearch( title='Files' tableColumns={columns} tableInitialSortingField='file' - endpoint={`/syscheck/${this.props.agent.id}`} + endpoint={APIendpoint} searchBarWQL={{ - options: searchBarWQLOptions, suggestions: { field: currentValue => [ + { label: 'date', description: 'filter by analysis time' }, { label: 'file', description: 'filter by file' }, { label: 'gid', description: 'filter by group id' }, { label: 'gname', description: 'filter by group name' }, + { label: 'md5', description: 'filter by MD5 checksum' }, { label: 'mtime', description: 'filter by modification time', }, + { label: 'sha1', description: 'filter by SHA1 checksum' }, + { + label: 'sha256', + description: 'filter by SHA256 checksum', + }, { label: 'size', description: 'filter by size' }, { label: 'uname', description: 'filter by user name' }, { label: 'uid', description: 'filter by user id' }, @@ -182,7 +229,7 @@ export const InventoryTable = withRouterSearch( try { const response = await WzRequest.apiReq( 'GET', - `/syscheck/${this.props.agent.id}`, + APIendpoint, { params: { distinct: true, @@ -191,12 +238,9 @@ export const InventoryTable = withRouterSearch( sort: `+${field}`, ...(currentValue ? { - // Add the implicit query - q: `${searchBarWQLOptions.implicitQuery.query}${searchBarWQLOptions.implicitQuery.conjunction}${field}~${currentValue}`, + q: `${field}~${currentValue}`, } - : { - q: `${searchBarWQLOptions.implicitQuery.query}`, - }), + : {}), }, }, ); @@ -223,11 +267,16 @@ export const InventoryTable = withRouterSearch( }, }, }} - filters={searchBarWQLFilters} + filters={this.state.filters} showReload downloadCsv={`fim-files-${this.props.agent.id}`} searchTable={true} rowProps={getRowProps} + saveStateStorage={{ + system: 'localStorage', + key: 'wz-fim-files-table', + }} + showFieldSelector /> @@ -251,6 +300,7 @@ export const InventoryTable = withRouterSearch( view='inventory' showViewInEvents={true} {...this.props} + onFiltersChange={this.onFiltersChange} /> )} > From e74b7ed46d3e35d7961415891499322b4d59c9fc Mon Sep 17 00:00:00 2001 From: Guido Modarelli <38738725+guidomodarelli@users.noreply.github.com> Date: Thu, 24 Oct 2024 10:34:11 -0300 Subject: [PATCH 05/33] Remove processes state column in macOS agents (#7122) * Refactor process column mapping to use a dedicated function for improved readability and maintainability * Update CHANGELOG to document removal of processes state column in macOS agents (#7122) * Refactor process column mapping to use `mapColumns` for consistency across OS implementations and enhance code clarity * Remove unused 'State' column from inventory snapshot for better clarity in agent rendering tests --- CHANGELOG.md | 1 + .../__snapshots__/inventory.test.tsx.snap | 27 +------------------ .../syscollector/columns/process-columns.ts | 17 ++++++++---- 3 files changed, 14 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc73471823..5cc2303e22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Removed agent RBAC filters from dashboard queries [#6945](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6945) - Removed GET /elastic/statistics API endpoint [#7001](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7001) - Removed VirusTotal application in favor of Malware Detection [#7038](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7038) +- Removed processes state column in macOS agents [#7122](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7122) ## Wazuh v4.9.1 - OpenSearch Dashboards 2.13.0 - Revision 04 diff --git a/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap b/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap index d048bbcd49..92dad0b43e 100644 --- a/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap +++ b/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap @@ -2085,31 +2085,6 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = ` - - - @@ -2118,7 +2093,7 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = ` >
({ + ...rest, + field, + name: rest.name || KeyEquivalence[field] || field, +}); const windowsColumns = [ { field: 'name', searchable: true, sortable: true, width: '10%' }, @@ -8,7 +14,8 @@ const windowsColumns = [ { field: 'priority', searchable: true, sortable: true }, { field: 'nlwp', searchable: true, sortable: true }, { field: 'cmd', searchable: true, sortable: true, width: '30%' }, -].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field})); +].map(mapColumns); + const linuxColumns = [ { field: 'name', searchable: true, sortable: true, width: '10%' }, { field: 'euser', searchable: true, sortable: true }, @@ -22,7 +29,8 @@ const linuxColumns = [ { field: 'session', searchable: true, sortable: true }, { field: 'nice', searchable: true, sortable: true }, { field: 'state', searchable: true, sortable: true, width: '15%' }, -].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field})); +].map(mapColumns); + const macColumns = [ { field: 'name', searchable: true, sortable: true, width: '10%' }, { field: 'euser', searchable: true, sortable: true }, @@ -30,8 +38,7 @@ const macColumns = [ { field: 'ppid', searchable: true, sortable: true }, { field: 'vm_size', searchable: true, sortable: true }, { field: 'nice', searchable: true, sortable: true }, - { field: 'state', searchable: true, sortable: true, width: '15%' }, -].map(({field, ...rest}) => ({...rest, field, name: rest.name || KeyEquivalence[field] || field})); +].map(mapColumns); export const processColumns = { windows: windowsColumns, From 5d9046f9d7877deb221b152bd705a7e8af61a011 Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Thu, 24 Oct 2024 15:40:40 +0200 Subject: [PATCH 06/33] Fix agents chart loading state (#7120) * Fix agents chart loading state * Add changelog --- CHANGELOG.md | 1 + .../public/components/overview/overview.tsx | 4 +- .../controllers/overview/components/stats.js | 82 +++++++++++-------- 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cc2303e22..7bd848e047 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed read-only users could not access to Statistics application [#7001](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7001) - Fixed no-agent-alert spawn with selected agent in agent-welcome view [#7029](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7029) +- Fixed loading state of the agents status chart in the home overview [#7120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7120) - Fixed security policy exception when it contained deprecated actions [#7042](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7042) - Fixed export formatted csv data with special characters from tables [#7048](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7048) - Fixed column reordering feature [#7072](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7072) diff --git a/plugins/main/public/components/overview/overview.tsx b/plugins/main/public/components/overview/overview.tsx index de7a53e7de..91e9c97528 100644 --- a/plugins/main/public/components/overview/overview.tsx +++ b/plugins/main/public/components/overview/overview.tsx @@ -40,6 +40,7 @@ export const Overview: React.FC = withRouteResolvers({ savedSearch, })(() => { const [agentsCounts, setAgentsCounts] = useState({}); + const [isAgentsLoading, setIsAgentsLoading] = useState(true); const { tab = 'welcome', tabView = 'dashboard', agentId } = useRouterSearch(); const navigationService = NavigationService.getInstance(); const pinnedAgentManager = new PinnedAgentManager(); @@ -131,6 +132,7 @@ export const Overview: React.FC = withRouteResolvers({ }, } = await WzRequest.apiReq('GET', '/agents/summary/status', {}); setAgentsCounts(data); + setIsAgentsLoading(false); } catch (error) { return Promise.reject(error); } @@ -167,7 +169,7 @@ export const Overview: React.FC = withRouteResolvers({ - + diff --git a/plugins/main/public/controllers/overview/components/stats.js b/plugins/main/public/controllers/overview/components/stats.js index 97fbb7cfec..aec7fcbfba 100644 --- a/plugins/main/public/controllers/overview/components/stats.js +++ b/plugins/main/public/controllers/overview/components/stats.js @@ -79,20 +79,39 @@ export const Stats = withErrorBoundary( ); } + /** + * Calculate the size of the visualization evaluating if it renders the internal loading or the chart + * based on the viewport size + */ + getVisualizationSize() { + const normalLoadingSize = { width: 377, height: '150px' }; + const mobileLoadingSize = { + height: '150px', + }; + const loadingSize = + window.innerWidth < 768 ? mobileLoadingSize : normalLoadingSize; + const size = this.props.isAgentsLoading + ? loadingSize + : { width: '100%', height: '150px' }; + return size; + } + render() { + const { isAgentsLoading } = this.props; const hasResults = this.agentStatus.some( ({ status }) => this.props[status], ); + const showAgentsChart = isAgentsLoading || hasResults; return ( - {hasResults ? ( + {showAgentsChart ? ( ({ @@ -107,36 +126,33 @@ export const Stats = withErrorBoundary( )} /> ) : ( - !hasResults && - this.props !== undefined && ( - - This instance has no agents registered. -
- Please deploy agents to begin monitoring your endpoints. -

- } - actions={ - - Deploy new agent - - } - /> - ) + + This instance has no agents registered. +
+ Please deploy agents to begin monitoring your endpoints. +

+ } + actions={ + + Deploy new agent + + } + /> )}
From 1fa58e71882bfe715fe8cf77f0f476658f06709b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chantal=20Bel=C3=A9n=20kelm?= <99441266+chantal-kelm@users.noreply.github.com> Date: Fri, 25 Oct 2024 04:40:14 -0300 Subject: [PATCH 07/33] Create agents management menu and move sections (#7112) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * create agents management menu and move sections * update changelog * move sections to a different location * Changes in the categories * changes in the categories * changes in the categories --------- Co-authored-by: Antonio David GutiƩrrez --- CHANGELOG.md | 1 + plugins/main/public/utils/applications.ts | 329 +++++++++++----------- 2 files changed, 170 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bd848e047..774ae6eaf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Support for Wazuh 4.10.0 - Added sample data for YARA [#6964](https://github.com/wazuh/wazuh-dashboard-plugins/issues/6964) - Added a custom filter and visualization for vulnerability.under_evaluation field [#6968](https://github.com/wazuh/wazuh-dashboard-plugins/issues/6968) [#7044](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7044) [#7046](https://github.com/wazuh/wazuh-dashboard-plugins/issues/7046) +- Added an "Agents management" menu and moved the sections: "Endpoint Groups" and "Endpoint Summary" which changed its name to "Summary".[#7112](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7112) - Added ability to filter from File Integrity Monitoring registry inventory [#7119](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7119) - Added new field columns and ability to select the visible fields in the File Integrity Monitoring Files and Registry tables [#7119](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7119) diff --git a/plugins/main/public/utils/applications.ts b/plugins/main/public/utils/applications.ts index 76ecbc060c..9b07810efd 100644 --- a/plugins/main/public/utils/applications.ts +++ b/plugins/main/public/utils/applications.ts @@ -24,8 +24,9 @@ Endpoint security: 200 Threat intelligence: 300 Security operations: 400 Cloud security: 500 -Server management: 600 -Dashboard management: 700 +Agents management: 600 +Server management: 700 +Dashboard management Indexer management (added to Wazuh dashboard default categories): 9000 */ @@ -54,53 +55,34 @@ export const overview = { }`, }; -export const fileIntegrityMonitoring = { +export const configurationAssessment = { category: 'wz-category-endpoint-security', - id: 'file-integrity-monitoring', - title: i18n.translate('wz-app-file-integrity-monitoring-title', { - defaultMessage: 'File Integrity Monitoring', + id: 'configuration-assessment', + title: i18n.translate('wz-app-configuration-assessment-title', { + defaultMessage: 'Configuration Assessment', }), breadcrumbLabel: i18n.translate( - 'wz-app-file-integrity-monitoring-breadcrumbLabel', + 'wz-app-configuration-assessment-breadcrumbLabel', { - defaultMessage: 'File Integrity Monitoring', + defaultMessage: 'Configuration Assessment', }, ), - description: i18n.translate('wz-app-file-integrity-monitoring-description', { + description: i18n.translate('wz-app-configuration-assessment-description', { defaultMessage: - 'Alerts related to file changes, including permissions, content, ownership, and attributes.', + 'Scan your assets as part of a configuration assessment audit.', }), - euiIconType: 'sqlApp', + order: 200, + euiIconType: 'managementApp', showInOverviewApp: true, showInAgentMenu: true, - order: 202, redirectTo: () => - `/overview/?tab=fim&tabView=dashboard${ + `/overview/?tab=sca&tabView=dashboard${ store.getState()?.appStateReducers?.currentAgentData?.id ? `&agentId=${store.getState()?.appStateReducers?.currentAgentData?.id}` : '' }`, }; -export const endpointSummary = { - category: 'wz-category-server-management', - id: 'endpoints-summary', - title: i18n.translate('wz-app-endpoints-summary-title', { - defaultMessage: 'Endpoints Summary', - }), - breadcrumbLabel: i18n.translate('wz-app-endpoints-summary-breadcrumbLabel', { - defaultMessage: 'Endpoints', - }), - description: i18n.translate('wz-app-endpoints-summary-description', { - defaultMessage: 'Summary of agents and their status.', - }), - euiIconType: 'spacesApp', - order: 600, - showInOverviewApp: false, - showInAgentMenu: false, - redirectTo: () => '/agents-preview/', -}; - export const malwareDetection = { category: 'wz-category-endpoint-security', id: 'malware-detection', @@ -126,28 +108,28 @@ export const malwareDetection = { }`, }; -export const configurationAssessment = { +export const fileIntegrityMonitoring = { category: 'wz-category-endpoint-security', - id: 'configuration-assessment', - title: i18n.translate('wz-app-configuration-assessment-title', { - defaultMessage: 'Configuration Assessment', + id: 'file-integrity-monitoring', + title: i18n.translate('wz-app-file-integrity-monitoring-title', { + defaultMessage: 'File Integrity Monitoring', }), breadcrumbLabel: i18n.translate( - 'wz-app-configuration-assessment-breadcrumbLabel', + 'wz-app-file-integrity-monitoring-breadcrumbLabel', { - defaultMessage: 'Configuration Assessment', + defaultMessage: 'File Integrity Monitoring', }, ), - description: i18n.translate('wz-app-configuration-assessment-description', { + description: i18n.translate('wz-app-file-integrity-monitoring-description', { defaultMessage: - 'Scan your assets as part of a configuration assessment audit.', + 'Alerts related to file changes, including permissions, content, ownership, and attributes.', }), - order: 200, - euiIconType: 'managementApp', + euiIconType: 'sqlApp', showInOverviewApp: true, showInAgentMenu: true, + order: 202, redirectTo: () => - `/overview/?tab=sca&tabView=dashboard${ + `/overview/?tab=fim&tabView=dashboard${ store.getState()?.appStateReducers?.currentAgentData?.id ? `&agentId=${store.getState()?.appStateReducers?.currentAgentData?.id}` : '' @@ -257,50 +239,50 @@ const pciDss = { }`, }; -const hipaa = { +const gdpr = { category: 'wz-category-security-operations', - id: 'hipaa', - title: i18n.translate('wz-app-hipaa-title', { - defaultMessage: 'HIPAA', + id: 'gdpr', + title: i18n.translate('wz-app-gdpr-title', { + defaultMessage: 'GDPR', }), - breadcrumbLabel: i18n.translate('wz-app-hipaa-breadcrumbLabel', { - defaultMessage: 'HIPAA', + breadcrumbLabel: i18n.translate('wz-app-gdpr-breadcrumbLabel', { + defaultMessage: 'GDPR', }), - description: i18n.translate('wz-app-hipaa-description', { + description: i18n.translate('wz-app-gdpr-description', { defaultMessage: - 'Health Insurance Portability and Accountability Act of 1996 (HIPAA) provides data privacy and security provisions for safeguarding medical information.', + 'General Data Protection Regulation (GDPR) sets guidelines for processing of personal data.', }), - euiIconType: 'monitoringApp', - order: 402, + euiIconType: 'visBarVertical', + order: 401, showInOverviewApp: true, showInAgentMenu: true, redirectTo: () => - `/overview/?tab=hipaa&tabView=dashboard${ + `/overview/?tab=gdpr&tabView=dashboard${ store.getState()?.appStateReducers?.currentAgentData?.id ? `&agentId=${store.getState()?.appStateReducers?.currentAgentData?.id}` : '' }`, }; -const gdpr = { +const hipaa = { category: 'wz-category-security-operations', - id: 'gdpr', - title: i18n.translate('wz-app-gdpr-title', { - defaultMessage: 'GDPR', + id: 'hipaa', + title: i18n.translate('wz-app-hipaa-title', { + defaultMessage: 'HIPAA', }), - breadcrumbLabel: i18n.translate('wz-app-gdpr-breadcrumbLabel', { - defaultMessage: 'GDPR', + breadcrumbLabel: i18n.translate('wz-app-hipaa-breadcrumbLabel', { + defaultMessage: 'HIPAA', }), - description: i18n.translate('wz-app-gdpr-description', { + description: i18n.translate('wz-app-hipaa-description', { defaultMessage: - 'General Data Protection Regulation (GDPR) sets guidelines for processing of personal data.', + 'Health Insurance Portability and Accountability Act of 1996 (HIPAA) provides data privacy and security provisions for safeguarding medical information.', }), - euiIconType: 'visBarVertical', - order: 401, + euiIconType: 'monitoringApp', + order: 402, showInOverviewApp: true, showInAgentMenu: true, redirectTo: () => - `/overview/?tab=gdpr&tabView=dashboard${ + `/overview/?tab=hipaa&tabView=dashboard${ store.getState()?.appStateReducers?.currentAgentData?.id ? `&agentId=${store.getState()?.appStateReducers?.currentAgentData?.id}` : '' @@ -357,6 +339,31 @@ const tsc = { }`, }; +export const docker = { + category: 'wz-category-cloud-security', + id: 'docker', + title: i18n.translate('wz-app-docker-title', { + defaultMessage: 'Docker', + }), + breadcrumbLabel: i18n.translate('wz-app-docker-breadcrumbLabel', { + defaultMessage: 'Docker', + }), + description: i18n.translate('wz-app-docker-description', { + defaultMessage: + 'Monitor and collect the activity from Docker containers such as creation, running, starting, stopping or pausing events.', + }), + euiIconType: LogoDocker, + order: 500, + showInOverviewApp: true, + showInAgentMenu: true, + redirectTo: () => + `/overview/?tab=docker&tabView=dashboard${ + store.getState()?.appStateReducers?.currentAgentData?.id + ? `&agentId=${store.getState()?.appStateReducers?.currentAgentData?.id}` + : '' + }`, +}; + export const amazonWebServices = { category: 'wz-category-cloud-security', id: 'amazon-web-services', @@ -374,7 +381,7 @@ export const amazonWebServices = { 'Security events related to your Amazon AWS services, collected directly via AWS API.', }), euiIconType: 'logoAWSMono', - order: 500, + order: 501, showInOverviewApp: true, showInAgentMenu: true, redirectTo: () => @@ -399,7 +406,7 @@ export const googleCloud = { 'Security events related to your Google Cloud Platform services, collected directly via GCP API.', }), euiIconType: LogoGoogleCloud, - order: 501, + order: 502, showInOverviewApp: true, showInAgentMenu: true, redirectTo: () => @@ -424,7 +431,7 @@ export const github = { 'Monitoring events from audit logs of your GitHub organizations.', }), euiIconType: LogoGitHub, - order: 502, + order: 503, showInOverviewApp: true, showInAgentMenu: true, redirectTo: () => @@ -448,7 +455,7 @@ export const office365 = { defaultMessage: 'Security events related to your Office 365 services.', }), euiIconType: LogoOffice365, - order: 503, + order: 504, showInOverviewApp: true, showInAgentMenu: true, redirectTo: () => @@ -459,29 +466,42 @@ export const office365 = { }`, }; -export const docker = { - category: 'wz-category-cloud-security', - id: 'docker', - title: i18n.translate('wz-app-docker-title', { - defaultMessage: 'Docker', +export const endpointSummary = { + category: 'wz-category-agents-management', + id: 'endpoints-summary', + title: i18n.translate('wz-app-endpoints-summary-title', { + defaultMessage: 'Summary', }), - breadcrumbLabel: i18n.translate('wz-app-docker-breadcrumbLabel', { - defaultMessage: 'Docker', + breadcrumbLabel: i18n.translate('wz-app-endpoints-summary-breadcrumbLabel', { + defaultMessage: 'Endpoints', }), - description: i18n.translate('wz-app-docker-description', { - defaultMessage: - 'Monitor and collect the activity from Docker containers such as creation, running, starting, stopping or pausing events.', + description: i18n.translate('wz-app-endpoints-summary-description', { + defaultMessage: 'Summary of agents and their status.', }), - euiIconType: LogoDocker, - order: 404, - showInOverviewApp: true, - showInAgentMenu: true, - redirectTo: () => - `/overview/?tab=docker&tabView=dashboard${ - store.getState()?.appStateReducers?.currentAgentData?.id - ? `&agentId=${store.getState()?.appStateReducers?.currentAgentData?.id}` - : '' - }`, + euiIconType: 'spacesApp', + order: 600, + showInOverviewApp: false, + showInAgentMenu: false, + redirectTo: () => '/agents-preview/', +}; + +export const endpointGroups = { + category: 'wz-category-agents-management', + id: 'endpoint-groups', + title: i18n.translate('wz-app-endpoint-groups-title', { + defaultMessage: 'Endpoint Groups', + }), + breadcrumbLabel: i18n.translate('wz-app-endpoint-groups-breadcrumbLabel', { + defaultMessage: 'Endpoint Groups', + }), + description: i18n.translate('wz-app-endpoint-groups-description', { + defaultMessage: 'Manage your agent groups.', + }), + euiIconType: 'usersRolesApp', + order: 601, + showInOverviewApp: false, + showInAgentMenu: false, + redirectTo: () => '/manager/?tab=groups', }; export const rules = { @@ -497,7 +517,7 @@ export const rules = { defaultMessage: 'Manage your cluster rules.', }), euiIconType: 'indexRollupApp', - order: 602, + order: 700, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=ruleset', @@ -516,7 +536,7 @@ export const decoders = { defaultMessage: 'Manage your cluster decoders.', }), euiIconType: 'indexRollupApp', - order: 603, + order: 701, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=decoders', @@ -535,31 +555,12 @@ export const cdbLists = { defaultMessage: 'Manage your cluster CDB list.', }), euiIconType: 'indexRollupApp', - order: 604, + order: 702, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=lists', }; -export const endpointGroups = { - category: 'wz-category-server-management', - id: 'endpoint-groups', - title: i18n.translate('wz-app-endpoint-groups-title', { - defaultMessage: 'Endpoint Groups', - }), - breadcrumbLabel: i18n.translate('wz-app-endpoint-groups-breadcrumbLabel', { - defaultMessage: 'Endpoint Groups', - }), - description: i18n.translate('wz-app-endpoint-groups-description', { - defaultMessage: 'Manage your agent groups.', - }), - euiIconType: 'usersRolesApp', - order: 601, - showInOverviewApp: false, - showInAgentMenu: false, - redirectTo: () => '/manager/?tab=groups', -}; - export const serverStatus = { category: 'wz-category-server-management', id: 'server-status', @@ -573,7 +574,7 @@ export const serverStatus = { defaultMessage: 'Manage your cluster status.', }), euiIconType: 'indexRollupApp', - order: 605, + order: 703, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=status', @@ -592,7 +593,7 @@ export const cluster = { defaultMessage: 'Manage your cluster.', }), euiIconType: 'indexRollupApp', - order: 606, + order: 704, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=monitoring', @@ -611,7 +612,7 @@ export const statistics = { defaultMessage: 'Information about the enviroment.', }), euiIconType: 'indexRollupApp', - order: 607, + order: 705, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=statistics', @@ -630,31 +631,12 @@ export const logs = { defaultMessage: 'Logs from your cluster.', }), euiIconType: 'indexRollupApp', - order: 608, + order: 706, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=logs', }; -export const reporting = { - category: 'wz-category-dashboard-management', - id: 'reporting', - title: i18n.translate('wz-app-reporting-title', { - defaultMessage: 'Reporting', - }), - breadcrumbLabel: i18n.translate('wz-app-reporting-breadcrumbLabel', { - defaultMessage: 'Reporting', - }), - description: i18n.translate('wz-app-reporting-description', { - defaultMessage: 'Check your stored reports.', - }), - euiIconType: 'indexRollupApp', - order: 10002, - showInOverviewApp: false, - showInAgentMenu: false, - redirectTo: () => '/manager/?tab=reporting', -}; - export const settings = { category: 'wz-category-server-management', id: 'dashboards-settings', @@ -668,7 +650,7 @@ export const settings = { defaultMessage: 'Manage your cluster configuration.', }), euiIconType: 'indexRollupApp', - order: 609, + order: 707, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/manager/?tab=configuration', @@ -687,7 +669,7 @@ export const devTools = { defaultMessage: 'Test the API endpoints.', }), euiIconType: 'devToolsApp', - order: 610, + order: 708, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/wazuh-dev?tab=devTools', @@ -706,7 +688,7 @@ export const rulesetTest = { defaultMessage: 'Check your ruleset testing logs.', }), euiIconType: 'visualizeApp', - order: 611, + order: 709, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/wazuh-dev?tab=logtest', @@ -726,31 +708,12 @@ export const security = { 'Manage permissions to system resources based on the roles and policies.', }), euiIconType: 'securityAnalyticsApp', - order: 612, + order: 710, showInOverviewApp: false, showInAgentMenu: false, redirectTo: () => '/security?tab=users', }; -export const serverApis = { - category: 'wz-category-dashboard-management', - id: 'server-apis', - title: i18n.translate('wz-app-server-apis-title', { - defaultMessage: 'Server APIs', - }), - breadcrumbLabel: i18n.translate('wz-app-server-apis-breadcrumbLabel', { - defaultMessage: 'Server APIs', - }), - description: i18n.translate('wz-app-server-apis-description', { - defaultMessage: 'Manage and configure the API entries.', - }), - euiIconType: 'indexRollupApp', - order: 10003, - showInOverviewApp: false, - showInAgentMenu: false, - redirectTo: () => '/settings?tab=api', -}; - export const sampleData = { category: 'management', id: 'sample-data', @@ -770,6 +733,44 @@ export const sampleData = { redirectTo: () => '/settings?tab=sample_data', }; +export const reporting = { + category: 'wz-category-dashboard-management', + id: 'reporting', + title: i18n.translate('wz-app-reporting-title', { + defaultMessage: 'Reporting', + }), + breadcrumbLabel: i18n.translate('wz-app-reporting-breadcrumbLabel', { + defaultMessage: 'Reporting', + }), + description: i18n.translate('wz-app-reporting-description', { + defaultMessage: 'Check your stored reports.', + }), + euiIconType: 'indexRollupApp', + order: 10002, + showInOverviewApp: false, + showInAgentMenu: false, + redirectTo: () => '/manager/?tab=reporting', +}; + +export const serverApis = { + category: 'wz-category-dashboard-management', + id: 'server-apis', + title: i18n.translate('wz-app-server-apis-title', { + defaultMessage: 'Server APIs', + }), + breadcrumbLabel: i18n.translate('wz-app-server-apis-breadcrumbLabel', { + defaultMessage: 'Server APIs', + }), + description: i18n.translate('wz-app-server-apis-description', { + defaultMessage: 'Manage and configure the API entries.', + }), + euiIconType: 'indexRollupApp', + order: 10003, + showInOverviewApp: false, + showInAgentMenu: false, + redirectTo: () => '/settings?tab=api', +}; + export const appSettings = { category: 'wz-category-dashboard-management', id: 'app-settings', @@ -897,12 +898,20 @@ export const Categories = [ order: 500, euiIconType: 'watchesApp', }, + { + id: 'wz-category-agents-management', + label: i18n.translate('wz-app-category-agents-management', { + defaultMessage: 'Agents management', + }), + order: 600, + euiIconType: 'indexRollupApp', + }, { id: 'wz-category-server-management', label: i18n.translate('wz-app-category-server-management', { defaultMessage: 'Server management', }), - order: 600, + order: 700, euiIconType: 'indexRollupApp', }, { @@ -910,13 +919,13 @@ export const Categories = [ label: i18n.translate('wz-app-category-dashboard-management', { defaultMessage: 'Dashboard management', }), - order: 6e3, + order: 5e3, euiIconType: 'dashboardApp', }, { id: 'management', label: 'Indexer management', - order: 5e3, + order: 6e3, euiIconType: 'managementApp', }, ]; From b87b0268db018982f6a0382d90252cb1c1e64e3b Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:32:54 +0200 Subject: [PATCH 08/33] Bump 4.9.2 rev 00 (#7126) * chore: bump 4.9.2 rev 00 * chore(changelog): add entry * feat(bump): add ability to edit the imposter specification file reference on bump script of main plugin --- CHANGELOG.md | 6 +++ docker/imposter/wazuh-config.yml | 2 +- plugins/main/opensearch_dashboards.json | 2 +- plugins/main/package.json | 4 +- plugins/main/scripts/release/bump.js | 43 +++++++++++++++++++ .../opensearch_dashboards.json | 2 +- plugins/wazuh-check-updates/package.json | 4 +- plugins/wazuh-core/opensearch_dashboards.json | 2 +- plugins/wazuh-core/package.json | 4 +- 9 files changed, 59 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d023a77b81..05e7e38146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to the Wazuh app project will be documented in this file. +## Wazuh v4.9.2 - OpenSearch Dashboards 2.13.0 - Revision 00 + +### Added + +- Support for Wazuh 4.9.2 + ## Wazuh v4.9.1 - OpenSearch Dashboards 2.13.0 - Revision 04 ### Added diff --git a/docker/imposter/wazuh-config.yml b/docker/imposter/wazuh-config.yml index 8f99c6897e..d8c2ae672a 100755 --- a/docker/imposter/wazuh-config.yml +++ b/docker/imposter/wazuh-config.yml @@ -1,6 +1,6 @@ --- plugin: openapi -specFile: https://raw.githubusercontent.com/wazuh/wazuh/master/api/api/spec/spec.yaml +specFile: https://raw.githubusercontent.com/wazuh/wazuh/4.9.2/api/api/spec/spec.yaml system: stores: # this store is preloaded from file diff --git a/plugins/main/opensearch_dashboards.json b/plugins/main/opensearch_dashboards.json index 6fce1510e4..b9b73e5517 100644 --- a/plugins/main/opensearch_dashboards.json +++ b/plugins/main/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuh", - "version": "4.9.1-04", + "version": "4.9.2-00", "opensearchDashboardsVersion": "opensearchDashboards", "configPath": ["wazuh"], "requiredPlugins": [ diff --git a/plugins/main/package.json b/plugins/main/package.json index af2557b1da..4325fedb44 100644 --- a/plugins/main/package.json +++ b/plugins/main/package.json @@ -1,7 +1,7 @@ { "name": "wazuh", - "version": "4.9.1", - "revision": "04", + "version": "4.9.2", + "revision": "00", "pluginPlatform": { "version": "2.13.0" }, diff --git a/plugins/main/scripts/release/bump.js b/plugins/main/scripts/release/bump.js index d76addd24b..a8f342f4ba 100644 --- a/plugins/main/scripts/release/bump.js +++ b/plugins/main/scripts/release/bump.js @@ -53,6 +53,47 @@ const cli = require('../../../../scripts/lib/cli/cli')( ], ); +function updateImposterSpecificationReference(configuration, logger) { + try { + logger.debug('Editing imposter specification reference'); + const fs = require('fs'); + const path = require('path'); + const specificationFile = path.join( + __dirname, + '../../../..', + 'docker/imposter/wazuh-config.yml', + ); + + logger.debug(`Reading ${specificationFile} file`); + const content = fs.readFileSync(specificationFile, 'utf8'); + + const { version } = configuration; + + if (!version) { + throw new Error('Version is not specified.'); + } + + // specFile: https://raw.githubusercontent.com/wazuh/wazuh//api/api/spec/spec.yaml + const updatedContent = content.replace( + /specFile:\s+\S+/m, + `specFile: https://raw.githubusercontent.com/wazuh/wazuh/${version}/api/api/spec/spec.yaml`, + ); + + if (content !== updatedContent) { + logger.debug( + `Updating [${specificationFile}] imposter specification file with latest changes`, + ); + fs.writeFileSync(specificationFile, updatedContent, 'utf8'); + logger.info(`${specificationFile} file has been updated`); + } else { + logger.debug(`Nothing to change in ${specificationFile} file`); + } + } catch (error) { + logger.error(`Error editing the specification file: ${error.message}`); + process.exit(1); + } +} + function run(configuration, logger) { let localConfiguration = { ...configuration, @@ -90,6 +131,8 @@ function run(configuration, logger) { ); process.exit(1); } + + updateImposterSpecificationReference(localConfiguration, logger); } const logger = require('../../../../scripts/release/lib/logger').create([ diff --git a/plugins/wazuh-check-updates/opensearch_dashboards.json b/plugins/wazuh-check-updates/opensearch_dashboards.json index ff7eb1c5e0..4c0572390e 100644 --- a/plugins/wazuh-check-updates/opensearch_dashboards.json +++ b/plugins/wazuh-check-updates/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuhCheckUpdates", - "version": "4.9.1-04", + "version": "4.9.2-00", "opensearchDashboardsVersion": "opensearchDashboards", "server": true, "ui": true, diff --git a/plugins/wazuh-check-updates/package.json b/plugins/wazuh-check-updates/package.json index c1bd160044..05ba1f7860 100644 --- a/plugins/wazuh-check-updates/package.json +++ b/plugins/wazuh-check-updates/package.json @@ -1,7 +1,7 @@ { "name": "wazuh-check-updates", - "version": "4.9.1", - "revision": "04", + "version": "4.9.2", + "revision": "00", "pluginPlatform": { "version": "2.13.0" }, diff --git a/plugins/wazuh-core/opensearch_dashboards.json b/plugins/wazuh-core/opensearch_dashboards.json index 4a80f42b28..d06a31df4e 100644 --- a/plugins/wazuh-core/opensearch_dashboards.json +++ b/plugins/wazuh-core/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuhCore", - "version": "4.9.1-04", + "version": "4.9.2-00", "opensearchDashboardsVersion": "opensearchDashboards", "server": true, "ui": true, diff --git a/plugins/wazuh-core/package.json b/plugins/wazuh-core/package.json index 44272d720a..5848556277 100644 --- a/plugins/wazuh-core/package.json +++ b/plugins/wazuh-core/package.json @@ -1,7 +1,7 @@ { "name": "wazuh-core", - "version": "4.9.1", - "revision": "04", + "version": "4.9.2", + "revision": "00", "pluginPlatform": { "version": "2.13.0" }, From 632f493217d29b73fff08bc75bf39b3943c00ba4 Mon Sep 17 00:00:00 2001 From: Federico Rodriguez Date: Fri, 25 Oct 2024 13:09:52 +0200 Subject: [PATCH 09/33] Fix vulnerability inventory table scroll (#7128) * Fix vulnerability inventory table scroll * Add changelog --- CHANGELOG.md | 4 ++++ .../vulnerabilities/dashboards/inventory/inventory.scss | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05e7e38146..37f7212cbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ All notable changes to the Wazuh app project will be documented in this file. - Support for Wazuh 4.9.2 +### Fixed + +- Fixed vulnerabilities inventory table scroll [#7128](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7128) + ## Wazuh v4.9.1 - OpenSearch Dashboards 2.13.0 - Revision 04 ### Added diff --git a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss index 4844141f13..46eab9c020 100644 --- a/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss +++ b/plugins/main/public/components/overview/vulnerabilities/dashboards/inventory/inventory.scss @@ -5,11 +5,6 @@ height: max-content !important; } - // This makes the table not generate an unnecessary scroll when filtering data from 1 page and then do another search for more pages. - .vulsInventoryDataGrid { - height: calc(100vh - 216px) !important; - } - .euiDataGrid--fullScreen { height: calc(100vh - 49px); bottom: 0; From 9ea89404857dd839576a985899bd07a9d110a41f Mon Sep 17 00:00:00 2001 From: JuanGarriuz Date: Mon, 28 Oct 2024 08:53:06 +0100 Subject: [PATCH 10/33] Fixed border on cells in events disappear (#7075) * Overwrite eui styles * Added changelog * Solve styles * Change border per shadow-box * Fix changelog --------- Co-authored-by: Federico Rodriguez --- CHANGELOG.md | 1 + plugins/main/public/styles/common.scss | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 774ae6eaf6..b626ef9d35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Fixed no-agent-alert spawn with selected agent in agent-welcome view [#7029](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7029) - Fixed loading state of the agents status chart in the home overview [#7120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7120) - Fixed security policy exception when it contained deprecated actions [#7042](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7042) +- Fixed border on cells in events that disappear when clicked [#7075](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7075) - Fixed export formatted csv data with special characters from tables [#7048](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7048) - Fixed column reordering feature [#7072](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7072) - Fixed filter management to prevent hiding when adding multiple filters [#7077](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7077) diff --git a/plugins/main/public/styles/common.scss b/plugins/main/public/styles/common.scss index b9e4429542..31007c0175 100644 --- a/plugins/main/public/styles/common.scss +++ b/plugins/main/public/styles/common.scss @@ -324,12 +324,6 @@ input[type='search'].euiFieldSearch { box-shadow: none; } -:focus:not(.wz-button):not(.input-filter-box):not(.kuiLocalSearchInput):not( - .euiTextArea - ):not(.euiPanel.euiPopover__panel.euiPopover__panel-isOpen) { - box-shadow: none !important; -} - /* Custom colors styles */ .color-white { color: white; From 713f4a60b493f451751d3425a2b2a84d14f20333 Mon Sep 17 00:00:00 2001 From: Antonio <34042064+Desvelao@users.noreply.github.com> Date: Mon, 28 Oct 2024 15:40:11 +0100 Subject: [PATCH 11/33] Bump 4.9.2 rev01 (#7134) chore: bump 4.9.2 rev01 --- CHANGELOG.md | 2 +- plugins/main/opensearch_dashboards.json | 2 +- plugins/main/package.json | 2 +- plugins/wazuh-check-updates/opensearch_dashboards.json | 2 +- plugins/wazuh-check-updates/package.json | 2 +- plugins/wazuh-core/opensearch_dashboards.json | 2 +- plugins/wazuh-core/package.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37f7212cbb..20aebf1819 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ All notable changes to the Wazuh app project will be documented in this file. -## Wazuh v4.9.2 - OpenSearch Dashboards 2.13.0 - Revision 00 +## Wazuh v4.9.2 - OpenSearch Dashboards 2.13.0 - Revision 01 ### Added diff --git a/plugins/main/opensearch_dashboards.json b/plugins/main/opensearch_dashboards.json index b9b73e5517..bd0235a0e9 100644 --- a/plugins/main/opensearch_dashboards.json +++ b/plugins/main/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuh", - "version": "4.9.2-00", + "version": "4.9.2-01", "opensearchDashboardsVersion": "opensearchDashboards", "configPath": ["wazuh"], "requiredPlugins": [ diff --git a/plugins/main/package.json b/plugins/main/package.json index 4325fedb44..89cdee3c90 100644 --- a/plugins/main/package.json +++ b/plugins/main/package.json @@ -1,7 +1,7 @@ { "name": "wazuh", "version": "4.9.2", - "revision": "00", + "revision": "01", "pluginPlatform": { "version": "2.13.0" }, diff --git a/plugins/wazuh-check-updates/opensearch_dashboards.json b/plugins/wazuh-check-updates/opensearch_dashboards.json index 4c0572390e..814ab83336 100644 --- a/plugins/wazuh-check-updates/opensearch_dashboards.json +++ b/plugins/wazuh-check-updates/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuhCheckUpdates", - "version": "4.9.2-00", + "version": "4.9.2-01", "opensearchDashboardsVersion": "opensearchDashboards", "server": true, "ui": true, diff --git a/plugins/wazuh-check-updates/package.json b/plugins/wazuh-check-updates/package.json index 05ba1f7860..728bad47f4 100644 --- a/plugins/wazuh-check-updates/package.json +++ b/plugins/wazuh-check-updates/package.json @@ -1,7 +1,7 @@ { "name": "wazuh-check-updates", "version": "4.9.2", - "revision": "00", + "revision": "01", "pluginPlatform": { "version": "2.13.0" }, diff --git a/plugins/wazuh-core/opensearch_dashboards.json b/plugins/wazuh-core/opensearch_dashboards.json index d06a31df4e..a77821f642 100644 --- a/plugins/wazuh-core/opensearch_dashboards.json +++ b/plugins/wazuh-core/opensearch_dashboards.json @@ -1,6 +1,6 @@ { "id": "wazuhCore", - "version": "4.9.2-00", + "version": "4.9.2-01", "opensearchDashboardsVersion": "opensearchDashboards", "server": true, "ui": true, diff --git a/plugins/wazuh-core/package.json b/plugins/wazuh-core/package.json index 5848556277..9bc499a2e3 100644 --- a/plugins/wazuh-core/package.json +++ b/plugins/wazuh-core/package.json @@ -1,7 +1,7 @@ { "name": "wazuh-core", "version": "4.9.2", - "revision": "00", + "revision": "01", "pluginPlatform": { "version": "2.13.0" }, From 1287cdf837f46e787f7521cabf2f59ff9f9de529 Mon Sep 17 00:00:00 2001 From: Guido Modarelli <38738725+guidomodarelli@users.noreply.github.com> Date: Tue, 29 Oct 2024 07:27:28 -0300 Subject: [PATCH 12/33] Redesign inventory, stats and configuration page to use tabs (#7089) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add toTitleCase function for changing text to title case * Update MainModuleAgent component to display section in EuiTabs * Update module.scss styles for module header agent * Change stats page to use tabs in Wazuh app * Refactor useAsyncAction function with TypeScript * Refactor AgentsWelcome component structure and layout * Refactor conditional rendering logic for main agent module * Remove unused EuiTitle import and euiThemeVars * Add EuiPanel around AgentInfo component in MainModuleAgent * Update indexPattern access to handle null values safely * Fix Prettier issue * Remove global breadcrumb from MainModuleAgent component * Update AgentStats component with AgentInfo component * Add AgentInfo component and update configuration options * Fix Prettier issue * Update stats and configuration page to use tabs * feat: add AgentInfo component to display agent details with customizable stats and styling. Includes initial SCSS for layout * fix: update import path for AgentInfo and adjust EuiSpacer size to improve layout in agent stats component * style: add overflow-y auto to visualization layout for improved scroll handling on small screens * refactor: simplify layout in SyscollectorInventory by removing unnecessary EuiFlexGroups for better readability and performance * refactor: remove unused styles in welcome component for cleaner SCSS and enhanced maintainability * refactor: update import path for AgentInfo in agents-welcome for improved file organization and clarity * refactor: remove unused .wz-module-header-agent styles for cleaner SCSS and improved code maintainability * refactor: remove unused import of Agent in endpoints-summary for cleaner code and improved maintainability * refactor: simplify MainModuleAgent component by removing unnecessary class for cleaner markup and improved readability * refactor: enhance SyscollectorInventory with EuiPanel and AgentInfo for improved layout and readability * refactor: update import path for AgentInfo to improve module structure and clarity in main-agent component * refactor: use clsx for conditional class assignment in MainModuleAgent component for cleaner markup and improved maintainability * refactor: adjust margin for .wz-module-header-agent to improve layout consistency in module.scss * refactor: fine-tune margin for EuiFlexItem in MainModuleOverview to enhance layout consistency and visual alignment * refactor: refine EuiFlexGroup and EuiFlexItem margins in MainModuleAgent for better layout consistency and visual alignment * refactor: update SyscollectorInventory to use EuiPage for improved layout structure and consistency in inventory.tsx * refactor: update Prettier and VSCode settings for consistent formatting and improved layout with adjusted print width and arrow parens * refactor: adjust font size and weight for .euiTab__content in module.scss to enhance layout and text readability * refactor: streamline MainModuleAgent component by simplifying conditional rendering and enhancing code readability * refactor: simplify component structure by removing unnecessary divs and styles related to agent info for cleaner code and UI * refactor: remove padding and min-height from welcome agent tabs for a cleaner dark theme UI design * refactor: remove unused variable in AgentsWelcome component for improved code clarity and maintainability * refactor: add margin-right to ButtonExploreAgent for better alignment in AgentsWelcome component UI * refactor: simplify import statements and improve code consistency in AgentsWelcome component for better readability and maintainability * refactor: adjust indentation for improved readability in MainModuleAgent component's JSX structure * refactor: streamline formatting and improve readability in AgentInfo component's JavaScript logic and JSX structure * refactor: update marginTop style in MainModuleAgent component for better visual alignment in the rendered output * feat: add SECTIONS enum to define constants for different sections in the application for improved organization and clarity * feat: create AgentTabs constants for improved organization of agent-related sections in the application * refactor: remove unused sections constants from WzMenu for cleaner code and improved maintainability * feat: integrate AgentTabs constants into AgentsWelcome for consistent tab handling and cleaner code structure * fix: update Endpoint summary link to use constants for navigation and improve consistency in routing across the application * feat: enhance routing in AgentView by utilizing AgentTabs constants for improved navigation consistency and cleaner code structure * refactor: streamline AgentView implementation by consolidating imports and utilizing AgentTabs for cleaner tab management * refactor: replace hardcoded route paths with SECTIONS constants for improved maintainability and consistency in app-router.tsx * refactor: update MainModuleAgent to use AgentTabs for improved tab management and clean up loading state handling * refactor: optimize ButtonExploreAgent rendering and streamline ComplianceTable component usage for cleaner code structure * feat: add Network component for displaying agent network details, including interfaces, ports, and settings in a structured layout * feat: introduce Software component to display agent software details, including platform-specific packages and updates management * feat: enhance AgentView to include MainSyscollector and enable switchTab functionality for improved agent details display * feat: update MainModuleAgent to support switchTab functionality for improved navigation across agent sections * feat: refactor SyscollectorInventory to conditionally render Software and Network components based on selected section * feat: simplify imports and adjust layout in SyscollectorInventory for improved readability and structure * feat: rename Network and Software components to NetworkTab and SoftwareTab for consistency and clarity in SyscollectorInventory * feat: add ProcessesTab component to Syscollector for displaying agent processes within the inventory view * feat: refactor SyscollectorInventory to improve component imports and update layout for better structure and readability * feat: update CHANGELOG to reflect change of inventory, stats, and configuration pages to use tabs for improved navigation * feat: clean up SyscollectorInventory layout by removing redundant direction prop in EuiFlexGroup components for better clarity * feat: streamline component imports and formatting in various files for improved code cleanliness and consistency * Revert prettier file * Revert Prettier and .vscode/settings.json * Revert ,vscode/settings.json * Fix Prettier issue * Refactor MainModuleAgent to use inventoryTabs for rendering tabs dynamically * Update inventory tests to use AgentTabs for network section rendering in SyscollectorInventory * Update inventory snapshots and tests for network ports table rendering across agents with correct titles and columns * Update inventory snapshots and tests for network interfaces and settings table rendering with correct titles and columns across agents * Refactor inventory tests to enhance structure and maintainability for network settings and interfaces rendering across agents * Update inventory snapshots and tests for software and Windows updates tables, ensuring correct rendering across agents with titles and columns * Update inventory snapshots and tests for processes table rendering, ensuring correct columns and titles for all agent types * Add data-test-subj for agent info in snapshots and tests, ensuring accurate rendering for Linux, Windows, and Apple agents * Refactor agent-stats component by removing redundant statsAgents definition, simplifying header column structure for better clarity * Add tests for AgentStats component, ensuring it correctly renders agent info and integrates with mock services * Add tests for WzConfigurationSwitch component, ensuring it correctly renders agent info and integrates with mock services * Add data-test-subj attributes to multiple table components for improved testing consistency in snapshots * Fix Prettier issue * Enhance type annotations in ReportingService for improved clarity and TypeScript compatibility * Add data-test attributes for improved testing in MainModuleAgent and GenerateReportButton components * Improve type safety in MainModuleAgent and GenerateReportButton by specifying Agent type for agent prop * Remove unused imports and instances of ReportingService and FilterHandler in MainModuleAgent for cleaner code * Remove unused imports in MainModuleAgent for cleaner code and improved maintainability * Remove unused state property 'switchModule' in MainModuleAgent for cleaner code and improved maintainability * Remove unused state property 'selectView' in MainModuleAgent for cleaner code and improved maintainability * Fix optional chaining for renderTabs method in MainModuleAgent to improve code robustness and maintainability * Refactor tab layout in MainModuleAgent for improved readability and consistent formatting in JSX structure * Add unit tests for MainModuleAgent to validate tab rendering behavior across sections for better test coverage and reliability * Add unique key prop to EuiTab in MainModuleAgent for better performance and to prevent React warnings during rendering * Update MainModuleAgent and tests for dynamic report tab rendering based on section, ensuring accurate content display * Refactor MainModuleAgent tests to use Testing Library, improving readability and adding click handler verification for tab switching * Refactor WzConfigurationSwitch tests to use Testing Library, enhancing clarity and ensuring proper agent info rendering * Refactor MainAgent tests to use constants for report tab identifiers, enhancing readability and maintainability of the tests * Refactor AgentStats tests to utilize queryDataTestAttr for agent info, enhancing test readability and maintainability * Refactor AgentStats test to use container and queryDataTestAttr, improving test readability and maintainability * Fix Prettier issue * Update report tab constants in main-agent tests for consistency with new naming conventions * Refactor AgentStats test to use wrapper for querying agent info, enhancing readability and maintainability * Enhance WzManagementConfiguration to always show agent info and improve conditionals in WzConfigurationSwitch for better clarity * Add data-test-subj to EuiSpacer and update tests for WzConfigurationSwitch to handle showAgentInfo condition better * Remove outdated group display logic in WzConfigurationSwitch to improve component clarity and reduce unnecessary complexity * Fix Prettier issue * style(visualizations): remove overflow-y property from visualization layout for better responsiveness on small screens * refactor(configuration-switch): streamline agent grouping display and remove redundant agent info section from component and tests * refactor(agent-stats): enhance stats display with structured fields and loading spinner, removing old agent info test case * refactor(main-agent): simplify section checks by limiting tabs to SOFTWARE, NETWORK, and PROCESSES for improved readability and performance * refactor(main-agent): destructure props for improved readability and simplify tab checks in rendering logic * test(main-agent): add tests to verify absence of generate report button and agent info ribbon in WzConfigurationSwitch component * test(inventory): remove STATE column from processes table test for accurate representation of data * test(agent-stats): add tests to verify absence of generate report button and agent info ribbon in AgentStats component * test(agent-stats): simplify imports in agent-stats test file for cleaner code organization * fix(wz-text-with-tooltip): refactor props interface and clean up component for better readability and maintainability * fix(group-truncate): update filterAction type and simplify action function for improved clarity and type safety * refactor(agent-info): migrate agents-info.js to TypeScript for improved type safety and maintainability * refactor(agent-info): rename agents-info to agent-info for consistent naming and improved clarity in imports * fix(group-truncate): make action type explicit and handle optional filterAction for better clarity and type safety * refactor(agent-info): rename checkField to renderField for improved clarity in rendering agent information * refactor(agent-info): simplify getOsName method for clearer logic and improved readability of OS name and version handling * refactor(agent-status): enhance type safety in AgentStatus props and clarify status handling with TypeScript types * refactor(agent-info): streamline agent stats structure and replace WzStat with RibbonItem for better component organization * refactor(agent-info): update labels to use RibbonItemLabel constants for improved consistency and clarity in agent stats display * refactor(agent-info): simplify agent stats display by replacing specific fields with the entire agent object for consistency * refactor(api-response): add api_version field to IData interface for better API version management and clarity * refactor(agent-info): remove direct agent reference from RibbonItem, enhancing component flexibility and consistency * feat(ribbon-item): implement RibbonItem component for enhanced display of agent information with flexible styling and tooltips * refactor(ribbon-item): rename renderTitle to renderValue for improved clarity in value rendering logic * feat(ribbon): add Ribbon component for flexible ribbon layout, enhancing agent info display in the application * refactor(ribbon-item): rename class from wz-agent-info to wz-ribbon-item for better consistency in styling across components * refactor(ribbon): rename Ribbon to WzRibbon for consistent naming across components and improve clarity in the codebase * refactor(syscollector-metrics): simplify rendering by utilizing WzRibbon for improved readability and maintainability * refactor(inventory): replace AgentInfo with InventoryMetrics to streamline inventory rendering and enhance code clarity * refactor(ribbon): add loading state and improve structure by wrapping WzRibbon in EuiPanel for better layout management * refactor(syscollector-metrics): streamline imports and use lodash directly for emptiness checks to enhance code clarity * refactor(syscollector-metrics): replace static label with constant for improved consistency and maintainability * refactor(syscollector-metrics): increase maxWidth for CPU styling to improve display consistency in metrics component * refactor(ribbon-item): enhance OS detection by adding support for Ubuntu in the ribbon item component * refactor(ribbon-item): adjust styling to incorporate font size constant and optional style for better design adaptability * refactor(ribbon-item): add optional icon property to ribbon items for improved visual representation in the UI * refactor(agents-welcome): simplify layout by removing unnecessary EuiPanel wrapper around AgentInfo component * refactor(main-agent): streamline rendering logic by removing redundant state and simplify component structure for better readability * refactor(ribbon): add unique keys for ribbon items to enhance rendering performance and avoid React warnings * refactor(syscollector-metrics): add unique keys to ribbon items for improved rendering and to eliminate React warnings * refactor(agent-stats): replace panel with WzRibbon for better presentation and streamline loading state rendering logic * Fix Prettier issue * refactor(ribbon): add SCSS styling for ribbon item and remove unused agent info styles to streamline components * refactor(syscollector): replace EuiPanel with EuiPageBody for improved layout and streamline agent status display logic * style(constants): fix formatting issue in AGENT_STATUS_CODE array to align with code style guidelines * chore(tests): update snapshots and refactor inventory tests for better consistency and maintainability * Fix Prettier issue * feat(tests): enhance WzConfigurationSwitch tests and add CSS selector utility for querying test attributes * feat(ui): rename report-tabs to agent-tabs for improved clarity in MainModuleAgent component * feat(tests): update test descriptions and selectors to reflect renaming of report tabs to agent tabs in MainModuleAgent tests * feat(tests): refine agent-stats and main-agent tests to include checks for generate report button presence and descriptions * feat(tests): add inventory metrics tests for Debian agent in SyscollectorInventory components across software, network, and processes sections * feat(tests): improve selector readability in main-agent tests by extracting aria-selected constant for consistency * feat(tests): enhance main-agent tests with comprehensive coverage for all tab sections and generate report button assertions * feat(tests): add ribbon rendering tests in AgentStats to ensure accurate display of status and metrics attributes * fix(tests): correct syntax in AgentStats test for improved readability and maintainability of ribbon item assertions * feat(tests): add unit tests for InventoryMetrics to validate rendering of syscollector metrics and ribbon items * fix(wz-agents): change agent parameter type to optional for better flexibility in getAgentOSType function * fix(agent-info/syscollector): update labels and key assignments for better clarity in metrics display and styling adjustments * fix(ribbon): adjust padding size and justify content for better layout in the ribbon component * fix(ribbon): update label formats to lowercase and switch from label to key for item identification in ribbon component * fix(ribbon): add conditional rendering to prevent empty icon display in ribbon item component * fix(agent-group-truncate): enhance button styling with specified font weight and size for improved consistency * fix(snapshot): update ribbon item data-test attribute to reflect correct label for operating system and adjust styles accordingly * fix(reporting): change default value of agents parameter from string to false in startVis2Png method * fix(agent): remove unnecessary prop from WzManagementConfiguration in AgentView component * fix(ribbon): rename STATUS label to AGENT_STATUS in ribbon and agent info components * fix(agent-info): update label casing for agent status and group in AgentInfo component --------- Co-authored-by: Chantal BelƩn kelm <99441266+chantal-kelm@users.noreply.github.com> --- CHANGELOG.md | 1 + docker/imposter/wazuh-config.yml | 2 +- .../main/common/services/wz_agent_status.ts | 31 +- plugins/main/public/app-router.tsx | 29 +- .../public/components/agents/agent-status.tsx | 18 +- .../agents/stats/agent-stats.test.tsx | 68 + .../components/agents/stats/agent-stats.tsx | 45 +- .../__snapshots__/inventory.test.tsx.snap | 22307 ++++++++++++---- .../components/network-interfaces-table.tsx | 2 +- .../components/network-ports-table.tsx | 2 +- .../components/network-settings-table.tsx | 2 +- .../components/packages-table.tsx | 2 +- .../components/processes-table.tsx | 2 +- .../components/syscollector-metrics.test.tsx | 88 + .../components/syscollector-metrics.tsx | 189 +- .../components/windows-updates-table.tsx | 2 +- .../agents/syscollector/inventory.test.tsx | 704 +- .../agents/syscollector/inventory.tsx | 96 +- .../agents/syscollector/network.tsx | 33 + .../agents/syscollector/processes.tsx | 21 + .../agents/syscollector/software.tsx | 26 + .../common/hooks/use_async_action.ts | 15 +- .../common/modules/main-agent.test.tsx | 359 + .../components/common/modules/main-agent.tsx | 229 +- .../common/modules/main-overview.tsx | 2 +- .../components/common/modules/module.scss | 31 +- .../common/modules/modules-defaults.tsx | 8 +- .../components/common/ribbon/ribbon-item.scss | 4 + .../components/common/ribbon/ribbon-item.tsx | 148 + .../components/common/ribbon/ribbon.tsx | 28 + .../table-with-search-bar.test.tsx.snap | 2 + .../__snapshots__/table-wz-api.test.tsx.snap | 2 + .../common/tables/table-with-search-bar.tsx | 1 + .../components/common/tables/table-wz-api.tsx | 2 +- .../agent-group-truncate/group-truncate.tsx | 18 +- .../components/common/util/change-case.ts | 3 + .../common/welcome/agent-info/agent-info.tsx | 134 + .../components/common/welcome/agents-info.js | 232 - .../common/welcome/agents-welcome.js | 189 +- .../components/common/welcome/welcome.scss | 15 - .../wz-text-with-tooltip-if-truncated.tsx | 64 +- .../endpoints-summary/agent/agent-tabs.ts | 8 + .../endpoints-summary/agent/index.tsx | 39 +- .../__snapshots__/agents-table.test.tsx.snap | 6 + .../__snapshots__/intelligence.test.tsx.snap | 2 + .../main/public/components/wz-menu/wz-menu.js | 11 - .../configuration/configuration-switch.js | 527 +- .../configuration-switch.test.tsx | 206 + .../interfaces/api-response.interface.ts | 1 + .../main/public/react-services/reporting.js | 7 +- .../main/public/react-services/wz-agents.ts | 7 +- plugins/main/public/sections.ts | 11 + .../public/styles/theme/dark/index.dark.scss | 13 - plugins/main/test/public/query-attr.ts | 8 + plugins/main/test/utils/CSS.ts | 27 + 55 files changed, 19693 insertions(+), 6336 deletions(-) create mode 100644 plugins/main/public/components/agents/stats/agent-stats.test.tsx create mode 100644 plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx create mode 100644 plugins/main/public/components/agents/syscollector/network.tsx create mode 100644 plugins/main/public/components/agents/syscollector/processes.tsx create mode 100644 plugins/main/public/components/agents/syscollector/software.tsx create mode 100644 plugins/main/public/components/common/modules/main-agent.test.tsx create mode 100644 plugins/main/public/components/common/ribbon/ribbon-item.scss create mode 100644 plugins/main/public/components/common/ribbon/ribbon-item.tsx create mode 100644 plugins/main/public/components/common/ribbon/ribbon.tsx create mode 100644 plugins/main/public/components/common/util/change-case.ts create mode 100644 plugins/main/public/components/common/welcome/agent-info/agent-info.tsx delete mode 100644 plugins/main/public/components/common/welcome/agents-info.js create mode 100644 plugins/main/public/components/endpoints-summary/agent/agent-tabs.ts create mode 100644 plugins/main/public/controllers/management/components/management/configuration/configuration-switch.test.tsx create mode 100644 plugins/main/public/sections.ts create mode 100644 plugins/main/test/public/query-attr.ts create mode 100644 plugins/main/test/utils/CSS.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index b626ef9d35..05f54d57c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Changed the warning icon in events view to a info icon [#7057](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7057) - Changed feature container margins to ensure consistent separation and uniform design. [#7034](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7034) - Changed the initial width to the default columns on each selected field [#7059](https://github.com/wazuh/wazuh-dashboard-plugins/issues/7059) +- Changed inventory, stats and configuration page to use tabs [#7089](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7089) ### Fixed diff --git a/docker/imposter/wazuh-config.yml b/docker/imposter/wazuh-config.yml index 8f99c6897e..cc745fa33e 100755 --- a/docker/imposter/wazuh-config.yml +++ b/docker/imposter/wazuh-config.yml @@ -1,6 +1,6 @@ --- plugin: openapi -specFile: https://raw.githubusercontent.com/wazuh/wazuh/master/api/api/spec/spec.yaml +specFile: https://raw.githubusercontent.com/wazuh/wazuh/4.10.0/api/api/spec/spec.yaml system: stores: # this store is preloaded from file diff --git a/plugins/main/common/services/wz_agent_status.ts b/plugins/main/common/services/wz_agent_status.ts index 3c37e98a92..694e536917 100644 --- a/plugins/main/common/services/wz_agent_status.ts +++ b/plugins/main/common/services/wz_agent_status.ts @@ -1,14 +1,27 @@ -import { UI_COLOR_AGENT_STATUS, UI_LABEL_NAME_AGENT_STATUS, API_NAME_AGENT_STATUS } from '../constants'; +import { + UI_COLOR_AGENT_STATUS, + UI_LABEL_NAME_AGENT_STATUS, + API_NAME_AGENT_STATUS, +} from '../constants'; -type TAgentStatus = typeof API_NAME_AGENT_STATUS[keyof typeof API_NAME_AGENT_STATUS]; +export type TAgentStatus = + (typeof API_NAME_AGENT_STATUS)[keyof typeof API_NAME_AGENT_STATUS]; -type TAgentStatusColor = typeof UI_COLOR_AGENT_STATUS[keyof typeof UI_COLOR_AGENT_STATUS]; -type TAgentStatusLabel = typeof UI_LABEL_NAME_AGENT_STATUS[keyof typeof UI_LABEL_NAME_AGENT_STATUS]; +type TAgentStatusColor = + (typeof UI_COLOR_AGENT_STATUS)[keyof typeof UI_COLOR_AGENT_STATUS]; +type TAgentStatusLabel = + (typeof UI_LABEL_NAME_AGENT_STATUS)[keyof typeof UI_LABEL_NAME_AGENT_STATUS]; -export function agentStatusColorByAgentStatus(status: TAgentStatus): TAgentStatusColor{ - return UI_COLOR_AGENT_STATUS[status] || UI_COLOR_AGENT_STATUS.default; +export function agentStatusColorByAgentStatus( + status: TAgentStatus, +): TAgentStatusColor { + return UI_COLOR_AGENT_STATUS[status] || UI_COLOR_AGENT_STATUS.default; } -export function agentStatusLabelByAgentStatus(status: TAgentStatus): TAgentStatusLabel{ - return UI_LABEL_NAME_AGENT_STATUS[status] || UI_LABEL_NAME_AGENT_STATUS.default; -} \ No newline at end of file +export function agentStatusLabelByAgentStatus( + status: TAgentStatus, +): TAgentStatusLabel { + return ( + UI_LABEL_NAME_AGENT_STATUS[status] || UI_LABEL_NAME_AGENT_STATUS.default + ); +} diff --git a/plugins/main/public/app-router.tsx b/plugins/main/public/app-router.tsx index 842c07ae03..8f45a6b3cd 100644 --- a/plugins/main/public/app-router.tsx +++ b/plugins/main/public/app-router.tsx @@ -21,6 +21,7 @@ import { Settings } from './components/settings'; import { WzSecurity } from './components/security'; import $ from 'jquery'; import NavigationService from './react-services/navigation-service'; +import { SECTIONS } from './sections'; export function Application(props) { const dispatch = useDispatch(); @@ -66,33 +67,41 @@ export function Application(props) { - + - + - + } > - - + + } > } > diff --git a/plugins/main/public/components/agents/agent-status.tsx b/plugins/main/public/components/agents/agent-status.tsx index a7967a0d92..65179ba825 100644 --- a/plugins/main/public/components/agents/agent-status.tsx +++ b/plugins/main/public/components/agents/agent-status.tsx @@ -2,15 +2,29 @@ import React from 'react'; import { agentStatusColorByAgentStatus, agentStatusLabelByAgentStatus, + TAgentStatus, } from '../../../common/services/wz_agent_status'; import { ColumnWithStatusIcon } from './column-with-status-icon'; import { EuiIconTip } from '@elastic/eui'; import { AGENT_STATUS_CODE } from '../../../common/constants'; import '../../styles/common.scss'; +import { Agent } from '../endpoints-summary/types'; -export const AgentStatus = ({ status, children = null, style = {}, agent }) => { +interface AgentStatusProps { + status: TAgentStatus; + children?: string | null; + style?: React.CSSProperties; + agent?: Agent; +} + +export const AgentStatus = ({ + status, + children, + style = {}, + agent, +}: AgentStatusProps) => { const statusCodeAgent = AGENT_STATUS_CODE.find( - (status: StatusCodeAgent) => status.STATUS_CODE === agent?.status_code, + status => status.STATUS_CODE === agent?.status_code, ); return (
({ + WzRequest: { + apiReq: jest.fn().mockResolvedValue(undefined), + }, +})); + +describe('AgentStats', () => { + it('should not render agent info ribbon', async () => { + await act(async () => { + const { container } = render(); + + const agentInfoRibbon = container.querySelector( + queryDataTestAttr('agent-info'), + ); + expect(agentInfoRibbon).toBeFalsy(); + }); + }); + + it('should render stats info ribbon', async () => { + await act(async () => { + const { container } = render(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-status')), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr('ribbon-item-buffer_enabled'), + ), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-msg_buffer')), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-msg_count')), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-msg_sent')), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-last_ack')), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr('ribbon-item-last_keepalive'), + ), + ).toBeTruthy(); + + expect( + container.querySelectorAll( + queryDataTestAttr('ribbon-item-', CSS.Attribute.Substring), + ), + ).toHaveLength(7); + }); + }); +}); diff --git a/plugins/main/public/components/agents/stats/agent-stats.tsx b/plugins/main/public/components/agents/stats/agent-stats.tsx index 2d57187359..98f966281c 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.tsx @@ -47,6 +47,7 @@ import { import { getErrorOrchestrator } from '../../../react-services/common-services'; import { endpointSummary } from '../../../utils/applications'; import NavigationService from '../../../react-services/navigation-service'; +import WzRibbon from '../../common/ribbon/ribbon'; const tableColumns = [ { @@ -142,7 +143,8 @@ export const MainAgentStats = compose( ), )(AgentStats); -function AgentStats({ agent }) { +export function AgentStats(props) { + const { agent } = props; const [loading, setLoading] = useState(); const [dataStatLogcollector, setDataStatLogcollector] = useState({}); const [dataStatAgent, setDataStatAgent] = useState(); @@ -186,33 +188,20 @@ function AgentStats({ agent }) { return ( - - - - - {statsAgents.map(stat => ( - - - {stat.title}:{' '} - {loading ? ( - - ) : ( - - {dataStatAgent !== undefined - ? stat.render - ? stat.render(dataStatAgent[stat.field]) - : dataStatAgent?.[stat.field] - : '-'} - - )} - - - ))} - - - - - + ({ + key: stat.field, + label: stat.title, + isLoading: loading, + value: + dataStatAgent !== undefined + ? stat.render + ? stat.render(dataStatAgent[stat.field]) + : dataStatAgent?.[stat.field] + : '-', + }))} + /> +
+ +
+
+ + + Cores [object Object] +
+
+
+ +
+
+ + + Memory [object Object] +
+
+
+ +
+
+ + + Arch [object Object] +
+
+
+ +
+
+ + + Operating system [object Object] +
+
+
+ +
+
+ + + CPU [object Object] +
+ +
+ +
+
+ + + Host name [object Object] +
+ +
+ +
+
+ + + Board serial [object Object] +
+ +
+ +
+
+ + + Last scan [object Object] +
- -
+
-

- Network interfaces - - (0) - -

-
-
-
-
-
-
- + Network interfaces + + (0) + + +
+
- + + + + Refresh + + + +
+
+ +
+
-
-
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
-
+
+
+
+
+ +
+
+
+
+
+
+ + + + + - - - - - - + + + + +
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
-
- - -
+
+ + - - - - - - - - - - - + - + + + + + + + + +
-
- - - Name - - - - - - + - - MAC - - - - - + - - State - + + + Type + + + +
+
+ + No items found + +
+
+ + + + + + +
+
+
+
+
+
+
+
+

+ Network ports + + (0) - -

+ + + +
+
+
-
+
-
+
- - No items found - +
+
+ +
+
+
-
+
+
+ + + + + + + + + + + + + + +
+
+ + + Local port + + + + + + Local IP address + + + + + + +
+
+ + No items found + +
+
+
+
-
-
-

- Network ports - - (0) - -

+

+ Network settings + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
-
+
+
- - WQL + + WQL + - - + +
@@ -686,183 +1209,238 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - + + - + - + - + - - - - - + + + + -
- - No items found - -
- - - -
-
- +
+
- - Local port - - - - + + Interface + + + + + - - Local IP address - - - - + - - State + + Netmask + - - - - - - Protocol + + Protocol + - - -
+ + + +
+ + No items found + +
+ + + + +
@@ -870,23 +1448,301 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = `
+
+`; + +exports[`Inventory data Network Network interfaces table A Linux agent should render network interfaces table with correct columns and title. 1`] = ` +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
-

- Network settings - - (0) - -

-
-
-
-
-
-
- + Network interfaces + + (0) + + +
+
- -
-
-
-
-
-
-
-
-
-
-
+
-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - -
-
- - - - - +
-
- -
-
- - No items found - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

- Packages - - (0) - -

-
-
-
-
-
-
- -
-
- +
+
-
-
-
-
-
+
-
+
-
- -
-
+
-
+
+
- - WQL - - - + + + WQL + + + +
+
-
-
-
-
-
+
-
-
+
+
+
+
+ +
+
+
+
+
+
+ + + + + - - + +
+
+ + - - - - - - - - - - + + + + + + + + + +
-
- - - Name - - + + State + + + + + + + +
+
+ + No items found + +
+
+ + + + + + +
+
+
+
+
+
+
+
+

+ Network ports + + (0) + +

+
+
+
+
+
+
+ -
+
-
+ + + + +
+
+
+
+
- +
+
+
+
+
+ + + +
+
+
+
+
+
+
- +
+
+ +
+
+
+
+
+
+ + + + - - - - - - - + + + + + + - - No items found - - - - - -
+
- Format + + Local port + - - - - - Location + + Local IP address + - - - - - Description + + Process + - - -
-
+
+ + + PID + + + + + + +
+
+ + No items found + +
+ +
+
+
-
-
-
-
-

- Processes - - (0) - -

+

+ Network settings + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
-
+
+
- - WQL + + WQL + - - + +
@@ -1852,262 +2692,238 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - + + - + - + - + - + - + + + + - - - - - - - - - -
-
-
+
- - Name + + Interface + + - - - - - - - Effective user + + Address + - - - - - - PID + + Netmask + - - - - - - Parent PID + + Protocol + - - - - - - VM size + + Broadcast + - - - +
-
- - No items found - -
-
+
+ + + + +
@@ -2118,139 +2934,298 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = `
`; -exports[`Inventory component A Linux agent should be well rendered. 1`] = ` +exports[`Inventory data Network Network interfaces table A Windows agent should render network interfaces table with correct columns and title. 1`] = `
+ +
+
+ + + Cores [object Object] +
+
+
+ +
+
+ + + Memory [object Object] +
+
+
+ +
+
+ + + Arch [object Object] +
+
+
+ +
+
+ + + Operating system [object Object] +
+
+
+ +
+
+ + + CPU [object Object] +
+
+
+ +
+
+ + + Host name [object Object] +
+
+
+ +
+
+ + + Board serial [object Object] +
+
+
+ +
+
+ + + Last scan [object Object] +
-
-
+
-

- Network interfaces - - (0) - -

-
-
-
-
-
-
- + Network interfaces + + (0) + + +
+
- -
-
-
-
-
-
-
-
-
-
-
+
-
- -
-
-
- +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + + WQL + + + +
+
-
-
-
-
-
+
-
-
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + - - - - + + + + + + +
+
+ + No items found + +
+
- + + + +
+
+
+
+
-
- - - - - - - - - - + +
+
+ +
+
+ + + + + + +
+
+
+
-
- - -
-
+
+
+

+ Network ports + + (0) + +

+
+
+ +
+
+
-
- - +
-
- - + + + + +
+
+
+
+
- -
+
- - No items found - -
-
-
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + Local port + + + + + + Local IP address + + + + + + + + +
+
+ + No items found + +
+
+
+
+
-
-
-

- Network ports - - (0) - -

+

+ Network settings + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
-
+
+
- - WQL + + WQL + - - + +
@@ -2803,214 +4167,238 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - + + - + - + - + - + - + + + + - - - - - - - - - -
-
- +
+
- - Local port - - - - + + Interface + + + + + - - Local IP address - - - - + + Address + + + + - - Process - - - - + + Netmask + + + + - - PID - - - - + - - State + + Broadcast + - - - +
-
- - No items found - -
-
+
+ + + + +
@@ -3018,572 +4406,10845 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = `
+
+`; + +exports[`Inventory data Network Network ports table A Apple agent should render network ports table with correct columns and title. 1`] = ` +
-
-
-
-

- Network settings - - (0) - -

-
-
-
- +
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

- Refresh - - - + Network interfaces + + (0) + +

+
+
- + + + + Refresh + + + +
+
+ +
+
-
-
-
-
-
+
-
+
-
- +
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
- - + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network ports + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + +
+
+ + + Local port + + + + + + Local IP address + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network settings + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[`Inventory data Network Network ports table A Linux agent should render network ports table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network interfaces + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network ports + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + +
+
+ + + Local port + + + + + + Local IP address + + + + + + Process + + + + + + PID + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network settings + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[`Inventory data Network Network ports table A Windows agent should render network ports table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network interfaces + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network ports + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + Local port + + + + + + Local IP address + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network settings + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[`Inventory data Network Network settings table A Apple agent should render network settings table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network interfaces + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network ports + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + +
+
+ + + Local port + + + + + + Local IP address + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network settings + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[`Inventory data Network Network settings table A Linux agent should render network settings table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network interfaces + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network ports + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + +
+
+ + + Local port + + + + + + Local IP address + + + + + + Process + + + + + + PID + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network settings + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[`Inventory data Network Network settings table A Windows agent should render network settings table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network interfaces + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network ports + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + Local port + + + + + + Local IP address + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Network settings + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[`Inventory data Processes A Apple agent should render processes table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Processes + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[`Inventory data Processes A Linux agent should render processes table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ Processes + + (0) + +

+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+ + No items found + +
+
+
+
+
+
+
+
+`; + +exports[`Inventory data Processes A Windows agent should render processes table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ class="euiText euiText--small euiStat__description" + > + +
+
+
+
+
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - - - - - -
-
- - - - - - - - - -
-
- - No items found - -
-
-
+
+
-
-
+
-

- Packages - - (0) - -

+

+ Processes + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
-
+
+
- - WQL + + WQL + - - + +
@@ -3591,239 +15252,288 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - + + + + + - + - + - + - + + + + - - - - - - - - - -
-
-
+
+ + + + + + - - Name + + VM size + - - - - - - - Architecture + + Priority + - - - - - - Version + + NLWP + - - - - - - Vendor + + Command + - - - +
-
- - No items found - -
-
+
+ + + + +
@@ -3831,167 +15541,450 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = `
+
+`; + +exports[`Inventory data Software Packages table A Apple agent should render software table with correct columns and title. 1`] = ` +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
-

- Processes - - (0) - -

+

+ Packages + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
+ +
+
- + +
@@ -3999,408 +15992,240 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - - - - - - - + + - + - + - + - + - + + + + - - - - - - - - - -
-
- - - - - - - - - - - - -
+
- - Argvs + + Name + + - - - - - - VM size + + Version + - - - - - - Size + + Format + - - - - - - Session + + Location + - - - - - - Priority + + Description + - - - +
-
- - No items found - -
-
+
+ + + + +
@@ -4411,283 +16236,447 @@ exports[`Inventory component A Linux agent should be well rendered. 1`] = `
`; -exports[`Inventory component A Windows agent should be well rendered. 1`] = ` +exports[`Inventory data Software Packages table A Linux agent should render software table with correct columns and title. 1`] = `
+ +
+
+ + + Cores [object Object] +
+
+
+ +
+
+ + + Memory [object Object] +
+
+
+ +
+
+ + + Arch [object Object] +
+
+
+ +
+
+ + + Operating system [object Object] +
+
+
+ +
+
+ + + CPU [object Object] +
+
+
+ +
+
+ + + Host name [object Object] +
+
+
+ +
+
+ + + Board serial [object Object] +
+
+
+ +
+
+ + + Last scan [object Object] +
-
-
+
-

- Network interfaces - - (0) - -

+

+ Packages + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
-
+
+
- - WQL + + WQL + - - + +
@@ -4695,401 +16684,692 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - + + - + - + - + - + - - - - - + + + -
- - No items found - -
- - - -
-
-
+
- - Name + + Name + + - - - - - - - MAC + + Architecture + - - - - - - State + + Version + - - - - - - MTU + + Vendor + - - - - - - Type + + Description + - - -
+ +
+ + No items found + +
+ + + + +
+
+
+`; + +exports[`Inventory data Software Packages table A Windows agent should render software table with correct columns and title. 1`] = ` +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
-

- Network ports - - (0) - -

+

+ Windows updates + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
-
+
+
- - WQL + + WQL + - - + +
@@ -5097,375 +17377,308 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - - - - + + - + + + + - - - - - - - - - -
-
- - - Local port - - - - - - Local IP address - - - - - -
+
- - State + + Update code + + - - - +
-
- - No items found - -
-
+
+ + + + +
-
-
-
-
-

- Network settings - - (0) - -

+

+ Packages + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
-
+
+
- - WQL + + WQL + - - + +
@@ -5473,1095 +17686,976 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - + + - + - + - + - + + + + - - - - - - - - - -
-
-
+
- - Interface + + Name + + - - - - - - - Address + + Architecture + - - - - - - Netmask + + Version + - - - - - - Protocol + + Vendor + - - - +
-
- - No items found - -
-
+
+ + + + +
+
+
+`; + +exports[`Inventory data Software Windows updates table A Windows agent should render software table with correct columns and title. 1`] = ` +
+
- -
+
+
+
+
+
+
+
+ Memory + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
- - - - - - - - - - - -
-
- -
-
- - No items found - -
-
-
+
+
-
-
+
-

- Packages - - (0) - -

+

+ Windows updates + + (0) + +

+
-
-
- -
-
- -
-
-
-
-
-
-
-
-
-
-
-
+
+
+ -
-
-
+ + + + Export formatted + + +
-
-
-
+
-
+
+
- - - Sorting + + WQL + - - -
-
-
-
-
-
- - - - - - + +
-
- - + + + + + + + + +
+
+
+
+
+
+
- -
- + + + + + + + + + + - + + + + - - - - - - - - - -
+
- - Version + + Update code + + - - - +
-
- - No items found - -
-
+ + +
+
-
-
-
-
-

- Processes - - (0) - -

+

+ Packages + + (0) + +

+
-
-
- -
-
- +
+
+ + +
-
-
-
-
+
+
-
-
-
- -
+
+
-
+
+
- - WQL + + WQL + - - + +
@@ -6569,287 +18663,216 @@ exports[`Inventory component A Windows agent should be well rendered. 1`] = `
-
-
-
-
-
+
+
+
-
+
- + +
-
- - - - - - + + - + - + - + - + + + + - - - - - - - - - -
-
- - - - -
+
- - Parent PID + + Name + + - - - - - - VM size + + Architecture + - - - - - - Priority + + Version + - - - - - - NLWP + + Vendor + - - - +
-
- - No items found - -
-
+
+ + + + +
diff --git a/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.tsx b/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.tsx index 862c4e2cbe..2fde2feae3 100644 --- a/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.tsx @@ -10,7 +10,7 @@ const sortFieldSuggestion = (a, b) => (a.label > b.label ? 1 : -1); export const NetworkInterfacesTable = ({ agent }) => { return ( - + (a.label > b.label ? 1 : -1); export const NetworkPortsTable = withSOPlatformGuard( ({ agent, soPlatform }) => { return ( - + (a.label > b.label ? 1 : -1); export const NetworkSettingsTable = ({ agent }) => { return ( - + (a.label > b.label ? 1 : -1); export const PackagesTable = withSOPlatformGuard(({ agent, soPlatform }) => { return ( - + (a.label > b.label ? 1 : -1); export const ProcessesTable = withSOPlatformGuard(({ agent, soPlatform }) => { return ( - + ({ + formatUIDate: jest.fn().mockReturnValue('2022-06-27T16:09:49+00:00'), +})); + +jest.mock('../../../common/hooks/useGenericRequest', () => ({ + useGenericRequest: jest.fn().mockReturnValue({ + isLoading: false, + data: { + hardware: { + cpu: { + name: 'Intel(R) Core(TM) i7-10710U CPU @ 1.10GHz', + cores: 4, + threads: 8, + }, + ram: { + total: '16.0 GB', + }, + }, + os: { + platform: 'windows', + version: '10.0.19045', + }, + }, + error: '', + }), +})); + +describe('Syscollector metrics', () => { + it('should render inventory metrics', () => { + const { container } = render(); + + const inventoryMetrics = container.querySelector( + queryDataTestAttr('syscollector-metrics'), + ); + + expect(inventoryMetrics).toBeTruthy(); + }); + + it('should render syscollector ribbon items', () => { + const { container } = render(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-cores')), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-memory')), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-arch')), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr('ribbon-item-operating-system'), + ), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-cpu')), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-hostname')), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-board-serial')), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr('ribbon-item-last-scan')), + ).toBeTruthy(); + + expect( + container.querySelectorAll( + queryDataTestAttr('ribbon-item-', CSS.Attribute.Substring), + ), + ).toHaveLength(8); + }); +}); diff --git a/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.tsx b/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.tsx index be0cf63f59..682e29585b 100644 --- a/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.tsx +++ b/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.tsx @@ -1,15 +1,13 @@ import React, { useState } from 'react'; -import { - EuiPanel, - EuiFlexGroup, - EuiFlexItem, - EuiText, - EuiLoadingSpinner, - EuiIcon, -} from '@elastic/eui'; -import mapValues from 'lodash'; +import { EuiPanel, EuiIcon } from '@elastic/eui'; +import _ from 'lodash'; import { useGenericRequest } from '../../../common/hooks/useGenericRequest'; import { formatUIDate } from '../../../../react-services/time-service'; +import WzRibbon from '../../../common/ribbon/ribbon'; +import { + IRibbonItem, + RibbonItemLabel, +} from '../../../common/ribbon/ribbon-item'; export function InventoryMetrics({ agent }) { const [params, setParams] = useState({}); @@ -31,8 +29,7 @@ export function InventoryMetrics({ agent }) { if ( !syscollector.isLoading && - (mapValues.isEmpty(syscollector.data.hardware) || - mapValues.isEmpty(syscollector.data.os)) + (_.isEmpty(syscollector.data.hardware) || _.isEmpty(syscollector.data.os)) ) { return ( @@ -42,106 +39,72 @@ export function InventoryMetrics({ agent }) { ); } - return ( - - - - - Cores:{' '} - {syscollector.isLoading ? ( - - ) : syscollector.data.hardware.cpu?.cores ? ( - {syscollector.data.hardware.cpu.cores} - ) : ( - - - )} - - - - - Memory:{' '} - {syscollector.isLoading ? ( - - ) : syscollector.data.hardware.ram?.total ? ( - - {(syscollector.data.hardware.ram.total / 1024).toFixed(2)} MB - - ) : ( - - - )} - - - - - Arch:{' '} - {syscollector.isLoading ? ( - - ) : ( - {syscollector.data.os.architecture} - )} - - - - - Operating system:{' '} - {syscollector.isLoading ? ( - - ) : ( - - {syscollector.data.os.os.name} {syscollector.data.os.os.version} - - )} - - - - - CPU:{' '} - {syscollector.isLoading ? ( - - ) : syscollector.data.hardware.cpu?.name ? ( - {syscollector.data.hardware.cpu.name} - ) : ( - - - )} - - - - - Host name:{' '} - {syscollector.isLoading ? ( - - ) : syscollector.data.os.hostname ? ( - {syscollector.data.os.hostname} - ) : ( - - - )} - - - - - Board serial:{' '} - {syscollector.isLoading ? ( - - ) : syscollector.data.hardware.board_serial ? ( - {syscollector.data.hardware.board_serial} - ) : ( - - - )} - - - - - Last scan:{' '} - {syscollector.isLoading ? ( - - ) : ( - - {offsetTimestamp('', syscollector.data.os.scan.time)} - - )} - - - - - ); + const render = () => { + const items: IRibbonItem[] = [ + { + key: 'cores', + label: 'Cores', + value: syscollector?.data?.hardware?.cpu?.cores, + isLoading: syscollector.isLoading, + style: { maxWidth: 100 }, + }, + { + key: 'memory', + label: 'Memory', + value: syscollector?.data?.hardware?.ram?.total + ? `${(syscollector?.data?.hardware?.ram?.total / 1024).toFixed(2)} MB` + : '-', + isLoading: syscollector.isLoading, + style: { maxWidth: 100 }, + }, + { + key: 'arch', + label: 'Arch', + value: syscollector?.data?.os?.architecture, + isLoading: syscollector.isLoading, + style: { maxWidth: 100 }, + }, + { + key: RibbonItemLabel.OPERATING_SYSTEM, + value: syscollector?.data?.os, + label: 'Operating system', + isLoading: syscollector.isLoading, + style: { maxWidth: 200 }, + }, + { + key: 'cpu', + label: 'CPU', + value: syscollector?.data?.hardware?.cpu?.name, + isLoading: syscollector.isLoading, + style: { maxWidth: 250 }, + }, + { + key: 'hostname', + label: 'Host name', + value: syscollector?.data?.os?.hostname, + isLoading: syscollector.isLoading, + style: { maxWidth: 100 }, + }, + { + key: 'board-serial', + label: 'Board serial', + value: syscollector?.data?.hardware?.board_serial, + isLoading: syscollector.isLoading, + style: { maxWidth: 100 }, + }, + { + key: 'last-scan', + label: 'Last scan', + value: syscollector?.data?.os?.scan?.time + ? offsetTimestamp('', syscollector?.data?.os?.scan?.time) + : '-', + isLoading: syscollector.isLoading, + style: { maxWidth: 180 }, + }, + ]; + + return ; + }; + + return render(); } diff --git a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.tsx b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.tsx index 65e3937cca..34410bc467 100644 --- a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.tsx @@ -10,7 +10,7 @@ const sortFieldSuggestion = (a, b) => (a.label > b.label ? 1 : -1); export const WindowsUpdatesTable = ({ agent }) => { return ( - + { - it('A Linux agent should be well rendered.', () => { - const agent = { - os: { - uname: - 'Linux |ip-10-0-1-106 |4.9.0-9-amd64 |1 SMP Debian 4.9.168-1+deb9u2 (2019-05-13) |x86_64', - }, - }; - const wrapper = render(); - const networkPortsCard = wrapper.find('.euiFlexItem--flexGrow2').last(); - const networkPortsTitle = networkPortsCard - .find('.euiTitle.euiTitle--small') - .text(); - const networkPortsColumns = networkPortsCard.find('th'); +const TABLE_ID = '__table_7d62db31-1cd0-11ee-8e0c-33242698a3b9'; +const SOFTWARE_PACKAGES = 'Packages'; +const SOFTWARE_WINDOWS_UPDATES = 'Windows updates'; +const NETWORK_PORTS = 'Network ports'; +const NETWORK_INTERFACES = 'Network interfaces'; +const NETWORK_SETTINGS = 'Network settings'; +const PROCESSES = 'Processes'; +const AGENT = { + DEBIAN: { + os: { + uname: + 'Linux |ip-10-0-1-106 |4.9.0-9-amd64 |1 SMP Debian 4.9.168-1+deb9u2 (2019-05-13) |x86_64', + }, + }, + WINDOWS: { + os: { + platform: 'windows', + }, + }, + DARWIN: { + os: { + platform: 'darwin', + }, + }, +} as const; + +const NETWORK_PORTS_COLUMNS = { + LOCAL_PORT: 'Local port', + LOCAL_IP: 'Local IP address', + PROCESS: 'Process', + PID: 'PID', + STATE: 'State', + PROTOCOL: 'Protocol', +} as const; + +const NETWORK_INTERFACES_COLUMNS = { + NAME: 'Name', + MAC: 'MAC', + STATE: 'State', + MTU: 'MTU', + TYPE: 'Type', +} as const; + +const NETWORK_SETTINGS_COLUMNS = { + INTERFACE: 'Interface', + ADDRESS: 'Address', + NETMASK: 'Netmask', + PROTOCOL: 'Protocol', + BROADCAST: 'Broadcast', +} as const; + +const SOFTWARE_PACKAGES_COLUMNS = { + NAME: 'Name', + ARCHITECTURE: 'Architecture', + VENDOR: 'Vendor', + VERSION: 'Version', + FORMAT: 'Format', + LOCATION: 'Location', + DESCRIPTION: 'Description', +} as const; + +const SOFTWARE_WINDOWS_UPDATES_COLUMNS = { + UPDATE_CODE: 'Update code', +} as const; + +const PROCESSES_COLUMNS = { + NAME: 'Name', + EFFECTIVE_USER: 'Effective user', + EFFECTIVE_GROUP: 'Effective group', + PID: 'PID', + PARENT_PID: 'Parent PID', + COMMAND: 'Command', + ARGVS: 'Argvs', + SIZE: 'Size', + VM_SIZE: 'VM size', + SESSION: 'Session', + PRIORITY: 'Priority', + STATE: 'State', + NLWP: 'NLWP', +} as const; + +const shouldRenderTableWithCorrectColumnsAndTitle = ( + dataTestId: string, + title: string, + agentTab: (typeof AgentTabs)[keyof typeof AgentTabs], + agent: (typeof AGENT)[keyof typeof AGENT], + columns: string[], +) => { + const wrapper = render( + , + ); + const visTable = wrapper.find(queryDataTestAttr(dataTestId)).first(); + const visTitle = visTable + .find(queryDataTestAttr('table-wz-api-title')) + .text(); + const visColumns = visTable.find( + queryDataTestAttr('table-with-search-bar') + ' .euiTableHeaderCell', + ); + + const visTables = wrapper.find('table'); + + for (let i = 0; i < visTables.length; i++) { // This is done because the ID of the tables changes at each execution and breaks the snapshot. + visTables[i]['attribs']['id'] = TABLE_ID; + } + + expect(wrapper).toMatchSnapshot(); + expect(visTitle.trim()).toContain(title); + expect(visColumns.length).toEqual(columns.length); + for (let i = 0; i < columns.length; i++) { + expect(visColumns.eq(i).text()).toContain(columns[i]); + } +}; +const shouldRenderNetworkPortsTableWithCorrectColumnsAndTitle = ( + agent: (typeof AGENT)[keyof typeof AGENT], + columns: string[], +) => { + shouldRenderTableWithCorrectColumnsAndTitle( + 'network-ports-table', + NETWORK_PORTS, + AgentTabs.NETWORK, + agent, + columns, + ); +}; + +const shouldRenderNetworkInterfacesTableWithCorrectColumnsAndTitle = ( + agent: (typeof AGENT)[keyof typeof AGENT], + columns: string[], +) => { + shouldRenderTableWithCorrectColumnsAndTitle( + 'network-interfaces-table', + NETWORK_INTERFACES, + AgentTabs.NETWORK, + agent, + columns, + ); +}; + +const shouldRenderNetworkSettingsTableWithCorrectColumnsAndTitle = ( + agent: (typeof AGENT)[keyof typeof AGENT], + columns: string[], +) => { + shouldRenderTableWithCorrectColumnsAndTitle( + 'network-settings-table', + NETWORK_SETTINGS, + AgentTabs.NETWORK, + agent, + columns, + ); +}; + +const shouldRenderSoftwarePackagesTableWithCorrectColumnsAndTitle = ( + agent: (typeof AGENT)[keyof typeof AGENT], + columns: string[], +) => { + shouldRenderTableWithCorrectColumnsAndTitle( + 'software-packages-table', + SOFTWARE_PACKAGES, + AgentTabs.SOFTWARE, + agent, + columns, + ); +}; + +const shouldRenderSoftwareWindowsUpdatesTableWithCorrectColumnsAndTitle = ( + agent: (typeof AGENT)[keyof typeof AGENT], + columns: string[], +) => { + shouldRenderTableWithCorrectColumnsAndTitle( + 'software-windows-updates-table', + SOFTWARE_WINDOWS_UPDATES, + AgentTabs.SOFTWARE, + agent, + columns, + ); +}; + +const shouldRenderProcessesTableWithCorrectColumnsAndTitle = ( + agent: (typeof AGENT)[keyof typeof AGENT], + columns: string[], +) => { + shouldRenderTableWithCorrectColumnsAndTitle( + 'processes-table', + PROCESSES, + AgentTabs.PROCESSES, + agent, + columns, + ); +}; + +function findAgentInfo(wrapper: cheerio.Cheerio): any { + return wrapper.find(queryDataTestAttr('agent-info')).html(); +} + +describe('Inventory data', () => { + describe('Agent info', () => { + it("A Linux agent shouldn't render agent info", () => { + let wrapper = render( + , + ); + + let agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + + wrapper = render( + , + ); + + agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + + wrapper = render( + , + ); + + agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + }); + + it("A Windows agent shouldn't render agent info", () => { + let wrapper = render( + , + ); + + let agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + + wrapper = render( + , + ); + + agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + + wrapper = render( + , + ); + + agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + }); - const tableId = '__table_7d62db31-1cd0-11ee-8e0c-33242698a3b9'; - - const tables = wrapper.find('table'); - - for (let i = 0; i < tables.length; i++) { - tables[i]['attribs']['id'] = tableId; - } - - const columns = [ - 'Local port', - 'Local IP address', - 'Process', - 'PID', - 'State', - 'Protocol', - ]; - - expect(wrapper).toMatchSnapshot(); - expect(networkPortsTitle.trim()).toContain('Network ports'); - expect(networkPortsColumns.length).toEqual(columns.length); - for (let i = 0; i < columns.length; i++) { - expect(networkPortsColumns.eq(i).text()).toContain(columns[i]); - } + it("A Apple agent shouldn't render agent info", () => { + let wrapper = render( + , + ); + + let agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + + wrapper = render( + , + ); + + agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + + wrapper = render( + , + ); + + agentInfo = findAgentInfo(wrapper); + + expect(agentInfo).toBeFalsy(); + }); }); - it('A Windows agent should be well rendered.', () => { - const agent = { - os: { - platform: 'windows', - }, - }; - const wrapper = render(); - const networkPortsCard = wrapper.find('.euiFlexItem--flexGrow2').last(); - const networkPortsTitle = networkPortsCard - .find('.euiTitle.euiTitle--small') - .text(); - const networkPortsColumns = networkPortsCard.find('th'); + describe('Software', () => { + it('should render inventory metrics', () => { + const wrapper = render( + , + ); - // This is done because the ID of the tables changes at each execution and breaks the snapshot. + const inventoryMetrics = wrapper.find( + queryDataTestAttr('syscollector-metrics'), + ); - const tableId = '__table_7d62db31-1cd0-11ee-8e0c-33242698a3b9'; + expect(inventoryMetrics).toBeTruthy(); + }); - const tables = wrapper.find('table'); + describe(SOFTWARE_PACKAGES + ' table', () => { + it('A Linux agent should render software table with correct columns and title.', () => { + const columns = [ + SOFTWARE_PACKAGES_COLUMNS.NAME, + SOFTWARE_PACKAGES_COLUMNS.ARCHITECTURE, + SOFTWARE_PACKAGES_COLUMNS.VERSION, + SOFTWARE_PACKAGES_COLUMNS.VENDOR, + SOFTWARE_PACKAGES_COLUMNS.DESCRIPTION, + ]; - for (let i = 0; i < tables.length; i++) { - tables[i]['attribs']['id'] = tableId; - } + shouldRenderSoftwarePackagesTableWithCorrectColumnsAndTitle( + AGENT.DEBIAN, + columns, + ); + }); + it('A Windows agent should render software table with correct columns and title.', () => { + const columns = [ + SOFTWARE_PACKAGES_COLUMNS.NAME, + SOFTWARE_PACKAGES_COLUMNS.ARCHITECTURE, + SOFTWARE_PACKAGES_COLUMNS.VERSION, + SOFTWARE_PACKAGES_COLUMNS.VENDOR, + ]; - const columns = [ - 'Local port', - 'Local IP address', - 'Process', - 'State', - 'Protocol', - ]; + shouldRenderSoftwarePackagesTableWithCorrectColumnsAndTitle( + AGENT.WINDOWS, + columns, + ); + }); + it('A Apple agent should render software table with correct columns and title.', () => { + const columns = [ + SOFTWARE_PACKAGES_COLUMNS.NAME, + SOFTWARE_PACKAGES_COLUMNS.VERSION, + SOFTWARE_PACKAGES_COLUMNS.FORMAT, + SOFTWARE_PACKAGES_COLUMNS.LOCATION, + SOFTWARE_PACKAGES_COLUMNS.DESCRIPTION, + ]; - expect(wrapper).toMatchSnapshot(); - expect(networkPortsTitle.trim()).toContain('Network ports'); - expect(networkPortsColumns.length).toEqual(columns.length); - for (let i = 0; i < columns.length; i++) { - expect(networkPortsColumns.eq(i).text()).toContain(columns[i]); - } + shouldRenderSoftwarePackagesTableWithCorrectColumnsAndTitle( + AGENT.DARWIN, + columns, + ); + }); + }); + + describe(SOFTWARE_WINDOWS_UPDATES + ' table', () => { + it('A Linux agent should render software table with correct columns and title.', () => { + const wrapper = render( + , + ); + const visTable = wrapper + .find(queryDataTestAttr('software-windows-updates-table]')) + .first() + .html(); + + expect(visTable).toBeFalsy(); + }); + + it('A Windows agent should render software table with correct columns and title.', () => { + const columns = [SOFTWARE_WINDOWS_UPDATES_COLUMNS.UPDATE_CODE]; + + shouldRenderSoftwareWindowsUpdatesTableWithCorrectColumnsAndTitle( + AGENT.WINDOWS, + columns, + ); + }); + + it('A Apple agent should render software table with correct columns and title.', () => { + const wrapper = render( + , + ); + const visTable = wrapper + .find(queryDataTestAttr('software-windows-updates-table')) + .first() + .html(); + + expect(visTable).toBeFalsy(); + }); + }); }); - it('A Apple agent should be well rendered.', () => { - const agent = { - os: { - platform: 'darwin', - }, - }; - const wrapper = render(); - const networkPortsCard = wrapper.find('.euiFlexItem--flexGrow2').last(); - const networkPortsTitle = networkPortsCard - .find('.euiTitle.euiTitle--small') - .text(); - const networkPortsColumns = networkPortsCard.find('th'); + describe('Network', () => { + it('should render inventory metrics', () => { + const wrapper = render( + , + ); - // This is done because the ID of the tables changes at each execution and breaks the snapshot. + const inventoryMetrics = wrapper.find( + queryDataTestAttr('syscollector-metrics'), + ); + + expect(inventoryMetrics).toBeTruthy(); + }); + + describe(NETWORK_SETTINGS + ' table', () => { + it('A Linux agent should render network settings table with correct columns and title.', () => { + const columns = [ + NETWORK_SETTINGS_COLUMNS.INTERFACE, + NETWORK_SETTINGS_COLUMNS.ADDRESS, + NETWORK_SETTINGS_COLUMNS.NETMASK, + NETWORK_SETTINGS_COLUMNS.PROTOCOL, + NETWORK_SETTINGS_COLUMNS.BROADCAST, + ]; + + shouldRenderNetworkSettingsTableWithCorrectColumnsAndTitle( + AGENT.DEBIAN, + columns, + ); + }); + it('A Windows agent should render network settings table with correct columns and title.', () => { + const columns = [ + NETWORK_SETTINGS_COLUMNS.INTERFACE, + NETWORK_SETTINGS_COLUMNS.ADDRESS, + NETWORK_SETTINGS_COLUMNS.NETMASK, + NETWORK_SETTINGS_COLUMNS.PROTOCOL, + NETWORK_SETTINGS_COLUMNS.BROADCAST, + ]; + + shouldRenderNetworkSettingsTableWithCorrectColumnsAndTitle( + AGENT.WINDOWS, + columns, + ); + }); + it('A Apple agent should render network settings table with correct columns and title.', () => { + const columns = [ + NETWORK_SETTINGS_COLUMNS.INTERFACE, + NETWORK_SETTINGS_COLUMNS.ADDRESS, + NETWORK_SETTINGS_COLUMNS.NETMASK, + NETWORK_SETTINGS_COLUMNS.PROTOCOL, + NETWORK_SETTINGS_COLUMNS.BROADCAST, + ]; + + shouldRenderNetworkSettingsTableWithCorrectColumnsAndTitle( + AGENT.DARWIN, + columns, + ); + }); + }); + describe(NETWORK_INTERFACES + ' table', () => { + it('A Linux agent should render network interfaces table with correct columns and title.', () => { + const columns = [ + NETWORK_INTERFACES_COLUMNS.NAME, + NETWORK_INTERFACES_COLUMNS.MAC, + NETWORK_INTERFACES_COLUMNS.STATE, + NETWORK_INTERFACES_COLUMNS.MTU, + NETWORK_INTERFACES_COLUMNS.TYPE, + ]; + + shouldRenderNetworkInterfacesTableWithCorrectColumnsAndTitle( + AGENT.DEBIAN, + columns, + ); + }); + it('A Windows agent should render network interfaces table with correct columns and title.', () => { + const columns = [ + NETWORK_INTERFACES_COLUMNS.NAME, + NETWORK_INTERFACES_COLUMNS.MAC, + NETWORK_INTERFACES_COLUMNS.STATE, + NETWORK_INTERFACES_COLUMNS.MTU, + NETWORK_INTERFACES_COLUMNS.TYPE, + ]; + + shouldRenderNetworkInterfacesTableWithCorrectColumnsAndTitle( + AGENT.WINDOWS, + columns, + ); + }); + it('A Apple agent should render network interfaces table with correct columns and title.', () => { + const columns = [ + NETWORK_INTERFACES_COLUMNS.NAME, + NETWORK_INTERFACES_COLUMNS.MAC, + NETWORK_INTERFACES_COLUMNS.STATE, + NETWORK_INTERFACES_COLUMNS.MTU, + NETWORK_INTERFACES_COLUMNS.TYPE, + ]; + + shouldRenderNetworkInterfacesTableWithCorrectColumnsAndTitle( + AGENT.DARWIN, + columns, + ); + }); + }); + describe(NETWORK_PORTS + ' table', () => { + it('A Linux agent should render network ports table with correct columns and title.', () => { + const columns = [ + NETWORK_PORTS_COLUMNS.LOCAL_PORT, + NETWORK_PORTS_COLUMNS.LOCAL_IP, + NETWORK_PORTS_COLUMNS.PROCESS, + NETWORK_PORTS_COLUMNS.PID, + NETWORK_PORTS_COLUMNS.STATE, + NETWORK_PORTS_COLUMNS.PROTOCOL, + ]; + + shouldRenderNetworkPortsTableWithCorrectColumnsAndTitle( + AGENT.DEBIAN, + columns, + ); + }); + + it('A Windows agent should render network ports table with correct columns and title.', () => { + const columns = [ + NETWORK_PORTS_COLUMNS.LOCAL_PORT, + NETWORK_PORTS_COLUMNS.LOCAL_IP, + NETWORK_PORTS_COLUMNS.PROCESS, + NETWORK_PORTS_COLUMNS.STATE, + NETWORK_PORTS_COLUMNS.PROTOCOL, + ]; + shouldRenderNetworkPortsTableWithCorrectColumnsAndTitle( + AGENT.WINDOWS, + columns, + ); + }); + + it('A Apple agent should render network ports table with correct columns and title.', () => { + const columns = [ + NETWORK_PORTS_COLUMNS.LOCAL_PORT, + NETWORK_PORTS_COLUMNS.LOCAL_IP, + NETWORK_PORTS_COLUMNS.STATE, + NETWORK_PORTS_COLUMNS.PROTOCOL, + ]; + + shouldRenderNetworkPortsTableWithCorrectColumnsAndTitle( + AGENT.DARWIN, + columns, + ); + }); + }); + }); + + describe('Processes', () => { + it('should render inventory metrics', () => { + const wrapper = render( + , + ); + + const inventoryMetrics = wrapper.find( + queryDataTestAttr('syscollector-metrics'), + ); + + expect(inventoryMetrics).toBeTruthy(); + }); + + it('A Linux agent should render processes table with correct columns and title.', () => { + const columns = [ + PROCESSES_COLUMNS.NAME, + PROCESSES_COLUMNS.EFFECTIVE_USER, + PROCESSES_COLUMNS.EFFECTIVE_GROUP, + PROCESSES_COLUMNS.PID, + PROCESSES_COLUMNS.PARENT_PID, + PROCESSES_COLUMNS.COMMAND, + PROCESSES_COLUMNS.ARGVS, + PROCESSES_COLUMNS.VM_SIZE, + PROCESSES_COLUMNS.SIZE, + PROCESSES_COLUMNS.SESSION, + PROCESSES_COLUMNS.PRIORITY, + PROCESSES_COLUMNS.STATE, + ]; - const tableId = '__table_7d62db31-1cd0-11ee-8e0c-33242698a3b9'; + shouldRenderProcessesTableWithCorrectColumnsAndTitle( + AGENT.DEBIAN, + columns, + ); + }); - const tables = wrapper.find('table'); + it('A Windows agent should render processes table with correct columns and title.', () => { + const columns = [ + PROCESSES_COLUMNS.NAME, + PROCESSES_COLUMNS.PID, + PROCESSES_COLUMNS.PARENT_PID, + PROCESSES_COLUMNS.VM_SIZE, + PROCESSES_COLUMNS.PRIORITY, + PROCESSES_COLUMNS.NLWP, + PROCESSES_COLUMNS.COMMAND, + ]; - for (let i = 0; i < tables.length; i++) { - tables[i]['attribs']['id'] = tableId; - } + shouldRenderProcessesTableWithCorrectColumnsAndTitle( + AGENT.WINDOWS, + columns, + ); + }); - const columns = ['Local port', 'Local IP address', 'State', 'Protocol']; + it('A Apple agent should render processes table with correct columns and title.', () => { + const columns = [ + PROCESSES_COLUMNS.NAME, + PROCESSES_COLUMNS.EFFECTIVE_USER, + PROCESSES_COLUMNS.PID, + PROCESSES_COLUMNS.PARENT_PID, + PROCESSES_COLUMNS.VM_SIZE, + PROCESSES_COLUMNS.PRIORITY, + ]; - expect(wrapper).toMatchSnapshot(); - expect(networkPortsTitle.trim()).toContain('Network ports'); - expect(networkPortsColumns.length).toEqual(columns.length); - for (let i = 0; i < columns.length; i++) { - expect(networkPortsColumns.eq(i).text()).toContain(columns[i]); - } + shouldRenderProcessesTableWithCorrectColumnsAndTitle( + AGENT.DARWIN, + columns, + ); + }); }); }); diff --git a/plugins/main/public/components/agents/syscollector/inventory.tsx b/plugins/main/public/components/agents/syscollector/inventory.tsx index 8f5e2413c7..417db55c4c 100644 --- a/plugins/main/public/components/agents/syscollector/inventory.tsx +++ b/plugins/main/public/components/agents/syscollector/inventory.tsx @@ -11,20 +11,22 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiCallOut } from '@elastic/eui'; -import { InventoryMetrics } from './components/syscollector-metrics'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiCallOut, + EuiSpacer, + EuiPage, + EuiPageBody, +} from '@elastic/eui'; import { API_NAME_AGENT_STATUS } from '../../../../common/constants'; import { compose } from 'redux'; import { withGuard } from '../../common/hocs'; import { PromptAgentNeverConnected } from '../prompts'; -import { - NetworkInterfacesTable, - NetworkPortsTable, - NetworkSettingsTable, - WindowsUpdatesTable, - ProcessesTable, - PackagesTable, -} from './components'; +import SoftwareTab from './software'; +import NetworkTab from './network'; +import ProcessesTab from './processes'; +import { InventoryMetrics } from './components'; export const SyscollectorInventory = compose( withGuard( @@ -33,7 +35,8 @@ export const SyscollectorInventory = compose( props.agent.status === API_NAME_AGENT_STATUS.NEVER_CONNECTED, PromptAgentNeverConnected, ), -)(function SyscollectorInventory({ agent }) { +)(function SyscollectorInventory(props) { + const { agent, section } = props; let soPlatform; if (agent?.os?.uname?.includes('Linux')) { soPlatform = 'linux'; @@ -48,54 +51,33 @@ export const SyscollectorInventory = compose( } return ( -
- {agent && agent.status === API_NAME_AGENT_STATUS.DISCONNECTED && ( - - - - - - )} - - - - - - - - - - - - - - - - - - - - {agent && agent.os && agent.os.platform === 'windows' && ( - - - + + + {agent?.status === API_NAME_AGENT_STATUS.DISCONNECTED && ( + + + + + )} - - - - - - + - - - - - -
+ + + {section === 'software' && ( + + )} + {section === 'network' && ( + + )} + {section === 'processes' && ( + + )} + + ); }); diff --git a/plugins/main/public/components/agents/syscollector/network.tsx b/plugins/main/public/components/agents/syscollector/network.tsx new file mode 100644 index 0000000000..db99e84f00 --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/network.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { + NetworkInterfacesTable, + NetworkPortsTable, + NetworkSettingsTable, +} from './components'; +import { Agent } from '../../endpoints-summary/types'; + +interface NetworkProps { + agent: Agent; + soPlatform?: string; +} + +const NetworkTab = ({ agent, soPlatform }: NetworkProps) => { + return ( + + + + + + + + + + + + + + ); +}; + +export default NetworkTab; diff --git a/plugins/main/public/components/agents/syscollector/processes.tsx b/plugins/main/public/components/agents/syscollector/processes.tsx new file mode 100644 index 0000000000..8403be456c --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/processes.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { ProcessesTable } from './components'; +import { Agent } from '../../endpoints-summary/types'; + +interface ProcessesProps { + agent: Agent; + soPlatform?: string; +} + +const ProcessesTab = ({ agent, soPlatform }: ProcessesProps) => { + return ( + + + + + + ); +}; + +export default ProcessesTab; diff --git a/plugins/main/public/components/agents/syscollector/software.tsx b/plugins/main/public/components/agents/syscollector/software.tsx new file mode 100644 index 0000000000..a8c8f1db27 --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/software.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import { Agent } from '../../endpoints-summary/types'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { PackagesTable, WindowsUpdatesTable } from './components'; + +interface SoftwareProps { + agent: Agent; + soPlatform?: string; +} + +const SoftwareTab = ({ agent, soPlatform }: SoftwareProps) => { + return ( + + {agent?.os?.platform === 'windows' && ( + + + + )} + + + + + ); +}; + +export default SoftwareTab; diff --git a/plugins/main/public/components/common/hooks/use_async_action.ts b/plugins/main/public/components/common/hooks/use_async_action.ts index 24ab181926..a98495fa9c 100644 --- a/plugins/main/public/components/common/hooks/use_async_action.ts +++ b/plugins/main/public/components/common/hooks/use_async_action.ts @@ -11,24 +11,27 @@ */ import { useCallback, useState } from 'react'; -export function useAsyncAction(action, dependencies = []){ +export function useAsyncAction( + action: (...params: any[]) => any, + dependencies: any[] = [], +) { const [running, setRunning] = useState(false); const [data, setData] = useState(null); const [error, setError] = useState(null); const run = useCallback(async (...params) => { - try{ + try { setRunning(true); setError(null); setData(null); const data = await action(...params); setData(data); - }catch(error){ + } catch (error) { setError(error); - }finally{ + } finally { setRunning(false); - }; + } }, dependencies); return { data, error, running, run }; -} \ No newline at end of file +} diff --git a/plugins/main/public/components/common/modules/main-agent.test.tsx b/plugins/main/public/components/common/modules/main-agent.test.tsx new file mode 100644 index 0000000000..02ba68cd67 --- /dev/null +++ b/plugins/main/public/components/common/modules/main-agent.test.tsx @@ -0,0 +1,359 @@ +import React from 'react'; +import { MainModuleAgent } from './main-agent'; +import { AgentTabs } from '../../endpoints-summary/agent/agent-tabs'; +import { fireEvent, render } from '@testing-library/react'; +import { queryDataTestAttr } from '../../../../test/public/query-attr'; + +const GENERATE_REPORT_BUTTON = 'generate-report-button'; +const ARIA_SELECTED = '[aria-selected="true"]'; + +const REPORT_TAB = { + STATS: 'agent-tab-stats', + CONFIGURATION: 'agent-tab-configuration', + SOFTWARE: 'agent-tab-software', + NETWORK: 'agent-tab-network', + PROCESSES: 'agent-tab-processes', +}; + +jest.mock('../../../react-services/reporting', () => ({ + ReportingService: { + startVis2Png: jest.fn(), + startConfigReport: jest.fn(), + }, +})); + +jest.mock('../data-source', () => ({ + useDataSource: jest.fn().mockImplementation(() => ({ + dataSource: {}, + fetchFilters: {}, + isLoading: false, + })), + AlertsDataSourceRepository: jest.fn(), + AlertsDataSource: jest.fn(), + __esModule: true, +})); + +describe('Main Agent', () => { + let switchTab: jest.Mock; + + beforeEach(() => { + switchTab = jest.fn(); + }); + + describe('Agent tabs', () => { + it('should render agent tab overview when section is stats', () => { + const { container } = render( + , + ); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.STATS) + ARIA_SELECTED, + ), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.CONFIGURATION)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.SOFTWARE)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.NETWORK)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.PROCESSES)), + ).toBeFalsy(); + }); + + it('should render agent tab overview when section is configuration', () => { + const { container } = render( + , + ); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.CONFIGURATION) + ARIA_SELECTED, + ), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.STATS)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.SOFTWARE)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.NETWORK)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.PROCESSES)), + ).toBeFalsy(); + }); + + it('should render agent tab overview when section is software', () => { + const { container } = render( + , + ); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.SOFTWARE) + ARIA_SELECTED, + ), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.NETWORK)), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.NETWORK) + ARIA_SELECTED, + ), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.PROCESSES)), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.PROCESSES) + ARIA_SELECTED, + ), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.CONFIGURATION)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.STATS)), + ).toBeFalsy(); + }); + + it('should render agent tab overview when section is network', () => { + const { container } = render( + , + ); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.SOFTWARE)), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.SOFTWARE) + ARIA_SELECTED, + ), + ).toBeFalsy(); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.NETWORK) + ARIA_SELECTED, + ), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.PROCESSES)), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.PROCESSES) + ARIA_SELECTED, + ), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.CONFIGURATION)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.STATS)), + ).toBeFalsy(); + }); + + it('should render agent tab overview when section is processes', () => { + const { container } = render( + , + ); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.SOFTWARE)), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.SOFTWARE) + ARIA_SELECTED, + ), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.NETWORK)), + ).toBeTruthy(); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.NETWORK) + ARIA_SELECTED, + ), + ).toBeFalsy(); + + expect( + container.querySelector( + queryDataTestAttr(REPORT_TAB.PROCESSES) + ARIA_SELECTED, + ), + ).toBeTruthy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.CONFIGURATION)), + ).toBeFalsy(); + + expect( + container.querySelector(queryDataTestAttr(REPORT_TAB.STATS)), + ).toBeFalsy(); + }); + + it('should be call switchTab when click on tab', () => { + const { container } = render( + , + ); + + fireEvent.click( + container.querySelector( + queryDataTestAttr(REPORT_TAB.SOFTWARE), + ) as Element, + ); + + expect(switchTab).toHaveBeenCalledTimes(1); + expect(switchTab).toHaveBeenCalledWith(AgentTabs.SOFTWARE); + + fireEvent.click( + container.querySelector( + queryDataTestAttr(REPORT_TAB.NETWORK), + ) as Element, + ); + + expect(switchTab).toHaveBeenCalledTimes(2); + expect(switchTab).toHaveBeenCalledWith(AgentTabs.NETWORK); + + fireEvent.click( + container.querySelector( + queryDataTestAttr(REPORT_TAB.PROCESSES), + ) as Element, + ); + + expect(switchTab).toHaveBeenCalledTimes(3); + expect(switchTab).toHaveBeenCalledWith(AgentTabs.PROCESSES); + }); + }); + + describe('Generate report button', () => { + it("shouldn't render generate report button when section is stats", () => { + const { container } = render( + , + ); + + const generateReportButton = container.querySelector( + queryDataTestAttr(GENERATE_REPORT_BUTTON), + ); + + expect(generateReportButton).toBeFalsy(); + }); + + it("shouldn't render generate report button when section is configuration", () => { + const { container } = render( + , + ); + + const generateReportButton = container.querySelector( + queryDataTestAttr(GENERATE_REPORT_BUTTON), + ); + + expect(generateReportButton).toBeFalsy(); + }); + + it('should render generate report button when section is software', () => { + const { container } = render( + , + ); + + const generateReportButton = container.querySelector( + queryDataTestAttr(GENERATE_REPORT_BUTTON), + ); + + expect(generateReportButton).toBeTruthy(); + }); + + it('should render generate report button when section is network', () => { + const { container } = render( + , + ); + + const generateReportButton = container.querySelector( + queryDataTestAttr(GENERATE_REPORT_BUTTON), + ); + + expect(generateReportButton).toBeTruthy(); + }); + + it('should render generate report button when section is processes', () => { + const { container } = render( + , + ); + + const generateReportButton = container.querySelector( + queryDataTestAttr(GENERATE_REPORT_BUTTON), + ); + + expect(generateReportButton).toBeTruthy(); + }); + }); +}); diff --git a/plugins/main/public/components/common/modules/main-agent.tsx b/plugins/main/public/components/common/modules/main-agent.tsx index b7d477038f..74ebf831e0 100644 --- a/plugins/main/public/components/common/modules/main-agent.tsx +++ b/plugins/main/public/components/common/modules/main-agent.tsx @@ -14,20 +14,13 @@ import React, { Component, Fragment } from 'react'; import { EuiFlexGroup, EuiFlexItem, - EuiTitle, EuiButtonEmpty, + EuiTabs, + EuiTab, } from '@elastic/eui'; -import { euiThemeVars } from '@osd/ui-shared-deps/theme'; import '../../common/modules/module.scss'; import store from '../../../redux/store'; -import { FilterHandler } from '../../../utils/filter-handler'; -import { AppState } from '../../../react-services/app-state'; import { ReportingService } from '../../../react-services/reporting'; -import { WAZUH_MODULES } from '../../../../common/wazuh-modules'; -import { AgentInfo } from '../../common/welcome/agents-info'; -import { compose } from 'redux'; -import { withGlobalBreadcrumb } from '../hocs'; -import { endpointSummary } from '../../../utils/applications'; import { AlertsDataSource, AlertsDataSourceRepository, @@ -37,140 +30,103 @@ import { useDataSource, } from '../data-source'; import { useAsyncAction } from '../hooks'; -import NavigationService from '../../../react-services/navigation-service'; +import { toTitleCase } from '../util/change-case'; +import clsx from 'clsx'; +import { AgentTabs } from '../../endpoints-summary/agent/agent-tabs'; +import { Agent } from '../../endpoints-summary/types'; export class MainModuleAgent extends Component { props!: { - [key: string]: any; + agent: Agent; + section: string; + switchTab?: (tab: string) => void; + selectView?: boolean; + tabs?: any[]; + renderTabs?: () => JSX.Element; + agentsSelectionProps?: any; }; - state: { - selectView: Boolean; - loadingReport: Boolean; - switchModule: Boolean; - showAgentInfo: Boolean; - }; - reportingService: ReportingService; - filterHandler: FilterHandler; - constructor(props) { - super(props); - this.reportingService = new ReportingService(); - this.filterHandler = new FilterHandler(AppState.getCurrentPattern()); - this.state = { - selectView: false, - loadingReport: false, - switchModule: false, - showAgentInfo: false, - }; - } + inventoryTabs = [AgentTabs.SOFTWARE, AgentTabs.NETWORK, AgentTabs.PROCESSES]; renderTitle() { + const { agent, section, switchTab } = this.props; return ( - - - - - - -

- { - NavigationService.getInstance().navigate( - `/agents?tab=welcome&agent=${this.props.agent.id}`, - ); - }} - > - -  {this.props.agent.name}    - - -

-
-
-
- - {this.props.section === 'syscollector' && ( - - - + + + + {this.inventoryTabs.includes(section) ? ( + <> + {this.inventoryTabs.map(tab => ( + switchTab?.(tab)} + > + {toTitleCase(tab)} + + ))} + + ) : ( + + {toTitleCase(section)} + )} - + + + {[AgentTabs.SOFTWARE, AgentTabs.NETWORK, AgentTabs.PROCESSES].includes( + section, + ) && ( + + + + )}
); } render() { const { agent, section, selectView } = this.props; - const ModuleTabView = (this.props.tabs || []).find( - tab => tab.id === selectView, - ); + const ModuleTabView = this.props.tabs?.find(tab => tab.id === selectView); + + const hasTabs = this.props.tabs?.length; + return ( -
- {agent && agent.os && ( +
+ {agent?.os && (
{this.renderTitle()}
-
- {this.state.showAgentInfo && ( -
- -
- )} - {this.props.tabs && this.props.tabs.length && ( +
+ {hasTabs && (
- {this.props.renderTabs()} + {this.props.renderTabs?.()} - {ModuleTabView && - ModuleTabView.buttons && - ModuleTabView.buttons.map( - (ModuleViewButton, index) => - typeof ModuleViewButton !== 'string' ? ( - - - - ) : null, - )} + {ModuleTabView?.buttons?.map( + (ModuleViewButton, index) => + typeof ModuleViewButton !== 'string' ? ( + + + + ) : null, + )} @@ -178,9 +134,8 @@ export class MainModuleAgent extends Component { )}
- {!['syscollector', 'configuration'].includes(section) && - ModuleTabView && - ModuleTabView.component && ( + {[AgentTabs.STATS].includes(section) && + ModuleTabView?.component && ( )} @@ -190,41 +145,6 @@ export class MainModuleAgent extends Component { } } -export default compose( - withGlobalBreadcrumb(({ agent, section }) => { - if (section === 'welcome') { - return [ - { - text: endpointSummary.breadcrumbLabel, - href: NavigationService.getInstance().getUrlForApp( - endpointSummary.id, - { - path: `#/agents-preview`, - }, - ), - }, - { text: agent.id }, - ]; - } else { - return [ - { - text: endpointSummary.breadcrumbLabel, - href: NavigationService.getInstance().getUrlForApp( - endpointSummary.id, - { - path: `#/agents-preview`, - }, - ), - }, - { agent: agent }, - { - text: WAZUH_MODULES[section].title, - }, - ]; - } - }), -)(MainModuleAgent); - export class AgentInventoryDataSource extends AlertsDataSource { constructor(id: string, title: string) { super(id, title); @@ -238,7 +158,7 @@ export class AgentInventoryDataSource extends AlertsDataSource { } } -const GenerateSyscollectorReportButton = ({ agent }) => { +const GenerateReportButton = ({ agent }: { agent: Agent }) => { const { dataSource, fetchFilters, @@ -254,7 +174,7 @@ const GenerateSyscollectorReportButton = ({ agent }) => { (agent || store.getState().appStateReducers.currentAgentData || {}).id || false; await reportingService.startVis2Png('syscollector', agentID, { - indexPattern: dataSource.indexPattern, + indexPattern: dataSource?.indexPattern, query: { query: '', language: 'kuery' }, filters: fetchFilters, time: { @@ -266,6 +186,7 @@ const GenerateSyscollectorReportButton = ({ agent }) => { return ( {ModuleTabView && diff --git a/plugins/main/public/components/common/modules/module.scss b/plugins/main/public/components/common/modules/module.scss index 8182b3d601..dbbd4491f1 100644 --- a/plugins/main/public/components/common/modules/module.scss +++ b/plugins/main/public/components/common/modules/module.scss @@ -7,14 +7,9 @@ background: #fafbfd; } -.wz-module-header-agent { - height: 50px; - padding: 16px; -} - -.wz-module-header-agent .euiHealth svg { - width: 16px; - height: 24px; +.wz-module-header-agent .euiTab__content { + font-size: 16px !important; + font-weight: 400; } .wzApp .euiFlyoutBody .euiFlyoutBody__overflowContent { @@ -25,6 +20,10 @@ margin-top: -16px; } +.wz-module-header-agent > .euiFlexGroup { + margin-top: -6px; +} + .wz-module-header-nav > .euiFlexGroup .euiFlexItem { margin-top: 0px; } @@ -39,20 +38,9 @@ border-radius: 100px; } -.wz-module-header-agent-title-btn { - cursor: pointer; -} - .wz-font-weight-normal { font-weight: normal; } -.wz-module-header-agent h1 { - font-weight: 400; -} - -.wz-module-header-agent h1 b { - font-weight: 500; -} .wz-module-header-nav .euiTabs { padding-top: 6px; @@ -96,11 +84,6 @@ discover-app-w .sidebar-container { @media only screen and (max-width: 767px) { .wz-module-header-agent { height: auto; - h1 { - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - } } .wz-module-body { margin-top: -160px; diff --git a/plugins/main/public/components/common/modules/modules-defaults.tsx b/plugins/main/public/components/common/modules/modules-defaults.tsx index 0fc4b4b5bc..215c3dd14f 100644 --- a/plugins/main/public/components/common/modules/modules-defaults.tsx +++ b/plugins/main/public/components/common/modules/modules-defaults.tsx @@ -444,7 +444,13 @@ export const ModulesDefaults = { ], availableFor: ['manager', 'agent'], }, - syscollector: { + software: { + notModule: true, + }, + network: { + notModule: true, + }, + processes: { notModule: true, }, configuration: { diff --git a/plugins/main/public/components/common/ribbon/ribbon-item.scss b/plugins/main/public/components/common/ribbon/ribbon-item.scss new file mode 100644 index 0000000000..bf543a6a40 --- /dev/null +++ b/plugins/main/public/components/common/ribbon/ribbon-item.scss @@ -0,0 +1,4 @@ +.wz-ribbon-item .euiStat .euiText { + font-size: 12px; + font-family: sans-serif; +} diff --git a/plugins/main/public/components/common/ribbon/ribbon-item.tsx b/plugins/main/public/components/common/ribbon/ribbon-item.tsx new file mode 100644 index 0000000000..29741c8a6b --- /dev/null +++ b/plugins/main/public/components/common/ribbon/ribbon-item.tsx @@ -0,0 +1,148 @@ +import { EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; +import React from 'react'; +import { WAZUH_AGENTS_OS_TYPE } from '../../../../common/constants'; +import { AgentStatus } from '../../agents/agent-status'; +import { Agent } from '../../endpoints-summary/types'; +import { WzStat } from '../../wz-stat'; +import { GroupTruncate } from '../util/agent-group-truncate'; +import WzTextWithTooltipIfTruncated from '../wz-text-with-tooltip-if-truncated'; +import './ribbon-item.scss'; +import { getAgentOSType } from '../../../react-services'; + +const FONT_SIZE = 12; + +export enum RibbonItemLabel { + GROUPS = 'groups', + OPERATING_SYSTEM = 'operating-system', + AGENT_STATUS = 'agent-status', +} + +export type IRibbonItem