diff --git a/CHANGELOG.md b/CHANGELOG.md index e235a66453..2f5e5155d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ All notable changes to the Wazuh app project will be documented in this file. - Changed the query to search for an agent in `management/configuration`. [#5485](https://github.com/wazuh/wazuh-kibana-app/pull/5485) - Changed the search bar in management/log to the one used in the rest of the app. [#5476](https://github.com/wazuh/wazuh-kibana-app/pull/5476) - Changed the design of the wizard to add agents. [#5457](https://github.com/wazuh/wazuh-kibana-app/pull/5457) -- Changed the search bar in Management (Rules, Decoders, CDB List, Groups) and Modules (Vulnerabilities > Inventory, Security Configuration Assessment > Inventory > {Policy ID} > Checks, MITRE ATT&CK > Intelligence > {Resource}, Integrity monitoring > Inventory > Files, Integrity monitoring > Inventory > Registry), Agent Inventory data, Explore agent modal [#5363](https://github.com/wazuh/wazuh-kibana-app/pull/5363) [#5442](https://github.com/wazuh/wazuh-kibana-app/pull/5442) [#5443](https://github.com/wazuh/wazuh-kibana-app/pull/5443) [#5444](https://github.com/wazuh/wazuh-kibana-app/pull/5444) [#5445](https://github.com/wazuh/wazuh-kibana-app/pull/5445) [#5447](https://github.com/wazuh/wazuh-kibana-app/pull/5447) +- Changed the search bar in Management (Rules, Decoders, CDB List, Groups) and Modules (Vulnerabilities > Inventory, Security Configuration Assessment > Inventory > {Policy ID} > Checks, MITRE ATT&CK > Intelligence > {Resource}, Integrity monitoring > Inventory > Files, Integrity monitoring > Inventory > Registry), Agent Inventory data, Explore agent modal, Agents [#5363](https://github.com/wazuh/wazuh-kibana-app/pull/5363) [#5442](https://github.com/wazuh/wazuh-kibana-app/pull/5442) [#5443](https://github.com/wazuh/wazuh-kibana-app/pull/5443) [#5444](https://github.com/wazuh/wazuh-kibana-app/pull/5444) [#5445](https://github.com/wazuh/wazuh-kibana-app/pull/5445) [#5447](https://github.com/wazuh/wazuh-kibana-app/pull/5447) [#5452](https://github.com/wazuh/wazuh-kibana-app/pull/5452) ### Fixed diff --git a/plugins/main/public/controllers/agent/components/agents-preview.js b/plugins/main/public/controllers/agent/components/agents-preview.js index 31ed799603..ef052c0745 100644 --- a/plugins/main/public/controllers/agent/components/agents-preview.js +++ b/plugins/main/public/controllers/agent/components/agents-preview.js @@ -197,7 +197,7 @@ export const AgentsPreview = compose( } removeFilters() { - this._isMount && this.setState({ agentTableFilters: [] }); + this._isMount && this.setState({ agentTableFilters: {} }); } showAgent(agent) { @@ -207,7 +207,7 @@ export const AgentsPreview = compose( filterAgentByStatus(status) { this._isMount && this.setState({ - agentTableFilters: [{ field: 'q', value: `status=${status}` }], + agentTableFilters: { q: `id!=000;status=${status}` }, }); } onRenderComplete() { diff --git a/plugins/main/public/controllers/agent/components/agents-table.js b/plugins/main/public/controllers/agent/components/agents-table.js index 09141ac9d6..853af6a40c 100644 --- a/plugins/main/public/controllers/agent/components/agents-table.js +++ b/plugins/main/public/controllers/agent/components/agents-table.js @@ -14,41 +14,37 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { - EuiBasicTable, EuiButton, - EuiButtonEmpty, EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiToolTip, - EuiTitle, - EuiSpacer, - EuiCallOut, - EuiCheckboxGroup, - EuiIcon, + EuiIconTip, } from '@elastic/eui'; -import { getToasts } from '../../../kibana-services'; import { AppNavigate } from '../../../react-services/app-navigate'; import { GroupTruncate } from '../../../components/common/util'; -import { - WzSearchBar, - filtersToObject, -} from '../../../components/wz-search-bar'; -import { getAgentFilterValues } from '../../../controllers/management/components/management/groups/get-agents-filters-values'; import { WzButtonPermissions } from '../../../components/common/permissions/button'; import { formatUIDate } from '../../../react-services/time-service'; import { withErrorBoundary } from '../../../components/common/hocs'; import { API_NAME_AGENT_STATUS, - UI_LOGGER_LEVELS, UI_ORDER_AGENT_STATUS, AGENT_SYNCED_STATUS, + SEARCH_BAR_WQL_VALUE_SUGGESTIONS_COUNT, } from '../../../../common/constants'; -import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/types'; -import { getErrorOrchestrator } from '../../../react-services/common-services'; import { AgentStatus } from '../../../components/agents/agent_status'; import { AgentSynced } from '../../../components/agents/agent-synced'; +import { TableWzAPI } from '../../../components/common/tables'; +import { WzRequest } from '../../../react-services/wz-request'; +import { get as getLodash } from 'lodash'; + +const searchBarWQLOptions = { + implicitQuery: { + query: 'id!=000', + conjunction: ';', + }, +}; export const AgentsTable = withErrorBoundary( class AgentsTable extends Component { @@ -56,285 +52,43 @@ export const AgentsTable = withErrorBoundary( constructor(props) { super(props); this.state = { - agents: [], - isLoading: false, - pageIndex: 0, - pageSize: 15, - sortDirection: 'asc', - sortField: 'id', - totalItems: 0, - selectedItems: [], - allSelected: false, - purgeModal: false, - isFilterColumnOpen: false, - filters: sessionStorage.getItem('agents_preview_selected_options') - ? JSON.parse( - sessionStorage.getItem('agents_preview_selected_options'), - ) - : [], - }; - this.suggestions = [ - { - type: 'q', - label: 'status', - description: 'Filter by agent connection status', - operators: ['=', '!='], - values: UI_ORDER_AGENT_STATUS, - }, - { - type: 'q', - label: 'group_config_status', - description: 'Filter by agent synced configuration status', - operators: ['=', '!='], - values: [AGENT_SYNCED_STATUS.SYNCED, AGENT_SYNCED_STATUS.NOT_SYNCED], - }, - { - type: 'q', - label: 'os.platform', - description: 'Filter by operating system platform', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('os.platform', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'ip', - description: 'Filter by agent IP address', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('ip', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'name', - description: 'Filter by agent name', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('name', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'id', - description: 'Filter by agent id', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('id', value, { q: 'id!=000' }), + filters: { + default: { q: 'id!=000' }, + ...(sessionStorage.getItem('wz-agents-overview-table-filter') + ? JSON.parse( + sessionStorage.getItem('wz-agents-overview-table-filter'), + ) + : {}), }, - { - type: 'q', - label: 'group', - description: 'Filter by agent group', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('group', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'node_name', - description: 'Filter by node name', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('node_name', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'manager', - description: 'Filter by manager', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('manager', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'version', - description: 'Filter by agent version', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('version', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'configSum', - description: 'Filter by agent config sum', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('configSum', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'mergedSum', - description: 'Filter by agent merged sum', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('mergedSum', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'dateAdd', - description: 'Filter by add date', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('dateAdd', value, { q: 'id!=000' }), - }, - { - type: 'q', - label: 'lastKeepAlive', - description: 'Filter by last keep alive', - operators: ['=', '!='], - values: async value => - getAgentFilterValues('lastKeepAlive', value, { q: 'id!=000' }), - }, - ]; - this.downloadCsv.bind(this); + reloadTable: 0, + }; } - onTableChange = ({ page = {}, sort = {} }) => { - const { index: pageIndex, size: pageSize } = page; - const { field: sortField, direction: sortDirection } = sort; - this._isMount && - this.setState({ - pageIndex, - pageSize, - sortField, - sortDirection, - }); - }; - async componentDidMount() { this._isMount = true; - await this.getItems(); } componentWillUnmount() { this._isMount = false; - if (sessionStorage.getItem('agents_preview_selected_options')) { - sessionStorage.removeItem('agents_preview_selected_options'); + if (sessionStorage.getItem('wz-agents-overview-table-filter')) { + sessionStorage.removeItem('wz-agents-overview-table-filter'); } } async reloadAgents() { - await this.getItems(); + this.setState({ reloadTable: Date.now() }); await this.props.reload(); } - async componentDidUpdate(prevProps, prevState) { + async componentDidUpdate(prevProps) { if ( - !_.isEqual(prevState.filters, this.state.filters) || - prevState.pageIndex !== this.state.pageIndex || - prevState.pageSize !== this.state.pageSize || - prevState.sortField !== this.state.sortField || - prevState.sortDirection !== this.state.sortDirection - ) { - await this.getItems(); - } else if ( - !_.isEqual(prevProps.filters, this.props.filters) && - this.props.filters && - this.props.filters.length + // TODO: external filters + !_.isEqual(prevProps.filters, this.props.filters) ) { - this.setState({ filters: this.props.filters, pageIndex: 0 }); - this.props.removeFilters(); + this.setState({ filters: this.props.filters }); } } - async getItems() { - try { - this._isMount && this.setState({ isLoading: true }); - const selectFieldsList = this.defaultColumns - .filter(field => field.field != 'actions') - .map(field => field.field.replace('os_', 'os.')); // "os_name" subfield should be specified as 'os.name' - const selectFields = [ - ...selectFieldsList, - 'os.platform', - 'os.uname', - 'os.version', - ].join(','); // Add version and uname fields to render the OS icon and version in the table - - const rawAgents = await this.props.wzReq('GET', '/agents', { - params: { ...this.buildFilter(), select: selectFields }, - }); - const formatedAgents = ( - ((rawAgents || {}).data || {}).data || {} - ).affected_items.map(this.formatAgent.bind(this)); - - this._isMount && - this.setState({ - agents: formatedAgents, - totalItems: (((rawAgents || {}).data || {}).data || {}) - .total_affected_items, - isLoading: false, - }); - } catch (error) { - const options = { - context: `${AgentsTable.name}.getItems`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - store: true, - error: { - error: error, - message: error.message || error, - title: `Could not get the agents list`, - }, - }; - getErrorOrchestrator().handleError(options); - this.setState({ isLoading: false }); - } - } - - buildFilter() { - const { pageIndex, pageSize, filters } = this.state; - - const filter = { - ...filtersToObject(filters), - offset: pageIndex * pageSize || 0, - limit: pageSize, - sort: this.buildSortFilter(), - }; - filter.q = !filter.q ? `id!=000` : `id!=000;${filter.q}`; - - return filter; - } - - buildSortFilter() { - const { sortField, sortDirection } = this.state; - - const field = sortField === 'os_name' ? 'os.name,os.version' : sortField; - const direction = sortDirection === 'asc' ? '+' : '-'; - - return direction + field; - } - - buildQFilter() { - const { q } = this.state; - return q === '' ? `id!=000` : `id!=000;${q}`; - } - - formatAgent(agent) { - const agentVersion = - agent.version !== undefined ? agent.version.split(' ')[1] : '-'; - const node_name = - agent.node_name && agent.node_name !== 'unknown' - ? agent.node_name - : '-'; - - return { - id: agent.id, - name: agent.name, - ip: agent.ip, - status: agent.status, - group_config_status: agent.group_config_status, - group: agent?.group || '-', - os_name: agent, - version: agentVersion, - node_name: node_name, - dateAdd: agent.dateAdd ? formatUIDate(agent.dateAdd) : '-', - lastKeepAlive: agent.lastKeepAlive - ? formatUIDate(agent.lastKeepAlive) - : '-', - actions: agent, - upgrading: false, - }; - } - actionButtonsRender(agent) { return (