From f7bac4acf38a3309fc1630f3bfc79e71048e8174 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 08:22:53 -0300 Subject: [PATCH 01/61] feat: integrate ButtonExploreAgent component into MainModuleAgent for enhanced agent interaction and updated layout consistency --- .../public/components/common/modules/main-agent.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/main/public/components/common/modules/main-agent.tsx b/plugins/main/public/components/common/modules/main-agent.tsx index 74ebf831e0..97b1414b8a 100644 --- a/plugins/main/public/components/common/modules/main-agent.tsx +++ b/plugins/main/public/components/common/modules/main-agent.tsx @@ -34,6 +34,7 @@ import { toTitleCase } from '../util/change-case'; import clsx from 'clsx'; import { AgentTabs } from '../../endpoints-summary/agent/agent-tabs'; import { Agent } from '../../endpoints-summary/types'; +import { ButtonExploreAgent } from '../../wz-agent-selector/button-explore-agent'; export class MainModuleAgent extends Component { props!: { @@ -52,7 +53,7 @@ export class MainModuleAgent extends Component { const { agent, section, switchTab } = this.props; return ( - + {this.inventoryTabs.includes(section) ? ( <> @@ -74,14 +75,13 @@ export class MainModuleAgent extends Component { )} - + + + {[AgentTabs.SOFTWARE, AgentTabs.NETWORK, AgentTabs.PROCESSES].includes( section, ) && ( - + )} From e45f750931aeb6f51a466de562aa0e2a74ff6a19 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 08:28:18 -0300 Subject: [PATCH 02/61] feat: add pinned agent mechanic across all pages for improved consistency in functionality and user experience --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05f54d57c6..c63b1f6f84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to the Wazuh app project will be documented in this file. - 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) +- Added pinned agent mechanic across all pages for consistent functionality [#7135](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7135) ### Changed From f221e076feb8d9871af72c87e56baca7d3d2309c Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 09:14:55 -0300 Subject: [PATCH 03/61] feat: enhance ButtonPinnedAgent with clsx for dynamic class management and improved background styling --- .../components/wz-agent-selector/button-explore-agent.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx b/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx index bdfb3a66fc..118bed45bb 100644 --- a/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx +++ b/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx @@ -5,6 +5,7 @@ import { WzButtonType } from '../common/buttons/button'; import { connect } from 'react-redux'; import { showExploreAgentModalGlobal } from '../../redux/actions/appStateActions'; import './button-explore-agent.scss'; +import clsx from 'clsx'; const ButtonPinnedAgent = ({ showExploreAgentModalGlobal, module }) => { const pinnedAgentManager = new PinnedAgentManager(); @@ -28,8 +29,8 @@ const ButtonPinnedAgent = ({ showExploreAgentModalGlobal, module }) => { : agent ? 'Change agent selected' : 'Select an agent to explore its modules', - }} - style={agent ? { background: 'rgba(0, 107, 180, 0.1)' } : undefined} + }} + className={clsx({ 'wz-unpin-agent-bg': agent })} iconType='watchesApp' onClick={() => showExploreAgentModalGlobal(true)} > @@ -38,7 +39,7 @@ const ButtonPinnedAgent = ({ showExploreAgentModalGlobal, module }) => { {agent ? ( { pinnedAgentManager.unPinAgent(); From fd3f673df67f560c6db58fffeff8cd2b352be39d Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 09:16:39 -0300 Subject: [PATCH 04/61] refactor: clean up agent selector styles by removing unnecessary focus and hover states for better maintainability --- .../wz-agent-selector/button-explore-agent.scss | 5 ++--- .../overview-actions/agents-selector.scss | 14 -------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/plugins/main/public/components/wz-agent-selector/button-explore-agent.scss b/plugins/main/public/components/wz-agent-selector/button-explore-agent.scss index a7a20f9695..6b70c7eb58 100644 --- a/plugins/main/public/components/wz-agent-selector/button-explore-agent.scss +++ b/plugins/main/public/components/wz-agent-selector/button-explore-agent.scss @@ -1,9 +1,8 @@ -.wz-explore-agent .euiButtonEmpty:focus { - background-color: transparent; +.wz-unpin-agent-bg { + background-color: rgba(0, 107, 180, 0.1); } .wz-unpin-agent { - background-color: rgba(0, 107, 180, 0.1); border-radius: 0; height: 40px; } diff --git a/plugins/main/public/controllers/overview/components/overview-actions/agents-selector.scss b/plugins/main/public/controllers/overview/components/overview-actions/agents-selector.scss index 00ee2dd91f..77411a551d 100644 --- a/plugins/main/public/controllers/overview/components/overview-actions/agents-selector.scss +++ b/plugins/main/public/controllers/overview/components/overview-actions/agents-selector.scss @@ -32,17 +32,3 @@ background: #bd271e; color: white; } - -.wz-explore-agent .euiButtonEmpty:focus { - background-color: transparent; -} - -.wz-unpin-agent { - background-color: rgba(0, 107, 180, 0.1); - border-radius: 0; - height: 40px; -} - -.wz-unpin-agent:hover { - transform: translateY(0px) !important; -} From 3ecbdbfbd7678f8d4b1f72ffbc63889f8225c500 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 09:17:01 -0300 Subject: [PATCH 05/61] refactor: update WzButtonProps type to include EUI component properties for better flexibility and maintainability --- .../components/common/buttons/button.tsx | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/plugins/main/public/components/common/buttons/button.tsx b/plugins/main/public/components/common/buttons/button.tsx index 46c78f577c..754d616065 100644 --- a/plugins/main/public/components/common/buttons/button.tsx +++ b/plugins/main/public/components/common/buttons/button.tsx @@ -12,11 +12,15 @@ import React from 'react'; import { EuiButton, + EuiButtonProps, EuiButtonEmpty, EuiButtonIcon, EuiLink, EuiToolTip, EuiSwitch, + EuiButtonEmptyProps, + EuiButtonIconProps, + EuiSwitchProps, } from '@elastic/eui'; export enum WzButtonType { @@ -27,14 +31,20 @@ export enum WzButtonType { switch = 'switch', } -interface WzButtonProps { - buttonType?: WzButtonType; - tooltip?: any; - color?: any; - children?: any; - isDisabled?: any; - rest?: any; -} +type WzButtonProps = + | { + buttonType?: WzButtonType; + tooltip?: any; + color?: string; + children?: any; + isDisabled?: any; + className?: string; + rest?: any; + } + | Partial + | Partial + | Partial + | Partial; const WzButtons: { [key in WzButtonType]: React.FunctionComponent } = { default: EuiButton, From ead4fb8e321e6844997d6c3c829d9a08d4469b20 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 09:17:09 -0300 Subject: [PATCH 06/61] refactor: improve ButtonPinnedAgent structure by adding data-test attribute and simplifying JSX for cleaner code readability --- .../button-explore-agent.tsx | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx b/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx index 118bed45bb..1912f55fbe 100644 --- a/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx +++ b/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx @@ -16,40 +16,41 @@ const ButtonPinnedAgent = ({ showExploreAgentModalGlobal, module }) => { ? module?.availableFor && module?.availableFor.includes('agent') : true; return ( - <> -
- + showExploreAgentModalGlobal(true)} - > - {agent ? `${agent.name} (${agent.id})` : 'Explore agent'} - - {agent ? ( - showExploreAgentModalGlobal(true)} + > + {agent ? `${agent.name} (${agent.id})` : 'Explore agent'} + + {agent ? ( + { - pinnedAgentManager.unPinAgent(); - }} - tooltip={{ position: 'bottom', content: 'Unpin agent' }} - aria-label='Unpin agent' - /> - ) : null} -
- + iconType='pinFilled' + onClick={() => { + pinnedAgentManager.unPinAgent(); + }} + tooltip={{ position: 'bottom', content: 'Unpin agent' }} + aria-label='Unpin agent' + /> + ) : null} + ); }; From d72222bcbfdae288e2053c368f1113521f94652f Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 09:31:44 -0300 Subject: [PATCH 07/61] test: add tests for explore agent button rendering in various agent tabs for improved coverage and verification of UI functionality --- .../common/modules/main-agent.test.tsx | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/plugins/main/public/components/common/modules/main-agent.test.tsx b/plugins/main/public/components/common/modules/main-agent.test.tsx index 02ba68cd67..a6df13c53c 100644 --- a/plugins/main/public/components/common/modules/main-agent.test.tsx +++ b/plugins/main/public/components/common/modules/main-agent.test.tsx @@ -6,6 +6,7 @@ import { queryDataTestAttr } from '../../../../test/public/query-attr'; const GENERATE_REPORT_BUTTON = 'generate-report-button'; const ARIA_SELECTED = '[aria-selected="true"]'; +const EXPLORE_AGENT_BUTTON = 'explore-agent-button'; const REPORT_TAB = { STATS: 'agent-tab-stats', @@ -33,6 +34,19 @@ jest.mock('../data-source', () => ({ __esModule: true, })); +jest.mock('react-redux', () => ({ + connect: () => Component => Component, + __esModule: true, +})); + +jest.mock('../../../react-services/navigation-service', () => ({ + getInstance: () => ({ + getPathname: () => '', + getParams: () => new URLSearchParams(), + renewURL: jest.fn(), + }), +})); + describe('Main Agent', () => { let switchTab: jest.Mock; @@ -356,4 +370,81 @@ describe('Main Agent', () => { expect(generateReportButton).toBeTruthy(); }); }); + describe('ButtonExploreAgent', () => { + it('should render explore agent button in tab software', () => { + const { container } = render( + , + ); + + const exploreAgentButton = container.querySelector( + queryDataTestAttr(EXPLORE_AGENT_BUTTON), + ); + + expect(exploreAgentButton).toBeTruthy(); + }); + it('should render explore agent button in tab network', () => { + const { container } = render( + , + ); + + const exploreAgentButton = container.querySelector( + queryDataTestAttr(EXPLORE_AGENT_BUTTON), + ); + + expect(exploreAgentButton).toBeTruthy(); + }); + it('should render explore agent button in tab processes', () => { + const { container } = render( + , + ); + + const exploreAgentButton = container.querySelector( + queryDataTestAttr(EXPLORE_AGENT_BUTTON), + ); + + expect(exploreAgentButton).toBeTruthy(); + }); + it('should render explore agent button in tab stats', () => { + const { container } = render( + , + ); + + const exploreAgentButton = container.querySelector( + queryDataTestAttr(EXPLORE_AGENT_BUTTON), + ); + + expect(exploreAgentButton).toBeTruthy(); + }); + it('should render explore agent button in tab configuration', () => { + const { container } = render( + , + ); + + const exploreAgentButton = container.querySelector( + queryDataTestAttr(EXPLORE_AGENT_BUTTON), + ); + + expect(exploreAgentButton).toBeTruthy(); + }); + }); }); From d10ff4eff04ba0919367f366050c465e9d478892 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 09:31:44 -0300 Subject: [PATCH 08/61] test: add tests for explore agent button rendering in various agent tabs for improved coverage and verification of UI functionality refactor: enhance MainModuleAgent layout by adding margin and padding styles to EuiFlexItems for improved UI consistency --- .../public/components/common/modules/main-agent.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/main/public/components/common/modules/main-agent.tsx b/plugins/main/public/components/common/modules/main-agent.tsx index 97b1414b8a..e03e7d5518 100644 --- a/plugins/main/public/components/common/modules/main-agent.tsx +++ b/plugins/main/public/components/common/modules/main-agent.tsx @@ -75,13 +75,21 @@ export class MainModuleAgent extends Component { )}
- + {[AgentTabs.SOFTWARE, AgentTabs.NETWORK, AgentTabs.PROCESSES].includes( section, ) && ( - + )} From 676016074983b5912159e98af1a44079080de69e Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 29 Oct 2024 15:21:42 -0300 Subject: [PATCH 09/61] refactor: add newline in ButtonPinnedAgent for improved readability and code consistency in explore agent button component --- .../public/components/wz-agent-selector/button-explore-agent.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx b/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx index 1912f55fbe..e8a6308252 100644 --- a/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx +++ b/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx @@ -15,6 +15,7 @@ const ButtonPinnedAgent = ({ showExploreAgentModalGlobal, module }) => { const avaliableForAgent = module ? module?.availableFor && module?.availableFor.includes('agent') : true; + return (
Date: Wed, 30 Oct 2024 08:22:25 -0300 Subject: [PATCH 10/61] chore: update CHANGELOG to clarify pinned agent mechanic in inventory, stats, and configuration for consistency across pages --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7501a25795..21b4adc541 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ All notable changes to the Wazuh app project will be documented in this file. - 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) - Added filter by value to document details fields [#7081](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7081) -- Added pinned agent mechanic across all pages for consistent functionality [#7135](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7135) +- Added pinned agent mechanic to inventory data, stats, and configuration for consistent functionality [#7135](https://github.com/wazuh/wazuh-dashboard-plugins/pull/7135) ### Changed From 21d5c0350c6407ba8e1b77b9891c6ae55ab0032c Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 11:54:27 -0300 Subject: [PATCH 11/61] refactor: add unPinAgent functionality to agent components for enhanced user interaction and UI consistency across agent views --- .../components/common/modules/main-agent.tsx | 3 +- .../common/welcome/agents-welcome.js | 2 +- .../endpoints-summary/agent/index.tsx | 30 ++++++++++++++++--- .../button-explore-agent.tsx | 27 +++++++++++++---- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/plugins/main/public/components/common/modules/main-agent.tsx b/plugins/main/public/components/common/modules/main-agent.tsx index e03e7d5518..960b179997 100644 --- a/plugins/main/public/components/common/modules/main-agent.tsx +++ b/plugins/main/public/components/common/modules/main-agent.tsx @@ -45,6 +45,7 @@ export class MainModuleAgent extends Component { tabs?: any[]; renderTabs?: () => JSX.Element; agentsSelectionProps?: any; + unPinAgent?: () => void; }; inventoryTabs = [AgentTabs.SOFTWARE, AgentTabs.NETWORK, AgentTabs.PROCESSES]; @@ -80,7 +81,7 @@ export class MainModuleAgent extends Component { className='euiTabs' style={{ marginInline: 0, paddingInline: 12 }} > - + {[AgentTabs.SOFTWARE, AgentTabs.NETWORK, AgentTabs.PROCESSES].includes( section, diff --git a/plugins/main/public/components/common/welcome/agents-welcome.js b/plugins/main/public/components/common/welcome/agents-welcome.js index 61d41e9a2e..22b6085226 100644 --- a/plugins/main/public/components/common/welcome/agents-welcome.js +++ b/plugins/main/public/components/common/welcome/agents-welcome.js @@ -331,7 +331,7 @@ export const AgentsWelcome = compose( grow={false} style={{ marginTop: 7, marginRight: '0.5rem' }} > - + { + // navigate to the agents preview page + NavigationService.getInstance().navigateToApp(endpointSummary.id, { + path: `#${SECTIONS.AGENTS_PREVIEW}`, + }); + }; + return ( @@ -113,6 +120,7 @@ export const AgentView = compose( agent={agentData} section={tab} switchTab={switchTab} + unPinAgent={unPinAgent} /> @@ -121,6 +129,7 @@ export const AgentView = compose( agent={agentData} section={tab} switchTab={switchTab} + unPinAgent={unPinAgent} /> @@ -129,19 +138,32 @@ export const AgentView = compose( agent={agentData} section={tab} switchTab={switchTab} + unPinAgent={unPinAgent} /> - + - + - + @@ -149,7 +171,7 @@ export const AgentView = compose( switchTab={switchTab} agent={agentData} pinAgent={pinnedAgentManager.pinAgent} - unPinAgent={pinnedAgentManager.unPinAgent} + unPinAgent={unPinAgent} /> diff --git a/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx b/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx index e8a6308252..d0574d1ed6 100644 --- a/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx +++ b/plugins/main/public/components/wz-agent-selector/button-explore-agent.tsx @@ -7,7 +7,19 @@ import { showExploreAgentModalGlobal } from '../../redux/actions/appStateActions import './button-explore-agent.scss'; import clsx from 'clsx'; -const ButtonPinnedAgent = ({ showExploreAgentModalGlobal, module }) => { +interface ButtonPinnedAgentProps { + showExploreAgentModalGlobal: (shouldShow: boolean) => void; + module?: { + availableFor?: string[]; + }; + onUnpinAgent?: () => void; +} + +const ButtonPinnedAgent = ({ + showExploreAgentModalGlobal, + module, + onUnpinAgent, +}: ButtonPinnedAgentProps) => { const pinnedAgentManager = new PinnedAgentManager(); const agent = pinnedAgentManager.isPinnedAgent() ? pinnedAgentManager.getPinnedAgent() @@ -16,6 +28,11 @@ const ButtonPinnedAgent = ({ showExploreAgentModalGlobal, module }) => { ? module?.availableFor && module?.availableFor.includes('agent') : true; + const unPinAgentHandler = () => { + pinnedAgentManager.unPinAgent(); + onUnpinAgent?.(); + }; + return (
{ buttonType={WzButtonType.icon} className='wz-unpin-agent wz-unpin-agent-bg' iconType='pinFilled' - onClick={() => { - pinnedAgentManager.unPinAgent(); - }} + onClick={unPinAgentHandler} tooltip={{ position: 'bottom', content: 'Unpin agent' }} aria-label='Unpin agent' /> @@ -62,8 +77,8 @@ const mapStateToProps = state => { }; const mapDispatchToProps = dispatch => ({ - showExploreAgentModalGlobal: data => - dispatch(showExploreAgentModalGlobal(data)), + showExploreAgentModalGlobal: (shouldShow: boolean) => + dispatch(showExploreAgentModalGlobal(shouldShow)), }); export const ButtonExploreAgent = connect( From d26e76f04f812d30b642b441eb9e8ba8f7f3bff1 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 13:04:11 -0300 Subject: [PATCH 12/61] refactor: remove unused EuiButtonEmpty import for cleaner code in configuration overview component --- .../management/configuration/configuration-overview.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/main/public/controllers/management/components/management/configuration/configuration-overview.js b/plugins/main/public/controllers/management/components/management/configuration/configuration-overview.js index 4426bd9f25..8c0d4fe8a1 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/configuration-overview.js +++ b/plugins/main/public/controllers/management/components/management/configuration/configuration-overview.js @@ -12,12 +12,7 @@ import React, { Component, Fragment } from 'react'; -import { - EuiTitle, - EuiFlexGroup, - EuiFlexItem, - EuiButtonEmpty, -} from '@elastic/eui'; +import { EuiTitle, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import WzConfigurationOverviewTable from './util-components/configuration-overview-table'; import WzHelpButtonPopover from './util-components/help-button-popover'; From e45733e960f8349a2cc2870f307cca5e84abd786 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 15:04:41 -0300 Subject: [PATCH 13/61] refactor: update useGenericRequest hook for improved type safety and cleaner data handling in API requests --- .../common/hooks/useGenericRequest.ts | 60 ++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/plugins/main/public/components/common/hooks/useGenericRequest.ts b/plugins/main/public/components/common/hooks/useGenericRequest.ts index d8fd733cff..dfdafb78ec 100644 --- a/plugins/main/public/components/common/hooks/useGenericRequest.ts +++ b/plugins/main/public/components/common/hooks/useGenericRequest.ts @@ -9,36 +9,56 @@ import { UILogLevel, } from '../../../react-services/error-orchestrator/types'; -export function useGenericRequest(method, path, params, formatFunction) { - const [items, setItems] = useState({}); - const [isLoading, setisLoading] = useState(true); - const [error, setError] = useState(""); +interface UseGenericRequestProps { + method: string; + path: string; + params?: any; + resolveData?: (data: any) => any; +} + +export function useGenericRequest({ + method, + path, + params = {}, + resolveData = response => response, +}: UseGenericRequestProps) { + const [response, setResponse] = useState({}); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(); - useEffect( () => { - try{ - setisLoading(true); - const fetchData = async() => { - const response = await GenericRequest.request(method, path, params); - setItems(response); - setisLoading(false); - } - fetchData(); - } catch(error) { - setError(error); - setisLoading(false); + useEffect(() => { + try { + setIsLoading(true); + const fetchData = async () => { + const response = await GenericRequest.request( + method, + path, + params, + ); + setResponse(response); + }; + fetchData(); + } catch (error) { + setError(error as Error); const options: UIErrorLog = { context: `${useGenericRequest.name}.fetchData`, level: UI_LOGGER_LEVELS.ERROR as UILogLevel, severity: UI_ERROR_SEVERITIES.UI as UIErrorSeverity, error: { error: error, - message: error.message || error, - title: error.name || error, + message: (error as Error).message || (error as string), + title: (error as Error).name || (error as string), }, }; getErrorOrchestrator().handleError(options); + } finally { + setIsLoading(false); } - }, [params]); + }, [JSON.stringify(params), path, method]); - return {isLoading, data: formatFunction(items), error}; + return { + isLoading, + data: resolveData(response), + error, + }; } From 269515161029073e8fb32c2f10329bc826928c94 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 15:06:36 -0300 Subject: [PATCH 14/61] refactor: enhance type safety in InventoryMetrics and streamline API request handling with updated useGenericRequest usage --- .../components/syscollector-metrics.tsx | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) 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 682e29585b..52395504e6 100644 --- a/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.tsx +++ b/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import { EuiPanel, EuiIcon } from '@elastic/eui'; import _ from 'lodash'; import { useGenericRequest } from '../../../common/hooks/useGenericRequest'; @@ -8,24 +8,26 @@ import { IRibbonItem, RibbonItemLabel, } from '../../../common/ribbon/ribbon-item'; +import { Agent } from '../../../endpoints-summary/types'; -export function InventoryMetrics({ agent }) { - const [params, setParams] = useState({}); - const offsetTimestamp = (text, time) => { - try { - return text + formatUIDate(time); - } catch (error) { - return time !== '-' ? `${text}${time} (UTC)` : time; - } - }; - const syscollector = useGenericRequest( - 'GET', - `/api/syscollector/${agent.id}`, - params, - result => { - return (result || {}).data || {}; - }, - ); +interface SyscollectorMetricsProps { + agent: Agent; +} + +const offsetTimestamp = (text: string, time: string) => { + try { + return text + formatUIDate(time); + } catch (error) { + return time !== '-' ? `${text}${time} (UTC)` : time; + } +}; + +export function InventoryMetrics({ agent }: SyscollectorMetricsProps) { + const syscollector = useGenericRequest({ + method: 'GET', + path: `/api/syscollector/${agent.id}`, + resolveData: data => data?.data || {}, + }); if ( !syscollector.isLoading && From 89ac9ff8a80136d6c0d45a4a6d3edee45cc8ebbd Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 15:59:01 -0300 Subject: [PATCH 15/61] refactor: rename ErrorOrchestratorService to ErrorService for improved clarity and type safety in error handling logic --- plugins/main/public/react-services/common-services.ts | 7 +++---- .../error-orchestrator/error-orchestrator.service.ts | 4 ++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/plugins/main/public/react-services/common-services.ts b/plugins/main/public/react-services/common-services.ts index f57e8d0005..517ad46240 100644 --- a/plugins/main/public/react-services/common-services.ts +++ b/plugins/main/public/react-services/common-services.ts @@ -11,9 +11,8 @@ * Find more information about this on the LICENSE file. * */ -import { ErrorOrchestratorService } from './error-orchestrator/error-orchestrator.service'; +import { ErrorService } from './error-orchestrator/error-orchestrator.service'; import { createGetterSetter } from '../utils/create-getter-setter'; -export const [getErrorOrchestrator, setErrorOrchestrator] = createGetterSetter< - ErrorOrchestratorService ->('ErrorOrchestratorService'); +export const [getErrorOrchestrator, setErrorOrchestrator] = + createGetterSetter('ErrorOrchestratorService'); diff --git a/plugins/main/public/react-services/error-orchestrator/error-orchestrator.service.ts b/plugins/main/public/react-services/error-orchestrator/error-orchestrator.service.ts index 2fdf26f584..6fe1a371b9 100644 --- a/plugins/main/public/react-services/error-orchestrator/error-orchestrator.service.ts +++ b/plugins/main/public/react-services/error-orchestrator/error-orchestrator.service.ts @@ -33,3 +33,7 @@ export class ErrorOrchestratorService { errorOrchestrator.loadErrorLog(uiErrorLog); } } + +export type ErrorService = ErrorOrchestratorService & { + handleError: (uiErrorLog: UIErrorLog) => void; +}; From 8707d26bf417ab9cda4f2cc906d00bdc772c6ab9 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 16:00:17 -0300 Subject: [PATCH 16/61] refactor: add JSDoc comments to GenericRequest for improved type safety and better documentation of request parameters --- plugins/main/public/react-services/generic-request.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/main/public/react-services/generic-request.js b/plugins/main/public/react-services/generic-request.js index 320dde6936..5c97ba290a 100644 --- a/plugins/main/public/react-services/generic-request.js +++ b/plugins/main/public/react-services/generic-request.js @@ -20,6 +20,15 @@ import { request } from '../services/request-handler'; import NavigationService from './navigation-service'; export class GenericRequest { + /** + * Generic request + * @template T + * @param {string} method + * @param {string} path + * @param {any} payload + * @param {boolean} returnError + * @returns {Promise} + */ static async request(method, path, payload = null, returnError = false) { try { if (!method || !path) { From 24a34b6530a491539d041caf03dae501c3e5c568 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 16:00:34 -0300 Subject: [PATCH 17/61] refactor: improve cluster handling logic and error management in WzConfigurationSwitch for better state management and readability --- .../configuration/configuration-switch.js | 183 ++++++++++-------- 1 file changed, 100 insertions(+), 83 deletions(-) diff --git a/plugins/main/public/controllers/management/components/management/configuration/configuration-switch.js b/plugins/main/public/controllers/management/components/management/configuration/configuration-switch.js index 3aaf1139e7..efd6316178 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/configuration-switch.js +++ b/plugins/main/public/controllers/management/components/management/configuration/configuration-switch.js @@ -53,7 +53,7 @@ import WzRefreshClusterInfoButton from './util-components/refresh-cluster-info-b import { withUserAuthorizationPrompt } from '../../../../../components/common/hocs'; import { - clusterNodes, + clusterNodes as requestClusterNodes, clusterReq, agentIsSynchronized, } from './utils/wz-fetch'; @@ -99,103 +99,120 @@ class WzConfigurationSwitch extends Component { loadingOverview: this.props.agent.id === '000', }; } + componentWillUnmount() { - this.props.updateClusterNodes(false); - this.props.updateClusterNodeSelected(false); + this.resetClusterState(); } + updateConfigurationSection = (view, title, description) => { this.setState({ view, viewProps: { title: title, description } }); }; + updateBadge = badgeStatus => { // default value false? this.setState({ viewProps: { ...this.state.viewProps, badge: badgeStatus }, }); }; - async componentDidMount() { + + catchError = (error, context) => { + const options = { + context: `${WzConfigurationSwitch.name}.${context}`, + level: UI_LOGGER_LEVELS.ERROR, + severity: UI_ERROR_SEVERITIES.BUSINESS, + error: { + error: error, + message: error.message || error, + title: error.name || error, + }, + }; + getErrorOrchestrator().handleError(options); + }; + + updateAgentSynchronization = async (/** @type {string} */ context) => { // If agent, check if is synchronized or not - if (this.props.agent.id !== '000') { - try { - const agentSynchronized = await agentIsSynchronized(this.props.agent); - this.setState({ agentSynchronized }); - } catch (error) { - const options = { - context: `${WzConfigurationSwitch.name}.componentDidMount`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - error: { - error: error, - message: error.message || error, - title: error.name || error, - }, - }; - getErrorOrchestrator().handleError(options); - } - } else { - try { - // try if it is a cluster - const clusterStatus = await clusterReq(); - const isCluster = - clusterStatus.data.data.enabled === 'yes' && - clusterStatus.data.data.running === 'yes'; - if (isCluster) { - const nodes = await clusterNodes(); - // set cluster nodes in Redux Store - this.props.updateClusterNodes(nodes.data.data.affected_items); - // set cluster node selected in Redux Store - this.props.updateClusterNodeSelected( - nodes.data.data.affected_items.find(node => node.type === 'master') - .name, - ); - } else { - // do nothing if it isn't a cluster - this.props.updateClusterNodes(false); - this.props.updateClusterNodeSelected(false); - } - } catch (error) { + try { + const agentSynchronized = await agentIsSynchronized(this.props.agent); + this.setState({ agentSynchronized }); + } catch (error) { + this.catchError(error, context); + } + }; + + handleClusterNodes = async () => { + const nodes = await requestClusterNodes(); + const clusterNodes = nodes.data.data.affected_items; + + this.props.updateClusterNodes(clusterNodes); + const masterNode = clusterNodes.find(node => node.type === 'master'); + if (masterNode) { + this.props.updateClusterNodeSelected(masterNode.name); + } + }; + + resetClusterState = () => { + this.props.updateClusterNodes(false); + this.props.updateClusterNodeSelected(false); + }; + + updateClusterInformation = async (/** @type {string} */ context) => { + try { + // try if it is a cluster + const clusterStatus = await clusterReq(); + const isCluster = + clusterStatus.data.data.enabled === 'yes' && + clusterStatus.data.data.running === 'yes'; + + if (isCluster) { + await this.handleClusterNodes(); + } else { // do nothing if it isn't a cluster - this.props.updateClusterNodes(false); - this.props.updateClusterNodeSelected(false); - const options = { - context: `${WzConfigurationSwitch.name}.componentDidMount`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - error: { - error: error, - message: error.message || error, - title: error.name || error, - }, - }; - getErrorOrchestrator().handleError(options); - } - // If manager/cluster require agent platform info to filter sections in overview. It isn't coming from props for Management/Configuration - try { - this.setState({ loadingOverview: true }); - const masterNodeInfo = await WzRequest.apiReq( - 'GET', - '/agents?agents_list=000', - {}, - ); - this.setState({ - masterNodeInfo: masterNodeInfo.data.data.affected_items[0], - }); - this.setState({ loadingOverview: false }); - } catch (error) { - this.setState({ loadingOverview: false }); - const options = { - context: `${WzConfigurationSwitch.name}.componentDidMount`, - level: UI_LOGGER_LEVELS.ERROR, - severity: UI_ERROR_SEVERITIES.BUSINESS, - error: { - error: error, - message: error.message || error, - title: error.name || error, - }, - }; - getErrorOrchestrator().handleError(options); + this.resetClusterState(); } + } catch (error) { + // do nothing if it isn't a cluster + this.resetClusterState(); + this.catchError(error, context); } + }; + + fetchMasterNodeInfo = async (/** @type {string} */ context) => { + this.setState({ loadingOverview: true }); + + try { + const masterNodeInfo = await WzRequest.apiReq( + 'GET', + '/agents?agents_list=000', + {}, + ); + const masterNode = masterNodeInfo.data.data.affected_items[0]; + this.setState({ masterNodeInfo: masterNode }); + } catch (error) { + this.catchError(error, context); + } finally { + this.setState({ loadingOverview: false }); + } + }; + + handleAgentOrClusterUpdate = (/** @type {string} */ context) => { + if (this.props.agent.id !== '000') { + this.updateAgentSynchronization(context); + } else { + this.updateClusterInformation(context); + this.fetchMasterNodeInfo(); + } + }; + + async componentDidMount() { + this.handleAgentOrClusterUpdate('componentDidMount'); } + + async componentDidUpdate(prevProps) { + if (this.props.agent.id !== prevProps.agent.id) { + this.handleAgentOrClusterUpdate('componentDidUpdate'); + } + } + render() { const { view, @@ -208,7 +225,7 @@ class WzConfigurationSwitch extends Component { - {agent.id !== '000' && agent.group && agent.group.length ? ( + {agent.id !== '000' && agent.group?.length ? ( Groups: From 62b1c73348c7dc21fca45294e4c97ae028c51f04 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 16:01:23 -0300 Subject: [PATCH 18/61] refactor: streamline AgentStats component with improved type safety and error handling for enhanced clarity and maintainability --- .../components/agents/stats/agent-stats.tsx | 90 ++++++++++--------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/plugins/main/public/components/agents/stats/agent-stats.tsx b/plugins/main/public/components/agents/stats/agent-stats.tsx index 98f966281c..8f41f7f196 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.tsx @@ -13,14 +13,10 @@ import React, { useState, useEffect } from 'react'; import { EuiFlexGroup, EuiFlexItem, - EuiLoadingSpinner, - EuiPanel, EuiPage, EuiPageBody, EuiSpacer, - EuiText, } from '@elastic/eui'; - import { withGlobalBreadcrumb, withGuard, @@ -48,6 +44,7 @@ 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'; +import { Agent } from '../../endpoints-summary/types'; const tableColumns = [ { @@ -67,40 +64,43 @@ const tableColumns = [ }, ]; -const statsAgents: { title: string; field: string; render?: (value) => any }[] = - [ - { - title: 'Status', - field: 'status', - }, - { - title: 'Buffer', - field: 'buffer_enabled', - render: value => (value ? 'enabled' : 'disabled'), - }, - { - title: 'Message buffer', - field: 'msg_buffer', - }, - { - title: 'Messages count', - field: 'msg_count', - }, - { - title: 'Messages sent', - field: 'msg_sent', - }, - { - title: 'Last ack', - field: 'last_ack', - render: formatUIDate, - }, - { - title: 'Last keep alive', - field: 'last_keepalive', - render: formatUIDate, - }, - ]; +const statsAgents: { + title: string; + field: string; + render?: (value: any) => any; +}[] = [ + { + title: 'Status', + field: 'status', + }, + { + title: 'Buffer', + field: 'buffer_enabled', + render: value => (value ? 'enabled' : 'disabled'), + }, + { + title: 'Message buffer', + field: 'msg_buffer', + }, + { + title: 'Messages count', + field: 'msg_count', + }, + { + title: 'Messages sent', + field: 'msg_sent', + }, + { + title: 'Last ack', + field: 'last_ack', + render: formatUIDate, + }, + { + title: 'Last keep alive', + field: 'last_keepalive', + render: formatUIDate, + }, +]; export const MainAgentStats = compose( withErrorBoundary, @@ -143,9 +143,13 @@ export const MainAgentStats = compose( ), )(AgentStats); -export function AgentStats(props) { +interface AgentStatsProps { + agent: Agent; +} + +export function AgentStats(props: AgentStatsProps) { const { agent } = props; - const [loading, setLoading] = useState(); + const [loading, setLoading] = useState(false); const [dataStatLogcollector, setDataStatLogcollector] = useState({}); const [dataStatAgent, setDataStatAgent] = useState(); useEffect(() => { @@ -175,8 +179,8 @@ export function AgentStats(props) { severity: UI_ERROR_SEVERITIES.BUSINESS as UIErrorSeverity, error: { error: error, - message: error.message || error, - title: error.name || error, + message: (error as Error).message || (error as string), + title: (error as Error).name || (error as string), }, }; getErrorOrchestrator().handleError(options); @@ -184,7 +188,7 @@ export function AgentStats(props) { setLoading(false); } })(); - }, []); + }, [agent.id]); return ( From 81a2de7b9d353a8f694ee3842c735dc09ff25af5 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Wed, 30 Oct 2024 16:28:53 -0300 Subject: [PATCH 19/61] Fix Prettier issue --- .../error-orchestrator/error-orchestrator.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/main/public/react-services/error-orchestrator/error-orchestrator.service.ts b/plugins/main/public/react-services/error-orchestrator/error-orchestrator.service.ts index 6fe1a371b9..456e76fe4b 100644 --- a/plugins/main/public/react-services/error-orchestrator/error-orchestrator.service.ts +++ b/plugins/main/public/react-services/error-orchestrator/error-orchestrator.service.ts @@ -29,7 +29,9 @@ export class ErrorOrchestratorService { error, }: UIErrorLog) { const uiErrorLog = { context, level, severity, display, store, error }; - const errorOrchestrator: ErrorOrchestrator = errorOrchestratorFactory(uiErrorLog.severity); + const errorOrchestrator: ErrorOrchestrator = errorOrchestratorFactory( + uiErrorLog.severity, + ); errorOrchestrator.loadErrorLog(uiErrorLog); } } From cafd694dcb38ed33037516e3d7cd896b80f6a9cf Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Thu, 31 Oct 2024 09:41:18 -0300 Subject: [PATCH 20/61] refactor: update test descriptions in MainModuleAgent tests to clarify the "Pinned Agent" button functionality across tabs --- .../components/common/modules/main-agent.test.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/main/public/components/common/modules/main-agent.test.tsx b/plugins/main/public/components/common/modules/main-agent.test.tsx index a6df13c53c..c685d8dec6 100644 --- a/plugins/main/public/components/common/modules/main-agent.test.tsx +++ b/plugins/main/public/components/common/modules/main-agent.test.tsx @@ -370,8 +370,8 @@ describe('Main Agent', () => { expect(generateReportButton).toBeTruthy(); }); }); - describe('ButtonExploreAgent', () => { - it('should render explore agent button in tab software', () => { + describe('Verify the presence of the "Pinned Agent" button', () => { + it('should render "Pinned Agent" button in tab software', () => { const { container } = render( { expect(exploreAgentButton).toBeTruthy(); }); - it('should render explore agent button in tab network', () => { + it('should render "Pinned Agent" button in tab network', () => { const { container } = render( { expect(exploreAgentButton).toBeTruthy(); }); - it('should render explore agent button in tab processes', () => { + it('should render "Pinned Agent" button in tab processes', () => { const { container } = render( { expect(exploreAgentButton).toBeTruthy(); }); - it('should render explore agent button in tab stats', () => { + it('should render "Pinned Agent" button in tab stats', () => { const { container } = render( { expect(exploreAgentButton).toBeTruthy(); }); - it('should render explore agent button in tab configuration', () => { + it('should render "Pinned Agent" button in tab configuration', () => { const { container } = render( Date: Thu, 31 Oct 2024 10:47:31 -0300 Subject: [PATCH 21/61] refactor: remove deprecated Route for syscollector in AgentView to clean up component structure and improve readability --- .../public/components/endpoints-summary/agent/index.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index a9e8156760..01c3851c33 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -142,14 +142,6 @@ export const AgentView = compose( /> - - - - Date: Thu, 31 Oct 2024 12:30:26 -0300 Subject: [PATCH 22/61] refactor: rename PartialRecordMock to DeepPartialRecordMock for better clarity and maintainability in type definitions --- plugins/main/test/types/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/main/test/types/index.ts b/plugins/main/test/types/index.ts index f10772d5ea..7fcb77633c 100644 --- a/plugins/main/test/types/index.ts +++ b/plugins/main/test/types/index.ts @@ -5,10 +5,12 @@ export type RecordMock = { ? RecordMock : T[K]; }; -export type PartialRecordMock = Partial<{ +export type DeepPartialRecordMock = Partial<{ [K in keyof T]: T[K] extends Function ? jest.Mock + : T[K] extends Date + ? T[K] : T[K] extends {} - ? PartialRecordMock + ? DeepPartialRecordMock : T[K]; }>; From 79c271862995b62e87b821a79d459d2990e6067f Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Thu, 31 Oct 2024 12:30:44 -0300 Subject: [PATCH 23/61] feat: add mock agent data for Debian, Windows, and Darwin to enhance testing and provide a comprehensive environment setup --- plugins/main/test/__mocks__/agent.ts | 78 ++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 plugins/main/test/__mocks__/agent.ts diff --git a/plugins/main/test/__mocks__/agent.ts b/plugins/main/test/__mocks__/agent.ts new file mode 100644 index 0000000000..fa98a98978 --- /dev/null +++ b/plugins/main/test/__mocks__/agent.ts @@ -0,0 +1,78 @@ +import { Agent } from '../../public/components/endpoints-summary/types'; +import { DeepPartialRecordMock } from '../types'; + +export const AGENT = { + DEBIAN: { + os: { + arch: 'x86_64', + major: '9', + name: 'Debian GNU/Linux', + platform: 'debian', + 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', + version: '9', + }, + group: ['default', 'debian'], + ip: 'FE80:1234:2223:A000:2202:B3FF:FE1E:8329', + id: '001', + registerIP: 'FE80:1234:2223:A000:2202:B3FF:FE1E:8329', + dateAdd: new Date('2022-08-25T16:17:46Z'), + name: 'Debian agent', + status: 'active', + manager: 'wazuh-manager-master-0', + node_name: 'master', + lastKeepAlive: new Date('9999-12-31T23:59:59Z'), + version: 'Wazuh v4.5.0', + group_config_status: 'not synced', + status_code: 0, + }, + WINDOWS: { + os: { + major: '10', + minor: '0', + name: 'Microsoft Windows 10 Home Single Language', + platform: 'windows', + uname: 'Microsoft Windows 10 Home Single Language', + version: '10.0.19045', + }, + manager: 'test.com', + status: 'active', + name: 'Windows-agent', + dateAdd: new Date('1970-01-01T00:00:00Z'), + group: ['default', 'windows'], + lastKeepAlive: new Date('2023-03-14T04:20:51Z'), + node_name: 'node01', + registerIP: 'any', + id: '003', + version: 'Wazuh v4.3.10', + ip: '111.111.1.111', + mergedSum: 'e669d89eba52f6897060fc65a45300ac', + configSum: '97fccbb67e250b7c80aadc8d0dc59abe', + group_config_status: 'not synced', + status_code: 1, + }, + DARWIN: { + os: { + arch: 'x86_64', + major: '2', + name: 'macOS High Sierra', + platform: 'darwin', + uname: + 'macOS High Sierra |wazuh-manager-master-0 |4.14.114-105.126.amzn2.x86_64 |#1 SMP Tue May 7 02:26:40 UTC 2019 |x86_64', + version: '2', + }, + ip: '127.0.0.1', + id: '004', + group: ['default', 'darwin'], + registerIP: '127.0.0.1', + dateAdd: new Date('2022-08-25T16:17:46Z'), + name: 'macOS High Sierra agent', + status: 'active', + manager: 'wazuh-manager-master-0', + node_name: 'master', + lastKeepAlive: new Date('9999-12-31T23:59:59Z'), + version: 'Wazuh v4.5.0', + group_config_status: 'synced', + status_code: 3, + }, +} satisfies Record>; From 25c6a661302e3daf18bdadd73e32838056df3c4a Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Thu, 31 Oct 2024 12:30:59 -0300 Subject: [PATCH 24/61] refactor: replace inline AGENT mock with import from test mocks for improved test organization and maintainability --- .../agents/syscollector/inventory.test.tsx | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/plugins/main/public/components/agents/syscollector/inventory.test.tsx b/plugins/main/public/components/agents/syscollector/inventory.test.tsx index b39238c7cc..9997767955 100644 --- a/plugins/main/public/components/agents/syscollector/inventory.test.tsx +++ b/plugins/main/public/components/agents/syscollector/inventory.test.tsx @@ -3,6 +3,7 @@ import { render } from 'enzyme'; import { SyscollectorInventory } from './inventory'; import { AgentTabs } from '../../endpoints-summary/agent/agent-tabs'; import { queryDataTestAttr } from '../../../../test/public/query-attr'; +import { AGENT } from '../../../../test/__mocks__/agent'; const TABLE_ID = '__table_7d62db31-1cd0-11ee-8e0c-33242698a3b9'; const SOFTWARE_PACKAGES = 'Packages'; @@ -12,25 +13,6 @@ 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', From 050e7a13f2d709aae4e2c83e1faf849f90971b2f Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Thu, 31 Oct 2024 14:29:56 -0300 Subject: [PATCH 25/61] test: add API call verification in AgentStats tests to ensure correct fetching of agent stats during component rendering --- .../agents/stats/agent-stats.test.tsx | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/plugins/main/public/components/agents/stats/agent-stats.test.tsx b/plugins/main/public/components/agents/stats/agent-stats.test.tsx index 84f8e2a648..72b144b799 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.test.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.test.tsx @@ -3,6 +3,9 @@ import { render, act } from '@testing-library/react'; import { AgentStats } from './agent-stats'; import { queryDataTestAttr } from '../../../../test/public/query-attr'; import { CSS } from '../../../../test/utils/CSS'; +import { WzRequest } from '../../../react-services'; + +const apiReqMock = WzRequest.apiReq as jest.Mock; jest.mock('../../../react-services', () => ({ WzRequest: { @@ -10,6 +13,43 @@ jest.mock('../../../react-services', () => ({ }, })); +jest.mock('redux', () => ({ + compose: () => (Component: React.JSX.Element) => Component, + __esModule: true, +})); + +jest.mock('../../common/hocs', () => ({ + withGlobalBreadcrumb: () => () => <>, + withGuard: () => () => <>, + withUserAuthorizationPrompt: () => () => <>, + withErrorBoundary: () => () => <>, + __esModule: true, +})); + +jest.mock('../prompts', () => ({ + PromptNoActiveAgentWithoutSelect: () => <>, + PromptAgentFeatureVersion: () => <>, + __esModule: true, +})); + +jest.mock('../../../utils/applications', () => ({ + endpointsSummary: { + id: 'endpoints-summary', + breadcrumbLabel: 'Endpoints', + }, +})); + +jest.mock('../../../react-services/navigation-service', () => ({ + getInstance: () => ({ + getUrlForApp: jest.fn().mockReturnValue('http://url'), + __esModule: true, + }), +})); + +jest.mock('./table', () => ({ + AgentStatTable: jest.fn(() => <>), +})); + describe('AgentStats', () => { it('should not render agent info ribbon', async () => { await act(async () => { @@ -65,4 +105,25 @@ describe('AgentStats', () => { ).toHaveLength(7); }); }); + + it('should call the API to fetch the agent stats', async () => { + apiReqMock.mockReset(); + const agentId = '000'; + + await act(async () => { + render(); + }); + + expect(apiReqMock).toHaveBeenCalledTimes(2); + expect(apiReqMock.mock.calls[0]).toEqual([ + 'GET', + `/agents/${agentId}/stats/logcollector`, + {}, + ]); + expect(apiReqMock.mock.calls[1]).toEqual([ + 'GET', + `/agents/${agentId}/stats/agent`, + {}, + ]); + }); }); From daf57932f9febcb7d1123f7c5262b8c4d03c0cd1 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Thu, 31 Oct 2024 14:40:44 -0300 Subject: [PATCH 26/61] test: enhance AgentStats tests to verify API calls with correct agent IDs and endpoints on component updates --- .../agents/stats/agent-stats.test.tsx | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/plugins/main/public/components/agents/stats/agent-stats.test.tsx b/plugins/main/public/components/agents/stats/agent-stats.test.tsx index 72b144b799..b9ba68a82c 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.test.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, act } from '@testing-library/react'; +import { render, act, RenderResult } from '@testing-library/react'; import { AgentStats } from './agent-stats'; import { queryDataTestAttr } from '../../../../test/public/query-attr'; import { CSS } from '../../../../test/utils/CSS'; @@ -106,12 +106,15 @@ describe('AgentStats', () => { }); }); - it('should call the API to fetch the agent stats', async () => { + it('should call api with correct agent ids and endpoints', async () => { apiReqMock.mockReset(); const agentId = '000'; + const agentId2 = '001'; + + let rerender: RenderResult['rerender']; await act(async () => { - render(); + ({ rerender } = render()); }); expect(apiReqMock).toHaveBeenCalledTimes(2); @@ -125,5 +128,21 @@ describe('AgentStats', () => { `/agents/${agentId}/stats/agent`, {}, ]); + + await act(async () => { + rerender(); + }); + + expect(apiReqMock).toHaveBeenCalledTimes(4); + expect(apiReqMock.mock.calls[2]).toEqual([ + 'GET', + `/agents/${agentId2}/stats/logcollector`, + {}, + ]); + expect(apiReqMock.mock.calls[3]).toEqual([ + 'GET', + `/agents/${agentId2}/stats/agent`, + {}, + ]); }); }); From f925e752748717135d0f0b7caaf819b80bf027d4 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Thu, 31 Oct 2024 14:49:05 -0300 Subject: [PATCH 27/61] test: refine AgentStats test description to clarify API call behavior when switching agents --- .../main/public/components/agents/stats/agent-stats.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/main/public/components/agents/stats/agent-stats.test.tsx b/plugins/main/public/components/agents/stats/agent-stats.test.tsx index b9ba68a82c..b95589611d 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.test.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.test.tsx @@ -106,7 +106,7 @@ describe('AgentStats', () => { }); }); - it('should call api with correct agent ids and endpoints', async () => { + it('should call api with correct agent ids and endpoints when changing agent', async () => { apiReqMock.mockReset(); const agentId = '000'; const agentId2 = '001'; From b5d65abd9d8e49bc641901c453d5e69ab28ca272 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 00:03:56 -0300 Subject: [PATCH 28/61] test: improve AgentStats tests to ensure correct column structure, titles, and CSV filename updates on rendering changes --- .../agents/stats/agent-stats.test.tsx | 137 ++++++++++++++++-- 1 file changed, 125 insertions(+), 12 deletions(-) diff --git a/plugins/main/public/components/agents/stats/agent-stats.test.tsx b/plugins/main/public/components/agents/stats/agent-stats.test.tsx index b95589611d..80e28e6344 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.test.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.test.tsx @@ -4,8 +4,13 @@ import { AgentStats } from './agent-stats'; import { queryDataTestAttr } from '../../../../test/public/query-attr'; import { CSS } from '../../../../test/utils/CSS'; import { WzRequest } from '../../../react-services'; +import { AgentStatTable } from './table'; + +const agent000 = '000'; +const agent001 = '001'; const apiReqMock = WzRequest.apiReq as jest.Mock; +const AgentStatTableMock = AgentStatTable as jest.Mock; jest.mock('../../../react-services', () => ({ WzRequest: { @@ -107,42 +112,150 @@ describe('AgentStats', () => { }); it('should call api with correct agent ids and endpoints when changing agent', async () => { - apiReqMock.mockReset(); - const agentId = '000'; - const agentId2 = '001'; + apiReqMock.mockClear(); let rerender: RenderResult['rerender']; await act(async () => { - ({ rerender } = render()); + ({ rerender } = render()); }); expect(apiReqMock).toHaveBeenCalledTimes(2); expect(apiReqMock.mock.calls[0]).toEqual([ 'GET', - `/agents/${agentId}/stats/logcollector`, + `/agents/${agent000}/stats/logcollector`, {}, ]); expect(apiReqMock.mock.calls[1]).toEqual([ 'GET', - `/agents/${agentId}/stats/agent`, + `/agents/${agent000}/stats/agent`, {}, ]); + apiReqMock.mockClear(); + await act(async () => { - rerender(); + rerender(); }); - expect(apiReqMock).toHaveBeenCalledTimes(4); - expect(apiReqMock.mock.calls[2]).toEqual([ + expect(apiReqMock).toHaveBeenCalledTimes(2); + expect(apiReqMock.mock.calls[0]).toEqual([ 'GET', - `/agents/${agentId2}/stats/logcollector`, + `/agents/${agent001}/stats/logcollector`, {}, ]); - expect(apiReqMock.mock.calls[3]).toEqual([ + expect(apiReqMock.mock.calls[1]).toEqual([ 'GET', - `/agents/${agentId2}/stats/agent`, + `/agents/${agent001}/stats/agent`, {}, ]); }); + + it('should maintain column structure across multiple renders', async () => { + AgentStatTableMock.mockClear(); + + const mockColumns = [ + { + field: 'location', + name: 'Location', + sortable: true, + }, + { + field: 'events', + name: 'Events', + sortable: true, + }, + { + field: 'bytes', + name: 'Bytes', + sortable: true, + }, + ]; + + let rerender: RenderResult['rerender']; + + await act(async () => { + ({ rerender } = render()); + }); + + expect(AgentStatTableMock.mock.calls[0][0].columns).toEqual(mockColumns); + expect(AgentStatTableMock.mock.calls[1][0].columns).toEqual(mockColumns); + + AgentStatTableMock.mockClear(); + + await act(async () => { + rerender(); + }); + + expect(AgentStatTableMock.mock.calls[0][0].columns).toEqual(mockColumns); + expect(AgentStatTableMock.mock.calls[1][0].columns).toEqual(mockColumns); + }); + + it('should apply correct titles after render and rerender', async () => { + AgentStatTableMock.mockClear(); + + const mockDataStatLogcollectorTitle = 'Global'; + const mockDataStatAgentTitle = 'Interval'; + + let rerender: RenderResult['rerender']; + + await act(async () => { + ({ rerender } = render()); + }); + + expect(AgentStatTableMock.mock.calls[0][0].title).toEqual( + mockDataStatLogcollectorTitle, + ); + expect(AgentStatTableMock.mock.calls[1][0].title).toEqual( + mockDataStatAgentTitle, + ); + + AgentStatTableMock.mockClear(); + + await act(async () => { + rerender(); + }); + + expect(AgentStatTableMock.mock.calls[0][0].title).toEqual( + mockDataStatLogcollectorTitle, + ); + expect(AgentStatTableMock.mock.calls[1][0].title).toEqual( + mockDataStatAgentTitle, + ); + }); + + it('should update export csv filename correctly on rerender', async () => { + AgentStatTableMock.mockClear(); + + const mockExportCSVFilename = ( + agent000: string, + suffix: 'global' | 'interval', + ) => `agent-stats-${agent000}-logcollector-${suffix}`; + + let rerender: RenderResult['rerender']; + + await act(async () => { + ({ rerender } = render()); + }); + + expect(AgentStatTableMock.mock.calls[0][0].exportCSVFilename).toEqual( + mockExportCSVFilename(agent000, 'global'), + ); + expect(AgentStatTableMock.mock.calls[1][0].exportCSVFilename).toEqual( + mockExportCSVFilename(agent000, 'interval'), + ); + + AgentStatTableMock.mockClear(); + + await act(async () => { + rerender(); + }); + + expect(AgentStatTableMock.mock.calls[0][0].exportCSVFilename).toEqual( + mockExportCSVFilename(agent001, 'global'), + ); + expect(AgentStatTableMock.mock.calls[1][0].exportCSVFilename).toEqual( + mockExportCSVFilename(agent001, 'interval'), + ); + }); }); From 28d05ffab53ce99913fc9553867a13755e4046ed Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 12:23:58 -0300 Subject: [PATCH 29/61] refactor: update breadcrumb types in useGlobalBreadcrumb for improved type safety and readability in context management --- .../components/common/hooks/useGlobalBreadcrumb.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/main/public/components/common/hooks/useGlobalBreadcrumb.ts b/plugins/main/public/components/common/hooks/useGlobalBreadcrumb.ts index 058c343c93..037ac8f393 100644 --- a/plugins/main/public/components/common/hooks/useGlobalBreadcrumb.ts +++ b/plugins/main/public/components/common/hooks/useGlobalBreadcrumb.ts @@ -11,15 +11,16 @@ */ import React, { useEffect } from 'react'; import { useDispatch } from 'react-redux'; -import { updateGlobalBreadcrumb } from '../../../redux/actions/globalBreadcrumbActions'; +import { updateGlobalBreadcrumb } from '../../../redux/actions/globalBreadcrumbActions'; +import { Agent } from '../../endpoints-summary/types'; -type TBreadcrumbSection = {text: string, href?: string} -type TBreadcrumb = TBreadcrumbSection[]; +export type BreadcrumbItem = { text: string; href?: string } | { agent: Agent }; +export type Breadcrumb = BreadcrumbItem[]; // It updates global breadcrumb -export const useGlobalBreadcrumb = (breadcrumb : TBreadcrumb = []) => { +export const useGlobalBreadcrumb = (breadcrumb: Breadcrumb = []) => { const dispatch = useDispatch(); useEffect(() => { - dispatch(updateGlobalBreadcrumb(breadcrumb)) + dispatch(updateGlobalBreadcrumb(breadcrumb)); }); -} +}; From 194cfa7ae236443737037802cd22c0823a764c4f Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 12:24:14 -0300 Subject: [PATCH 30/61] refactor: enhance withGlobalBreadcrumb HOC for better type handling and maintainability in breadcrumb logic --- .../common/hocs/withGlobalBreadcrumb.tsx | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/plugins/main/public/components/common/hocs/withGlobalBreadcrumb.tsx b/plugins/main/public/components/common/hocs/withGlobalBreadcrumb.tsx index 07a2463238..f40a247d95 100644 --- a/plugins/main/public/components/common/hocs/withGlobalBreadcrumb.tsx +++ b/plugins/main/public/components/common/hocs/withGlobalBreadcrumb.tsx @@ -9,15 +9,25 @@ * * Find more information about this on the LICENSE file. */ -import React, { useEffect } from 'react'; -import { useGlobalBreadcrumb } from '../hooks/useGlobalBreadcrumb'; +import React from 'react'; +import { Breadcrumb, useGlobalBreadcrumb } from '../hooks/useGlobalBreadcrumb'; -type TBreadcrumbSection = {text: string, href?: string} | { agent: any }; -type TBreadcrumb = TBreadcrumbSection[]; -type TBreadcrumbParameter = TBreadcrumb | ((props: any) => TBreadcrumb); +type BreadcrumbParam = Breadcrumb | ((props: any) => Breadcrumb); // It returns user permissions -export const withGlobalBreadcrumb = (breadcrumb : TBreadcrumbParameter) => WrappedComponent => props => { - useGlobalBreadcrumb(typeof breadcrumb === 'function' ? breadcrumb(props) : breadcrumb); - return -} +export const withGlobalBreadcrumb = + (breadcrumbParam: BreadcrumbParam) => + (WrappedComponent: React.JSX.Element) => + (props: any) => { + const getBreadcrumb = () => { + if (typeof breadcrumbParam === 'function') { + return breadcrumbParam(props); + } + return breadcrumbParam; + }; + + useGlobalBreadcrumb(getBreadcrumb()); + + // @ts-expect-error + return ; + }; From 57db5113cd524ae5171ee02729722c0f4267226f Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 12:24:24 -0300 Subject: [PATCH 31/61] refactor: replace hardcoded path in agent stats breadcrumb with SECTIONS constant for improved maintainability and readability --- plugins/main/public/components/agents/stats/agent-stats.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/main/public/components/agents/stats/agent-stats.tsx b/plugins/main/public/components/agents/stats/agent-stats.tsx index 8f41f7f196..86269a7fae 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.tsx @@ -45,6 +45,7 @@ import { endpointSummary } from '../../../utils/applications'; import NavigationService from '../../../react-services/navigation-service'; import WzRibbon from '../../common/ribbon/ribbon'; import { Agent } from '../../endpoints-summary/types'; +import { SECTIONS } from '../../../sections'; const tableColumns = [ { @@ -108,7 +109,7 @@ export const MainAgentStats = compose( { text: endpointSummary.breadcrumbLabel, href: NavigationService.getInstance().getUrlForApp(endpointSummary.id, { - path: `#/agents-preview`, + path: `#/${SECTIONS.AGENTS_PREVIEW}`, }), }, { agent }, From 2827472386379858de49ca4ed63b68a404f69889 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 12:24:43 -0300 Subject: [PATCH 32/61] refactor: replace hardcoded agents-preview path with SECTIONS constant for improved maintainability and readability in configuration-main.js --- .../components/management/configuration/configuration-main.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js index 6d71818717..6bb488f618 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js +++ b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js @@ -17,6 +17,7 @@ import { import { compose } from 'redux'; import { endpointSummary, settings } from '../../../../../utils/applications'; import NavigationService from '../../../../../react-services/navigation-service'; +import { SECTIONS } from '../../../../../sections'; export default compose( withErrorBoundary, @@ -31,7 +32,7 @@ export default compose( href: NavigationService.getInstance().getUrlForApp( endpointSummary.id, { - path: `#/agents-preview`, + path: `#/${SECTIONS.AGENTS_PREVIEW}`, }, ), }, From 79acf837e1b51108766ca99f391ad2c51439c7f0 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 12:24:52 -0300 Subject: [PATCH 33/61] refactor: improve agent handling in withGlobalBreadcrumb for better maintainability and readability in configuration-main.js --- .../management/configuration/configuration-main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js index 6bb488f618..3e418c65c6 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js +++ b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js @@ -21,9 +21,9 @@ import { SECTIONS } from '../../../../../sections'; export default compose( withErrorBoundary, - withGlobalBreadcrumb(props => { + withGlobalBreadcrumb(({ agent }) => { let breadcrumb = false; - if (props.agent?.id === '000') { + if (agent?.id === '000') { breadcrumb = [{ text: settings.breadcrumbLabel }]; } else { breadcrumb = [ @@ -36,7 +36,7 @@ export default compose( }, ), }, - { agent: props.agent }, + { agent }, { text: 'Configuration' }, ]; } From fd6fd605f2b765d124773f7c13855e2cc8a31cd4 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 12:25:05 -0300 Subject: [PATCH 34/61] refactor: add global breadcrumb support in AgentView for better navigation and maintainability in index.tsx --- .../components/endpoints-summary/agent/index.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index 01c3851c33..e693722c46 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -39,6 +39,16 @@ export const AgentView = compose( withRouteResolvers({ enableMenu, ip, nestedResolve, savedSearch }), connect(mapStateToProps), withAgentSync, + withGlobalBreadcrumb(() => { + return [ + { + text: endpointSummary.breadcrumbLabel, + href: NavigationService.getInstance().getUrlForApp(endpointSummary.id, { + path: `#/${SECTIONS.AGENTS_PREVIEW}`, + }), + }, + ]; + }), withGuard( props => !(props.agent && props.agent.id), () => ( From 60a8a91c410acdb06e9b256a5bd85237071c2aa5 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 12:25:21 -0300 Subject: [PATCH 35/61] refactor: update unPinAgent to navigate with new URL structure for improved navigation in index.tsx --- .../public/components/endpoints-summary/agent/index.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index e693722c46..1c9a95da2c 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -117,10 +117,8 @@ export const AgentView = compose( } const unPinAgent = () => { - // navigate to the agents preview page - NavigationService.getInstance().navigateToApp(endpointSummary.id, { - path: `#${SECTIONS.AGENTS_PREVIEW}`, - }); + // remove the pinned agent from the URL + navigationService.navigate(`/agents?tab=${tab}`); }; return ( From cd17fd61e4c341c046a6d173923610043258aa15 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 12:25:28 -0300 Subject: [PATCH 36/61] refactor: add withGlobalBreadcrumb HOC to enhance navigation structure in agent index.tsx --- plugins/main/public/components/endpoints-summary/agent/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/main/public/components/endpoints-summary/agent/index.tsx b/plugins/main/public/components/endpoints-summary/agent/index.tsx index 1c9a95da2c..c45207b382 100644 --- a/plugins/main/public/components/endpoints-summary/agent/index.tsx +++ b/plugins/main/public/components/endpoints-summary/agent/index.tsx @@ -6,6 +6,7 @@ import { MainAgentStats } from '../../agents/stats'; import WzManagementConfiguration from '../../../controllers/management/components/management/configuration/configuration-main.js'; import { withErrorBoundary, + withGlobalBreadcrumb, withGuard, withRouteResolvers, } from '../../common/hocs'; From ffebd908939fc848197c737fc6e3692f2f7bc064 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 15:05:19 -0300 Subject: [PATCH 37/61] refactor: enhance AgentStats tests with clearer descriptions for column structure and title checks amidst agent changes --- .../public/components/agents/stats/agent-stats.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/main/public/components/agents/stats/agent-stats.test.tsx b/plugins/main/public/components/agents/stats/agent-stats.test.tsx index 80e28e6344..c0b7ef3399 100644 --- a/plugins/main/public/components/agents/stats/agent-stats.test.tsx +++ b/plugins/main/public/components/agents/stats/agent-stats.test.tsx @@ -151,7 +151,7 @@ describe('AgentStats', () => { ]); }); - it('should maintain column structure across multiple renders', async () => { + it('should maintain column structure across multiple renders, either when changing agent or not', async () => { AgentStatTableMock.mockClear(); const mockColumns = [ @@ -191,7 +191,7 @@ describe('AgentStats', () => { expect(AgentStatTableMock.mock.calls[1][0].columns).toEqual(mockColumns); }); - it('should apply correct titles after render and rerender', async () => { + it('should apply correct titles after render and rerender, either when changing agent or not', async () => { AgentStatTableMock.mockClear(); const mockDataStatLogcollectorTitle = 'Global'; @@ -224,7 +224,7 @@ describe('AgentStats', () => { ); }); - it('should update export csv filename correctly on rerender', async () => { + it('should update export csv filename correctly when changing agent', async () => { AgentStatTableMock.mockClear(); const mockExportCSVFilename = ( From b071b9c8abffb4838d8b3f9b5cd228f62c7453f7 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 15:05:40 -0300 Subject: [PATCH 38/61] refactor: replace jQuery with native DOM method for setting title attribute in breadcrumb configuration component --- .../components/management/configuration/configuration-main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js index 3e418c65c6..52396f7efa 100644 --- a/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js +++ b/plugins/main/public/controllers/management/components/management/configuration/configuration-main.js @@ -40,7 +40,7 @@ export default compose( { text: 'Configuration' }, ]; } - $('#breadcrumbNoTitle').attr('title', ''); + document.querySelector('#breadcrumbNoTitle')?.setAttribute('title', ''); return breadcrumb; }), )(WzConfigurationSwitch); From b993aea7823d149864d37bb864390903ac214c36 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 15:46:41 -0300 Subject: [PATCH 39/61] refactor: improve syscollector metrics tests by adding agent ID handling and verifying data fetching for different agents --- .../components/syscollector-metrics.test.tsx | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx b/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx index a1d42d874b..93ddc36847 100644 --- a/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx @@ -3,6 +3,12 @@ import { render } from '@testing-library/react'; import { InventoryMetrics } from './syscollector-metrics'; import { queryDataTestAttr } from '../../../../../test/public/query-attr'; import { CSS } from '../../../../../test/utils/CSS'; +import { useGenericRequest } from '../../../common/hooks/useGenericRequest'; + +const AGENT_000 = '000'; +const AGENT_001 = '001'; + +let useGenericRequestMock = useGenericRequest as jest.Mock; jest.mock('../../../../react-services/time-service', () => ({ formatUIDate: jest.fn().mockReturnValue('2022-06-27T16:09:49+00:00'), @@ -33,7 +39,9 @@ jest.mock('../../../common/hooks/useGenericRequest', () => ({ describe('Syscollector metrics', () => { it('should render inventory metrics', () => { - const { container } = render(); + const { container } = render( + , + ); const inventoryMetrics = container.querySelector( queryDataTestAttr('syscollector-metrics'), @@ -43,7 +51,9 @@ describe('Syscollector metrics', () => { }); it('should render syscollector ribbon items', () => { - const { container } = render(); + const { container } = render( + , + ); expect( container.querySelector(queryDataTestAttr('ribbon-item-cores')), @@ -85,4 +95,22 @@ describe('Syscollector metrics', () => { ), ).toHaveLength(8); }); + + it('should fetch syscollector data for given agent id either when changing agent or not', async () => { + let { rerender } = render(); + + expect(useGenericRequestMock.mock.calls[0][0].method).toEqual('GET'); + expect(useGenericRequestMock.mock.calls[0][0].path).toEqual( + `/api/syscollector/${AGENT_000}`, + ); + + useGenericRequestMock.mockClear(); + + rerender(); + + expect(useGenericRequestMock.mock.calls[0][0].method).toEqual('GET'); + expect(useGenericRequestMock.mock.calls[0][0].path).toEqual( + `/api/syscollector/${AGENT_001}`, + ); + }); }); From dfe7db8e5878eb60e067bdf9caf13d9dba622216 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 15:59:20 -0300 Subject: [PATCH 40/61] refactor: add unit test for SoftwareTab rendering WindowsUpdatesTable on Windows platform in syscollector agent component --- .../agents/syscollector/software.test.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 plugins/main/public/components/agents/syscollector/software.test.tsx diff --git a/plugins/main/public/components/agents/syscollector/software.test.tsx b/plugins/main/public/components/agents/syscollector/software.test.tsx new file mode 100644 index 0000000000..ed5183e733 --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/software.test.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { WindowsUpdatesTable } from './components'; +import SoftwareTab from './software'; + +let WindowsUpdatesTableMock = WindowsUpdatesTable as jest.Mock; + +jest.mock('./components', () => ({ + WindowsUpdatesTable: jest.fn(() => <>), + PackagesTable: jest.fn(() => <>), +})); + +describe('Software', () => { + it('should render WindowsUpdatesTable when platform is windows', () => { + render(); + + expect(WindowsUpdatesTableMock).toHaveBeenCalled(); + }); +}); From ead93b27a55db64b4a724e2f95423a376a816085 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 16:24:07 -0300 Subject: [PATCH 41/61] refactor: add unit test for WindowsUpdatesTable to verify correct hotfixes endpoint when changing agents in syscollector component --- .../components/windows-updates-table.test.tsx | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx diff --git a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx new file mode 100644 index 0000000000..37907e0c23 --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { WindowsUpdatesTable } from './windows-updates-table'; +import { TableWzAPI } from '../../../common/tables'; + +const AGENT_000 = '000'; +const AGENT_001 = '001'; + +let TableWzAPIMock = TableWzAPI as jest.Mock; + +jest.mock('../../../common/tables', () => ({ + TableWzAPI: jest.fn(() => <>), +})); + +jest.mock('../../../../react-services', () => ({ + WzRequest: { + apiReq: jest.fn().mockResolvedValue({ + data: { + data: { + affected_items: [], + }, + }, + }), + }, +})); + +describe('WindowsUpdatesTable', () => { + it('should render table with correct hotfixes endpoint for agent either when changing agent or not', async () => { + const { rerender } = render( + , + ); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_000}/hotfixes`, + ); + + TableWzAPIMock.mockClear(); + + rerender(); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_001}/hotfixes `, + ); + }); +}); From 1b39e35e190d0516f359ce8f2da4e3e0e8b51786 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 16:27:13 -0300 Subject: [PATCH 42/61] refactor: fix endpoint string in WindowsUpdatesTable test for accurate hotfixes URL when changing agents in syscollector component --- .../syscollector/components/windows-updates-table.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx index 37907e0c23..2849938eff 100644 --- a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx @@ -39,7 +39,7 @@ describe('WindowsUpdatesTable', () => { rerender(); expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_001}/hotfixes `, + `/syscollector/${AGENT_001}/hotfixes`, ); }); }); From 30e08ccacd9da273d4ef82d23f1a8c31b3a0242c Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 16:31:00 -0300 Subject: [PATCH 43/61] refactor: enhance WindowsUpdatesTable test to validate API requests for different agent IDs in syscollector component --- .../components/windows-updates-table.test.tsx | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx index 2849938eff..3b907147f8 100644 --- a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx @@ -2,14 +2,19 @@ import React from 'react'; import { render } from '@testing-library/react'; import { WindowsUpdatesTable } from './windows-updates-table'; import { TableWzAPI } from '../../../common/tables'; +import { WzRequest } from '../../../../react-services'; const AGENT_000 = '000'; const AGENT_001 = '001'; let TableWzAPIMock = TableWzAPI as jest.Mock; +let apiReqMock = WzRequest.apiReq as jest.Mock; jest.mock('../../../common/tables', () => ({ - TableWzAPI: jest.fn(() => <>), + TableWzAPI: jest.fn(({ searchBarWQL }) => { + searchBarWQL.suggestions.value(undefined, { field: 'hotfix' }); + return <>; + }), })); jest.mock('../../../../react-services', () => ({ @@ -42,4 +47,24 @@ describe('WindowsUpdatesTable', () => { `/syscollector/${AGENT_001}/hotfixes`, ); }); + + it('should fetch syscollector data for given agent id either when changing agent or not', async () => { + const { rerender } = render( + , + ); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_000}/hotfixes`, + ); + + apiReqMock.mockClear(); + + rerender(); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_001}/hotfixes`, + ); + }); }); From b633c52c23e4114bbfa99aa2baf2df88e93dfc99 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 16:56:47 -0300 Subject: [PATCH 44/61] refactor: handle potential undefined values in packages-table component for safer access to sorting fields when rendering table --- .../agents/syscollector/components/packages-table.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/main/public/components/agents/syscollector/components/packages-table.tsx b/plugins/main/public/components/agents/syscollector/components/packages-table.tsx index 12ba207111..1daa02e5fa 100644 --- a/plugins/main/public/components/agents/syscollector/components/packages-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/packages-table.tsx @@ -15,11 +15,11 @@ export const PackagesTable = withSOPlatformGuard(({ agent, soPlatform }) => { field) + ?.map(({ field }) => field) .join(',')}`} searchTable downloadCsv From 6d51ac8e80fdf443eb404d1dc175940c009013a8 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 16:57:53 -0300 Subject: [PATCH 45/61] test: add test suite for PackagesTable to validate API requests and table rendering for different agent IDs in syscollector component --- .../components/packages-table.test.tsx | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx diff --git a/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx new file mode 100644 index 0000000000..1c0501d7fe --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { TableWzAPI } from '../../../common/tables'; +import { WzRequest } from '../../../../react-services'; +import { PackagesTable } from './packages-table'; + +const AGENT_000 = '000'; +const AGENT_001 = '001'; + +let TableWzAPIMock = TableWzAPI as jest.Mock; +let apiReqMock = WzRequest.apiReq as jest.Mock; + +jest.mock('../../../common/tables', () => ({ + TableWzAPI: jest.fn(({ searchBarWQL }) => { + searchBarWQL.suggestions.value(undefined, { field: 'hotfix' }); + return <>; + }), +})); + +jest.mock('../../../../react-services', () => ({ + WzRequest: { + apiReq: jest.fn().mockResolvedValue({ + data: { + data: { + affected_items: [], + }, + }, + }), + }, +})); + +jest.mock('./with-so-platform-guard', () => ({ + withSOPlatformGuard: jest.fn(Component => Component), +})); + +describe('PackagesTable', () => { + it('should render table with correct hotfixes endpoint for agent either when changing agent or not', async () => { + const { rerender } = render(); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_000}/packages`, + ); + + TableWzAPIMock.mockClear(); + + rerender(); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_001}/packages`, + ); + }); + + it('should fetch syscollector data for given agent id either when changing agent or not', async () => { + const { rerender } = render(); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_000}/packages`, + ); + + apiReqMock.mockClear(); + + rerender(); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_001}/packages`, + ); + }); +}); From 5ef2550a957ff62af04aac8d6146d1f46f11eb04 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 17:10:55 -0300 Subject: [PATCH 46/61] refactor: safeguard against undefined values for sorting fields in multiple syscollector table components during rendering --- .../syscollector/components/network-interfaces-table.tsx | 2 +- .../agents/syscollector/components/network-ports-table.tsx | 6 +++--- .../agents/syscollector/components/packages-table.tsx | 2 +- .../agents/syscollector/components/processes-table.tsx | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) 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 2fde2feae3..64abfcf3ce 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 @@ -14,7 +14,7 @@ export const NetworkInterfacesTable = ({ agent }) => { field) .join(',')}`} diff --git a/plugins/main/public/components/agents/syscollector/components/network-ports-table.tsx b/plugins/main/public/components/agents/syscollector/components/network-ports-table.tsx index 02490d439a..f2c097557b 100644 --- a/plugins/main/public/components/agents/syscollector/components/network-ports-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/network-ports-table.tsx @@ -16,11 +16,11 @@ export const NetworkPortsTable = withSOPlatformGuard( field) + ?.map(({ field }) => field) .join(',')}`} searchTable downloadCsv @@ -30,7 +30,7 @@ export const NetworkPortsTable = withSOPlatformGuard( suggestions: { field(currentValue) { return portsColumns[soPlatform] - .map(item => ({ + ?.map(item => ({ label: item.field, description: `filter by ${item.name}`, })) diff --git a/plugins/main/public/components/agents/syscollector/components/packages-table.tsx b/plugins/main/public/components/agents/syscollector/components/packages-table.tsx index 1daa02e5fa..e3aff9ba5a 100644 --- a/plugins/main/public/components/agents/syscollector/components/packages-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/packages-table.tsx @@ -29,7 +29,7 @@ export const PackagesTable = withSOPlatformGuard(({ agent, soPlatform }) => { suggestions: { field(currentValue) { return packagesColumns[soPlatform] - .map(item => ({ + ?.map(item => ({ label: item.field, description: `filter by ${item.name}`, })) diff --git a/plugins/main/public/components/agents/syscollector/components/processes-table.tsx b/plugins/main/public/components/agents/syscollector/components/processes-table.tsx index 3b56ce4cad..0b3ef29fdc 100644 --- a/plugins/main/public/components/agents/syscollector/components/processes-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/processes-table.tsx @@ -15,11 +15,11 @@ export const ProcessesTable = withSOPlatformGuard(({ agent, soPlatform }) => { field) + ?.map(({ field }) => field) .join(',')}`} searchTable downloadCsv @@ -29,7 +29,7 @@ export const ProcessesTable = withSOPlatformGuard(({ agent, soPlatform }) => { suggestions: { field(currentValue) { return processColumns[soPlatform] - .map(item => ({ + ?.map(item => ({ label: item.field, description: `filter by ${item.name}`, })) From b6bc5c8733b29057ef2d3d1ecc348745993ea301 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 17:18:19 -0300 Subject: [PATCH 47/61] test: add test suite for NetworkInterfacesTable to verify API requests and rendering behavior for changing agent IDs --- .../network-interfaces-table.test.tsx | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 plugins/main/public/components/agents/syscollector/components/network-interfaces-table.test.tsx diff --git a/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.test.tsx new file mode 100644 index 0000000000..145ba1819d --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.test.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { TableWzAPI } from '../../../common/tables'; +import { WzRequest } from '../../../../react-services'; +import { NetworkInterfacesTable } from './network-interfaces-table'; + +const AGENT_000 = '000'; +const AGENT_001 = '001'; + +let TableWzAPIMock = TableWzAPI as jest.Mock; +let apiReqMock = WzRequest.apiReq as jest.Mock; + +jest.mock('../../../common/tables', () => ({ + TableWzAPI: jest.fn(({ searchBarWQL }) => { + searchBarWQL.suggestions.value(undefined, { field: 'hotfix' }); + return <>; + }), +})); + +jest.mock('../../../../react-services', () => ({ + WzRequest: { + apiReq: jest.fn().mockResolvedValue({ + data: { + data: { + affected_items: [], + }, + }, + }), + }, +})); + +describe('NetworkInterfacesTable', () => { + it('should render table with correct netiface endpoint for agent either when changing agent or not', async () => { + const { rerender } = render( + , + ); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_000}/netiface`, + ); + + TableWzAPIMock.mockClear(); + + rerender(); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_001}/netiface`, + ); + }); + + it('should fetch netiface data for given agent id either when changing agent or not', async () => { + const { rerender } = render( + , + ); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_000}/netiface`, + ); + + apiReqMock.mockClear(); + + rerender(); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_001}/netiface`, + ); + }); +}); From 5a05f76ec27b3faafc2bc5f1862c8c1518ffb219 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 17:18:29 -0300 Subject: [PATCH 48/61] test: update test descriptions in PackagesTable and WindowsUpdatesTable for clarity on data being fetched for given agent IDs --- .../agents/syscollector/components/packages-table.test.tsx | 4 ++-- .../syscollector/components/windows-updates-table.test.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx index 1c0501d7fe..14c1bfb39f 100644 --- a/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx @@ -34,7 +34,7 @@ jest.mock('./with-so-platform-guard', () => ({ })); describe('PackagesTable', () => { - it('should render table with correct hotfixes endpoint for agent either when changing agent or not', async () => { + it('should render table with correct packages endpoint for agent either when changing agent or not', async () => { const { rerender } = render(); expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( @@ -50,7 +50,7 @@ describe('PackagesTable', () => { ); }); - it('should fetch syscollector data for given agent id either when changing agent or not', async () => { + it('should fetch packages data for given agent id either when changing agent or not', async () => { const { rerender } = render(); expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); diff --git a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx index 3b907147f8..6e00e9c922 100644 --- a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx @@ -48,7 +48,7 @@ describe('WindowsUpdatesTable', () => { ); }); - it('should fetch syscollector data for given agent id either when changing agent or not', async () => { + it('should fetch hotfixes data for given agent id either when changing agent or not', async () => { const { rerender } = render( , ); From 9ef5ac00f783769824ca05ccd0eed476ac8e4b40 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 17:21:47 -0300 Subject: [PATCH 49/61] test: add tests for NetworkPortsTable to verify correct API requests and rendering behavior for different agent IDs --- .../components/network-ports-table.test.tsx | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx diff --git a/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx new file mode 100644 index 0000000000..3c4ef3cf98 --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { TableWzAPI } from '../../../common/tables'; +import { WzRequest } from '../../../../react-services'; +import { NetworkPortsTable } from './network-ports-table'; + +const AGENT_000 = '000'; +const AGENT_001 = '001'; + +let TableWzAPIMock = TableWzAPI as jest.Mock; +let apiReqMock = WzRequest.apiReq as jest.Mock; + +jest.mock('../../../common/tables', () => ({ + TableWzAPI: jest.fn(({ searchBarWQL }) => { + searchBarWQL.suggestions.value(undefined, { field: 'hotfix' }); + return <>; + }), +})); + +jest.mock('../../../../react-services', () => ({ + WzRequest: { + apiReq: jest.fn().mockResolvedValue({ + data: { + data: { + affected_items: [], + }, + }, + }), + }, +})); + +jest.mock('./with-so-platform-guard', () => ({ + withSOPlatformGuard: jest.fn(Component => Component), +})); + +describe('NetworkInterfacesTable', () => { + it('should render table with correct ports endpoint for agent either when changing agent or not', async () => { + const { rerender } = render( + , + ); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_000}/ports`, + ); + + TableWzAPIMock.mockClear(); + + rerender(); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_001}/ports`, + ); + }); + + it('should fetch ports data for given agent id either when changing agent or not', async () => { + const { rerender } = render( + , + ); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_000}/ports`, + ); + + apiReqMock.mockClear(); + + rerender(); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_001}/ports`, + ); + }); +}); From adcd04daa3f0a413fb25d741c6c170d37a5ec5ab Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 17:27:10 -0300 Subject: [PATCH 50/61] test: rename test suite to NetworkPortsTable for clarity and proper context in related API request tests --- .../agents/syscollector/components/network-ports-table.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx index 3c4ef3cf98..37d7e076b5 100644 --- a/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx @@ -33,7 +33,7 @@ jest.mock('./with-so-platform-guard', () => ({ withSOPlatformGuard: jest.fn(Component => Component), })); -describe('NetworkInterfacesTable', () => { +describe('NetworkPortsTable', () => { it('should render table with correct ports endpoint for agent either when changing agent or not', async () => { const { rerender } = render( , From 03a99070e55656a1e93fa72dd5d0da2655fffb6e Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 17:27:28 -0300 Subject: [PATCH 51/61] test: add NetworkSettingsTable tests to ensure correct rendering and API requests for changing agent IDs --- .../network-settings-table.test.tsx | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 plugins/main/public/components/agents/syscollector/components/network-settings-table.test.tsx diff --git a/plugins/main/public/components/agents/syscollector/components/network-settings-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/network-settings-table.test.tsx new file mode 100644 index 0000000000..5c9b032146 --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/components/network-settings-table.test.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { TableWzAPI } from '../../../common/tables'; +import { WzRequest } from '../../../../react-services'; +import { NetworkSettingsTable } from './network-settings-table'; + +const AGENT_000 = '000'; +const AGENT_001 = '001'; + +let TableWzAPIMock = TableWzAPI as jest.Mock; +let apiReqMock = WzRequest.apiReq as jest.Mock; + +jest.mock('../../../common/tables', () => ({ + TableWzAPI: jest.fn(({ searchBarWQL }) => { + searchBarWQL.suggestions.value(undefined, { field: 'hotfix' }); + return <>; + }), +})); + +jest.mock('../../../../react-services', () => ({ + WzRequest: { + apiReq: jest.fn().mockResolvedValue({ + data: { + data: { + affected_items: [], + }, + }, + }), + }, +})); + +describe('NetworkSettingsTable', () => { + it('should render table with correct netaddr endpoint for agent either when changing agent or not', async () => { + const { rerender } = render( + , + ); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_000}/netaddr`, + ); + + TableWzAPIMock.mockClear(); + + rerender(); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_001}/netaddr`, + ); + }); + + it('should fetch netaddr data for given agent id either when changing agent or not', async () => { + const { rerender } = render( + , + ); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_000}/netaddr`, + ); + + apiReqMock.mockClear(); + + rerender(); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_001}/netaddr`, + ); + }); +}); From 809de19b3b72a040860ab87db66bbb3d8c4a7502 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Fri, 1 Nov 2024 17:41:34 -0300 Subject: [PATCH 52/61] test: add tests for ProcessesTable to validate rendering and API requests when switching between agent IDs --- .../components/processes-table.test.tsx | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 plugins/main/public/components/agents/syscollector/components/processes-table.test.tsx diff --git a/plugins/main/public/components/agents/syscollector/components/processes-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/processes-table.test.tsx new file mode 100644 index 0000000000..8df50ab5a9 --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/components/processes-table.test.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import { TableWzAPI } from '../../../common/tables'; +import { WzRequest } from '../../../../react-services'; +import { ProcessesTable } from './processes-table'; + +const AGENT_000 = '000'; +const AGENT_001 = '001'; + +let TableWzAPIMock = TableWzAPI as jest.Mock; +let apiReqMock = WzRequest.apiReq as jest.Mock; + +jest.mock('../../../common/tables', () => ({ + TableWzAPI: jest.fn(({ searchBarWQL }) => { + searchBarWQL.suggestions.value(undefined, { field: 'hotfix' }); + return <>; + }), +})); + +jest.mock('../../../../react-services', () => ({ + WzRequest: { + apiReq: jest.fn().mockResolvedValue({ + data: { + data: { + affected_items: [], + }, + }, + }), + }, +})); + +jest.mock('./with-so-platform-guard', () => ({ + withSOPlatformGuard: jest.fn(Component => Component), +})); + +describe('ProcessesTable', () => { + it('should render table with correct processes endpoint for agent either when changing agent or not', async () => { + const { rerender } = render(); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_000}/processes`, + ); + + TableWzAPIMock.mockClear(); + + rerender(); + + expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_001}/processes`, + ); + }); + + it('should fetch processes data for given agent id either when changing agent or not', async () => { + const { rerender } = render(); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_000}/processes`, + ); + + apiReqMock.mockClear(); + + rerender(); + + expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); + expect(apiReqMock.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_001}/processes`, + ); + }); +}); From 2f357dffe525b7eb276f618320adfaa1124a9a95 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Mon, 4 Nov 2024 09:56:38 -0300 Subject: [PATCH 53/61] fix: improve optional chaining to direct access for initial sorting fields in network tables for better readability --- .../syscollector/components/network-interfaces-table.tsx | 2 +- .../agents/syscollector/components/network-ports-table.tsx | 6 +++--- .../agents/syscollector/components/packages-table.tsx | 6 +++--- .../agents/syscollector/components/processes-table.tsx | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) 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 64abfcf3ce..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 @@ -14,7 +14,7 @@ export const NetworkInterfacesTable = ({ agent }) => { field) .join(',')}`} diff --git a/plugins/main/public/components/agents/syscollector/components/network-ports-table.tsx b/plugins/main/public/components/agents/syscollector/components/network-ports-table.tsx index f2c097557b..02490d439a 100644 --- a/plugins/main/public/components/agents/syscollector/components/network-ports-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/network-ports-table.tsx @@ -16,11 +16,11 @@ export const NetworkPortsTable = withSOPlatformGuard( field) + .map(({ field }) => field) .join(',')}`} searchTable downloadCsv @@ -30,7 +30,7 @@ export const NetworkPortsTable = withSOPlatformGuard( suggestions: { field(currentValue) { return portsColumns[soPlatform] - ?.map(item => ({ + .map(item => ({ label: item.field, description: `filter by ${item.name}`, })) diff --git a/plugins/main/public/components/agents/syscollector/components/packages-table.tsx b/plugins/main/public/components/agents/syscollector/components/packages-table.tsx index e3aff9ba5a..12ba207111 100644 --- a/plugins/main/public/components/agents/syscollector/components/packages-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/packages-table.tsx @@ -15,11 +15,11 @@ export const PackagesTable = withSOPlatformGuard(({ agent, soPlatform }) => { field) + .map(({ field }) => field) .join(',')}`} searchTable downloadCsv @@ -29,7 +29,7 @@ export const PackagesTable = withSOPlatformGuard(({ agent, soPlatform }) => { suggestions: { field(currentValue) { return packagesColumns[soPlatform] - ?.map(item => ({ + .map(item => ({ label: item.field, description: `filter by ${item.name}`, })) diff --git a/plugins/main/public/components/agents/syscollector/components/processes-table.tsx b/plugins/main/public/components/agents/syscollector/components/processes-table.tsx index 0b3ef29fdc..3b56ce4cad 100644 --- a/plugins/main/public/components/agents/syscollector/components/processes-table.tsx +++ b/plugins/main/public/components/agents/syscollector/components/processes-table.tsx @@ -15,11 +15,11 @@ export const ProcessesTable = withSOPlatformGuard(({ agent, soPlatform }) => { field) + .map(({ field }) => field) .join(',')}`} searchTable downloadCsv @@ -29,7 +29,7 @@ export const ProcessesTable = withSOPlatformGuard(({ agent, soPlatform }) => { suggestions: { field(currentValue) { return processColumns[soPlatform] - ?.map(item => ({ + .map(item => ({ label: item.field, description: `filter by ${item.name}`, })) From 924e8e6ac1bce5d2ec515c0accecfad30c4d024f Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Mon, 4 Nov 2024 10:29:05 -0300 Subject: [PATCH 54/61] test: introduce reusable functions for validating agent API requests and endpoint rendering in various system collector tables --- .../check-endpoint-for-given-agent-id.tsx | 59 +++++++++++++++++++ .../network-interfaces-table.test.tsx | 52 +++++----------- .../components/network-ports-table.test.tsx | 50 ++++------------ .../network-settings-table.test.tsx | 50 ++++------------ .../components/packages-table.test.tsx | 48 ++++----------- .../components/processes-table.test.tsx | 46 ++++----------- .../components/syscollector-metrics.test.tsx | 6 +- .../components/windows-updates-table.test.tsx | 50 ++++------------ 8 files changed, 140 insertions(+), 221 deletions(-) create mode 100644 plugins/main/public/components/agents/syscollector/components/check-endpoint-for-given-agent-id.tsx diff --git a/plugins/main/public/components/agents/syscollector/components/check-endpoint-for-given-agent-id.tsx b/plugins/main/public/components/agents/syscollector/components/check-endpoint-for-given-agent-id.tsx new file mode 100644 index 0000000000..b67c724ec1 --- /dev/null +++ b/plugins/main/public/components/agents/syscollector/components/check-endpoint-for-given-agent-id.tsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { render } from '@testing-library/react'; + +const AGENT_000 = '000'; +const AGENT_001 = '001'; + +export function shouldRenderTableWithCorrectEndpointForAgent( + mocked: jest.Mock, + Component: React.ComponentType<{ + agent: { id: string }; + soPlatform?: string; + }>, + endpoint: string, + soPlatform: string = 'linux', +) { + const { rerender } = render( + , + ); + + expect(mocked.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_000}/${endpoint}`, + ); + + mocked.mockClear(); + + rerender(); + + expect(mocked.mock.calls[0][0].endpoint).toContain( + `/syscollector/${AGENT_001}/${endpoint}`, + ); +} + +export function shouldFetchDataForGivenAgentId( + mocked: jest.Mock, + Component: React.ComponentType<{ + agent: { id: string }; + soPlatform?: string; + }>, + endpoint: string, + soPlatform: string = 'linux', +) { + const { rerender } = render( + , + ); + + expect(mocked.mock.calls[0][0]).toEqual('GET'); + expect(mocked.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_000}/${endpoint}`, + ); + + mocked.mockClear(); + + rerender(); + + expect(mocked.mock.calls[0][0]).toEqual('GET'); + expect(mocked.mock.calls[0][1]).toEqual( + `/syscollector/${AGENT_001}/${endpoint}`, + ); +} diff --git a/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.test.tsx index 145ba1819d..f3f008703d 100644 --- a/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/network-interfaces-table.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { render } from '@testing-library/react'; import { TableWzAPI } from '../../../common/tables'; import { WzRequest } from '../../../../react-services'; import { NetworkInterfacesTable } from './network-interfaces-table'; +import { + shouldFetchDataForGivenAgentId, + shouldRenderTableWithCorrectEndpointForAgent, +} from './check-endpoint-for-given-agent-id'; -const AGENT_000 = '000'; -const AGENT_001 = '001'; - -let TableWzAPIMock = TableWzAPI as jest.Mock; +let TableWzAPIMock = TableWzAPI as unknown as jest.Mock; let apiReqMock = WzRequest.apiReq as jest.Mock; jest.mock('../../../common/tables', () => ({ @@ -30,41 +30,19 @@ jest.mock('../../../../react-services', () => ({ })); describe('NetworkInterfacesTable', () => { - it('should render table with correct netiface endpoint for agent either when changing agent or not', async () => { - const { rerender } = render( - , - ); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_000}/netiface`, - ); - - TableWzAPIMock.mockClear(); - - rerender(); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_001}/netiface`, + it('should render table with correct netiface endpoint for agent either when changing agent or not', () => { + shouldRenderTableWithCorrectEndpointForAgent( + TableWzAPIMock, + NetworkInterfacesTable, + 'netiface', ); }); - it('should fetch netiface data for given agent id either when changing agent or not', async () => { - const { rerender } = render( - , - ); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_000}/netiface`, - ); - - apiReqMock.mockClear(); - - rerender(); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_001}/netiface`, + it('should fetch netiface data for given agent id either when changing agent or not', () => { + shouldFetchDataForGivenAgentId( + apiReqMock, + NetworkInterfacesTable, + 'netiface', ); }); }); diff --git a/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx index 37d7e076b5..c7cdac4eb6 100644 --- a/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/network-ports-table.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { render } from '@testing-library/react'; import { TableWzAPI } from '../../../common/tables'; import { WzRequest } from '../../../../react-services'; import { NetworkPortsTable } from './network-ports-table'; +import { + shouldFetchDataForGivenAgentId, + shouldRenderTableWithCorrectEndpointForAgent, +} from './check-endpoint-for-given-agent-id'; -const AGENT_000 = '000'; -const AGENT_001 = '001'; - -let TableWzAPIMock = TableWzAPI as jest.Mock; +let TableWzAPIMock = TableWzAPI as unknown as jest.Mock; let apiReqMock = WzRequest.apiReq as jest.Mock; jest.mock('../../../common/tables', () => ({ @@ -34,41 +34,15 @@ jest.mock('./with-so-platform-guard', () => ({ })); describe('NetworkPortsTable', () => { - it('should render table with correct ports endpoint for agent either when changing agent or not', async () => { - const { rerender } = render( - , - ); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_000}/ports`, - ); - - TableWzAPIMock.mockClear(); - - rerender(); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_001}/ports`, + it('should render table with correct ports endpoint for agent either when changing agent or not', () => { + shouldRenderTableWithCorrectEndpointForAgent( + TableWzAPIMock, + NetworkPortsTable, + 'ports', ); }); - it('should fetch ports data for given agent id either when changing agent or not', async () => { - const { rerender } = render( - , - ); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_000}/ports`, - ); - - apiReqMock.mockClear(); - - rerender(); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_001}/ports`, - ); + it('should fetch ports data for given agent id either when changing agent or not', () => { + shouldFetchDataForGivenAgentId(apiReqMock, NetworkPortsTable, 'ports'); }); }); diff --git a/plugins/main/public/components/agents/syscollector/components/network-settings-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/network-settings-table.test.tsx index 5c9b032146..68496ded70 100644 --- a/plugins/main/public/components/agents/syscollector/components/network-settings-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/network-settings-table.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { render } from '@testing-library/react'; import { TableWzAPI } from '../../../common/tables'; import { WzRequest } from '../../../../react-services'; import { NetworkSettingsTable } from './network-settings-table'; +import { + shouldFetchDataForGivenAgentId, + shouldRenderTableWithCorrectEndpointForAgent, +} from './check-endpoint-for-given-agent-id'; -const AGENT_000 = '000'; -const AGENT_001 = '001'; - -let TableWzAPIMock = TableWzAPI as jest.Mock; +let TableWzAPIMock = TableWzAPI as unknown as jest.Mock; let apiReqMock = WzRequest.apiReq as jest.Mock; jest.mock('../../../common/tables', () => ({ @@ -30,41 +30,15 @@ jest.mock('../../../../react-services', () => ({ })); describe('NetworkSettingsTable', () => { - it('should render table with correct netaddr endpoint for agent either when changing agent or not', async () => { - const { rerender } = render( - , - ); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_000}/netaddr`, - ); - - TableWzAPIMock.mockClear(); - - rerender(); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_001}/netaddr`, + it('should render table with correct netaddr endpoint for agent either when changing agent or not', () => { + shouldRenderTableWithCorrectEndpointForAgent( + TableWzAPIMock, + NetworkSettingsTable, + 'netaddr', ); }); - it('should fetch netaddr data for given agent id either when changing agent or not', async () => { - const { rerender } = render( - , - ); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_000}/netaddr`, - ); - - apiReqMock.mockClear(); - - rerender(); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_001}/netaddr`, - ); + it('should fetch netaddr data for given agent id either when changing agent or not', () => { + shouldFetchDataForGivenAgentId(apiReqMock, NetworkSettingsTable, 'netaddr'); }); }); diff --git a/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx index 14c1bfb39f..155845b12f 100644 --- a/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/packages-table.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { render } from '@testing-library/react'; +import { PackagesTable } from './packages-table'; import { TableWzAPI } from '../../../common/tables'; import { WzRequest } from '../../../../react-services'; -import { PackagesTable } from './packages-table'; +import { + shouldFetchDataForGivenAgentId, + shouldRenderTableWithCorrectEndpointForAgent, +} from './check-endpoint-for-given-agent-id'; -const AGENT_000 = '000'; -const AGENT_001 = '001'; - -let TableWzAPIMock = TableWzAPI as jest.Mock; +let TableWzAPIMock = TableWzAPI as unknown as jest.Mock; let apiReqMock = WzRequest.apiReq as jest.Mock; jest.mock('../../../common/tables', () => ({ @@ -34,37 +34,15 @@ jest.mock('./with-so-platform-guard', () => ({ })); describe('PackagesTable', () => { - it('should render table with correct packages endpoint for agent either when changing agent or not', async () => { - const { rerender } = render(); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_000}/packages`, - ); - - TableWzAPIMock.mockClear(); - - rerender(); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_001}/packages`, + it('should render table with correct packages endpoint for agent either when changing agent or not', () => { + shouldRenderTableWithCorrectEndpointForAgent( + TableWzAPIMock, + PackagesTable, + 'packages', ); }); - it('should fetch packages data for given agent id either when changing agent or not', async () => { - const { rerender } = render(); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_000}/packages`, - ); - - apiReqMock.mockClear(); - - rerender(); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_001}/packages`, - ); + it('should fetch packages data for given agent id either when changing agent or not', () => { + shouldFetchDataForGivenAgentId(apiReqMock, PackagesTable, 'packages'); }); }); diff --git a/plugins/main/public/components/agents/syscollector/components/processes-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/processes-table.test.tsx index 8df50ab5a9..259f0609a3 100644 --- a/plugins/main/public/components/agents/syscollector/components/processes-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/processes-table.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { render } from '@testing-library/react'; import { TableWzAPI } from '../../../common/tables'; import { WzRequest } from '../../../../react-services'; import { ProcessesTable } from './processes-table'; +import { + shouldFetchDataForGivenAgentId, + shouldRenderTableWithCorrectEndpointForAgent, +} from './check-endpoint-for-given-agent-id'; -const AGENT_000 = '000'; -const AGENT_001 = '001'; - -let TableWzAPIMock = TableWzAPI as jest.Mock; +let TableWzAPIMock = TableWzAPI as unknown as jest.Mock; let apiReqMock = WzRequest.apiReq as jest.Mock; jest.mock('../../../common/tables', () => ({ @@ -34,37 +34,15 @@ jest.mock('./with-so-platform-guard', () => ({ })); describe('ProcessesTable', () => { - it('should render table with correct processes endpoint for agent either when changing agent or not', async () => { - const { rerender } = render(); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_000}/processes`, - ); - - TableWzAPIMock.mockClear(); - - rerender(); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_001}/processes`, + it('should render table with correct processes endpoint for agent either when changing agent or not', () => { + shouldRenderTableWithCorrectEndpointForAgent( + TableWzAPIMock, + ProcessesTable, + 'processes', ); }); - it('should fetch processes data for given agent id either when changing agent or not', async () => { - const { rerender } = render(); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_000}/processes`, - ); - - apiReqMock.mockClear(); - - rerender(); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_001}/processes`, - ); + it('should fetch processes data for given agent id either when changing agent or not', () => { + shouldFetchDataForGivenAgentId(apiReqMock, ProcessesTable, 'processes'); }); }); diff --git a/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx b/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx index 93ddc36847..cd344068b8 100644 --- a/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/syscollector-metrics.test.tsx @@ -40,6 +40,7 @@ jest.mock('../../../common/hooks/useGenericRequest', () => ({ describe('Syscollector metrics', () => { it('should render inventory metrics', () => { const { container } = render( + // @ts-expect-error , ); @@ -52,6 +53,7 @@ describe('Syscollector metrics', () => { it('should render syscollector ribbon items', () => { const { container } = render( + // @ts-expect-error , ); @@ -96,7 +98,8 @@ describe('Syscollector metrics', () => { ).toHaveLength(8); }); - it('should fetch syscollector data for given agent id either when changing agent or not', async () => { + it('should fetch syscollector data for given agent id either when changing agent or not', () => { + // @ts-expect-error let { rerender } = render(); expect(useGenericRequestMock.mock.calls[0][0].method).toEqual('GET'); @@ -106,6 +109,7 @@ describe('Syscollector metrics', () => { useGenericRequestMock.mockClear(); + // @ts-expect-error rerender(); expect(useGenericRequestMock.mock.calls[0][0].method).toEqual('GET'); diff --git a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx index 6e00e9c922..813e2edcb1 100644 --- a/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx +++ b/plugins/main/public/components/agents/syscollector/components/windows-updates-table.test.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { render } from '@testing-library/react'; import { WindowsUpdatesTable } from './windows-updates-table'; import { TableWzAPI } from '../../../common/tables'; import { WzRequest } from '../../../../react-services'; +import { + shouldFetchDataForGivenAgentId, + shouldRenderTableWithCorrectEndpointForAgent, +} from './check-endpoint-for-given-agent-id'; -const AGENT_000 = '000'; -const AGENT_001 = '001'; - -let TableWzAPIMock = TableWzAPI as jest.Mock; +let TableWzAPIMock = TableWzAPI as unknown as jest.Mock; let apiReqMock = WzRequest.apiReq as jest.Mock; jest.mock('../../../common/tables', () => ({ @@ -30,41 +30,15 @@ jest.mock('../../../../react-services', () => ({ })); describe('WindowsUpdatesTable', () => { - it('should render table with correct hotfixes endpoint for agent either when changing agent or not', async () => { - const { rerender } = render( - , - ); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_000}/hotfixes`, - ); - - TableWzAPIMock.mockClear(); - - rerender(); - - expect(TableWzAPIMock.mock.calls[0][0].endpoint).toContain( - `/syscollector/${AGENT_001}/hotfixes`, + it('should render table with correct hotfixes endpoint for agent either when changing agent or not', () => { + shouldRenderTableWithCorrectEndpointForAgent( + TableWzAPIMock, + WindowsUpdatesTable, + 'hotfixes', ); }); - it('should fetch hotfixes data for given agent id either when changing agent or not', async () => { - const { rerender } = render( - , - ); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_000}/hotfixes`, - ); - - apiReqMock.mockClear(); - - rerender(); - - expect(apiReqMock.mock.calls[0][0]).toEqual('GET'); - expect(apiReqMock.mock.calls[0][1]).toEqual( - `/syscollector/${AGENT_001}/hotfixes`, - ); + it('should fetch hotfixes data for given agent id either when changing agent or not', () => { + shouldFetchDataForGivenAgentId(apiReqMock, WindowsUpdatesTable, 'hotfixes'); }); }); From b8d6154d077f02ed9f2b23d9e618b2658728794d Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Mon, 4 Nov 2024 16:24:50 -0300 Subject: [PATCH 55/61] ci: update GitHub Actions workflows to use actions/upload-artifact@v4 and clean up formatting across YAML files --- .github/workflows/cypress-basic.yml | 22 +++++++++++----------- .github/workflows/cypress-odfe.yml | 24 ++++++++++++------------ .github/workflows/cypress-wzd.yml | 22 +++++++++++----------- .github/workflows/cypress-xpack.yml | 22 +++++++++++----------- .github/workflows/dev-environment.yml | 2 +- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/.github/workflows/cypress-basic.yml b/.github/workflows/cypress-basic.yml index e0465d7e2c..f5e84be2cb 100644 --- a/.github/workflows/cypress-basic.yml +++ b/.github/workflows/cypress-basic.yml @@ -12,18 +12,18 @@ on: description: 'Wazuh Version' default: 'v4.3.4' required: true - elastic-version: + elastic-version: description: 'Elastic Version' default: '7.16.3' required: true - ubuntu-cypress-version: + ubuntu-cypress-version: description: 'Ubuntu Cypress Version' default: '3.0.0' required: true url-package: description: 'Package Download Url' - required: false - default: 'https://packages-dev.wazuh.com/pre-release/ui/kibana/wazuh_kibana-4.3.4_7.16.3-1.zip' + required: false + default: 'https://packages-dev.wazuh.com/pre-release/ui/kibana/wazuh_kibana-4.3.4_7.16.3-1.zip' # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -40,8 +40,8 @@ jobs: elastic-version: ${{ github.event.inputs.elastic-version }} ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} url-package: ${{ github.event.inputs.url-package }}" - - - name: Step 02 - Download Project wazuh-app-environments + + - name: Step 02 - Download Project wazuh-app-environments uses: actions/checkout@v2 with: repository: matiasmoreno876/wazuh-app-environments @@ -62,7 +62,7 @@ jobs: cd ${{ env.PATH_TEMPLATE }} docker-compose up -d echo CONTINUES AFTER 15 SECONDS ... - sleep 15s + sleep 15s - name: Step 05 - Installing package from url run: | cd ${{ env.PATH_TEMPLATE }} @@ -81,13 +81,13 @@ jobs: run: | cd ${{ env.PATH_TEMPLATE }} docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:basic" | tee cypress.log - continue-on-error: true + continue-on-error: true - name: Step 08 - Run Cypress reports run: | cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" - name: Step 09 - Archive reports - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: cypress-reports_BASIC_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.elastic-version }} path: ${{ env.PATH_TEMPLATE }}/report/* @@ -110,4 +110,4 @@ jobs: # For posting a simple plain text message slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" env: - SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} \ No newline at end of file + SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} diff --git a/.github/workflows/cypress-odfe.yml b/.github/workflows/cypress-odfe.yml index e95263a91a..6d99360008 100644 --- a/.github/workflows/cypress-odfe.yml +++ b/.github/workflows/cypress-odfe.yml @@ -12,22 +12,22 @@ on: description: 'Wazuh Version' default: 'v4.3.4' required: true - elastic-version: + elastic-version: description: 'Elastic Version' default: '7.10.2' required: true - odfe-version: + odfe-version: description: 'ODFE Version' default: '1.13.2' required: true - ubuntu-cypress-version: + ubuntu-cypress-version: description: 'Ubuntu Cypress Version' default: '3.0.0' required: true url-package: description: 'Package Download Url' - required: false - default: 'https://packages-dev.wazuh.com/pre-release/ui/kibana/wazuh_kibana-4.3.4_7.16.3-1.zip' + required: false + default: 'https://packages-dev.wazuh.com/pre-release/ui/kibana/wazuh_kibana-4.3.4_7.16.3-1.zip' # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -45,8 +45,8 @@ jobs: odfe-version: ${{ github.event.inputs.odfe-version }} ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} url-package: ${{ github.event.inputs.url-package }}" - - - name: Step 02 - Download Project wazuh-app-environments + + - name: Step 02 - Download Project wazuh-app-environments uses: actions/checkout@v2 with: repository: matiasmoreno876/wazuh-app-environments @@ -68,7 +68,7 @@ jobs: cd ${{ env.PATH_TEMPLATE }} docker-compose up -d echo CONTINUES AFTER 15 SECONDS ... - sleep 15s + sleep 15s - name: Step 05 - Installing package from url run: | cd ${{ env.PATH_TEMPLATE }} @@ -87,13 +87,13 @@ jobs: run: | cd ${{ env.PATH_TEMPLATE }} docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:odfe" | tee cypress.log - continue-on-error: true + continue-on-error: true - name: Step 08 - Run Cypress reports run: | cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" - name: Step 09 - Archive reports - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: cypress-reports_ODFE_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.odfe-version }}-${{ github.event.inputs.elastic-version }} path: ${{ env.PATH_TEMPLATE }}/report/* @@ -116,4 +116,4 @@ jobs: # For posting a simple plain text message slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nODFE version: ${{ github.event.inputs.odfe-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" env: - SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} \ No newline at end of file + SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} diff --git a/.github/workflows/cypress-wzd.yml b/.github/workflows/cypress-wzd.yml index 8e0b051142..3db2236d73 100644 --- a/.github/workflows/cypress-wzd.yml +++ b/.github/workflows/cypress-wzd.yml @@ -12,14 +12,14 @@ on: description: 'Wazuh Stack Version' default: '4.3.4' required: true - ubuntu-cypress-version: + ubuntu-cypress-version: description: 'Ubuntu Cypress Version' default: '3.0.0' required: true url-package: description: 'Package Download Url' - required: false - default: 'https://packages-dev.wazuh.com/pre-release/ui/dashboard/wazuh-4.3.4-1.zip' + required: false + default: 'https://packages-dev.wazuh.com/pre-release/ui/dashboard/wazuh-4.3.4-1.zip' # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -35,8 +35,8 @@ jobs: wazuh-stack-version: ${{ github.event.inputs.wazuh-stack-version }} ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} url-package: ${{ github.event.inputs.url-package }}" - - - name: Step 02 - Download Project wazuh-app-environments + + - name: Step 02 - Download Project wazuh-app-environments uses: actions/checkout@v2 with: repository: matiasmoreno876/wazuh-app-environments @@ -56,7 +56,7 @@ jobs: cd ${{ env.PATH_TEMPLATE }} docker-compose up -d echo CONTINUES AFTER 30 SECONDS ... - sleep 30s + sleep 30s - name: Step 05 - Remove Wazuh run: | cd ${{ env.PATH_TEMPLATE }} @@ -64,7 +64,7 @@ jobs: docker-compose restart wazuh.dashboard echo CONTINUES AFTER 30 SECONDS ... sleep 30s - docker-compose ps + docker-compose ps - name: Step 06 - Installing package from url run: | cd ${{ env.PATH_TEMPLATE }} @@ -78,13 +78,13 @@ jobs: run: | cd ${{ env.PATH_TEMPLATE }} docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:wzd" | tee cypress.log - continue-on-error: true + continue-on-error: true - name: Step 08 - Run Cypress reports run: | cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" - name: Step 09 - Archive reports - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: cypress-reports_WZD_${{ github.event.inputs.wazuh-stack-version }} path: ${{ env.PATH_TEMPLATE }}/report/* @@ -107,4 +107,4 @@ jobs: # For posting a simple plain text message slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh stack version: ${{ github.event.inputs.wazuh-stack-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" env: - SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} \ No newline at end of file + SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} diff --git a/.github/workflows/cypress-xpack.yml b/.github/workflows/cypress-xpack.yml index a16f888eff..0d3c1d2f98 100644 --- a/.github/workflows/cypress-xpack.yml +++ b/.github/workflows/cypress-xpack.yml @@ -12,18 +12,18 @@ on: description: 'Wazuh Version' default: 'v4.3.4' required: true - elastic-version: + elastic-version: description: 'Elastic Version' default: '7.16.3' required: true - ubuntu-cypress-version: + ubuntu-cypress-version: description: 'Ubuntu Cypress Version' default: '3.0.0' required: true url-package: description: 'Package Download Url' - required: false - default: 'https://packages-dev.wazuh.com/pre-release/ui/kibana/wazuh_kibana-4.3.4_7.16.3-1.zip' + required: false + default: 'https://packages-dev.wazuh.com/pre-release/ui/kibana/wazuh_kibana-4.3.4_7.16.3-1.zip' # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -40,8 +40,8 @@ jobs: elastic-version: ${{ github.event.inputs.elastic-version }} ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} url-package: ${{ github.event.inputs.url-package }}" - - - name: Step 02 - Download Project wazuh-app-environments + + - name: Step 02 - Download Project wazuh-app-environments uses: actions/checkout@v2 with: repository: matiasmoreno876/wazuh-app-environments @@ -63,7 +63,7 @@ jobs: sed -i -e 's|docker-compose exec elasticsearch|docker exec $(docker-compose ps -q elasticsearch)|g' ./setup.sh sudo sh setup.sh echo CONTINUES AFTER 15 SECONDS ... - sleep 15s + sleep 15s - name: Step 05 - Installing package from url run: | cd ${{ env.PATH_TEMPLATE }} @@ -82,13 +82,13 @@ jobs: run: | cd ${{ env.PATH_TEMPLATE }} docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:xpack" | tee cypress.log - continue-on-error: true + continue-on-error: true - name: Step 08 - Run Cypress reports run: | cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" - name: Step 09 - Archive reports - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: cypress-reports_XPACK_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.elastic-version }} path: ${{ env.PATH_TEMPLATE }}/report/* @@ -111,4 +111,4 @@ jobs: # For posting a simple plain text message slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" env: - SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} \ No newline at end of file + SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} diff --git a/.github/workflows/dev-environment.yml b/.github/workflows/dev-environment.yml index 1fd2f9c080..32f0e7ac37 100644 --- a/.github/workflows/dev-environment.yml +++ b/.github/workflows/dev-environment.yml @@ -115,7 +115,7 @@ jobs: - name: Step 04 - Upload artifact to GitHub if: ${{ inputs.artifact_name && inputs.artifact_path }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ inputs.artifact_name }}_${{ env.version }}-${{ env.revision }}_${{ inputs.reference }}.zip path: ${{ matrix.plugins.path }}/${{ inputs.artifact_path }} From 2119a3f80cbe0341ad504c9e4567fa6ed289d898 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Mon, 4 Nov 2024 16:27:12 -0300 Subject: [PATCH 56/61] ci: upgrade actions/checkout to v4 across multiple workflows for consistency and improved features --- .github/actions/comment-test-coverage/README.md | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/cypress-basic.yml | 2 +- .github/workflows/cypress-odfe.yml | 2 +- .github/workflows/cypress-wzd.yml | 2 +- .github/workflows/cypress-xpack.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/dev-environment.yml | 2 +- .github/workflows/eslint.yml | 2 +- .github/workflows/manual-build.yml | 2 +- .github/workflows/prettier.yml | 2 +- .github/workflows/wazuh-build-push-docker-action.yml | 6 +++--- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/actions/comment-test-coverage/README.md b/.github/actions/comment-test-coverage/README.md index e86b5f2238..b20a220ab1 100644 --- a/.github/actions/comment-test-coverage/README.md +++ b/.github/actions/comment-test-coverage/README.md @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code - uses: actions/checkout@v1 + uses: actions/checkout@v4 - name: Run Jasmine tests run: npm run test -- --no-watch --no-progress --browsers=ChromeHeadlessCI diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0b144db595..f6e5d5feaa 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/cypress-basic.yml b/.github/workflows/cypress-basic.yml index f5e84be2cb..5e7c824b7a 100644 --- a/.github/workflows/cypress-basic.yml +++ b/.github/workflows/cypress-basic.yml @@ -42,7 +42,7 @@ jobs: url-package: ${{ github.event.inputs.url-package }}" - name: Step 02 - Download Project wazuh-app-environments - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: repository: matiasmoreno876/wazuh-app-environments ref: 'master' diff --git a/.github/workflows/cypress-odfe.yml b/.github/workflows/cypress-odfe.yml index 6d99360008..d8fe5d7d41 100644 --- a/.github/workflows/cypress-odfe.yml +++ b/.github/workflows/cypress-odfe.yml @@ -47,7 +47,7 @@ jobs: url-package: ${{ github.event.inputs.url-package }}" - name: Step 02 - Download Project wazuh-app-environments - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: repository: matiasmoreno876/wazuh-app-environments ref: 'master' diff --git a/.github/workflows/cypress-wzd.yml b/.github/workflows/cypress-wzd.yml index 3db2236d73..0669e3709d 100644 --- a/.github/workflows/cypress-wzd.yml +++ b/.github/workflows/cypress-wzd.yml @@ -37,7 +37,7 @@ jobs: url-package: ${{ github.event.inputs.url-package }}" - name: Step 02 - Download Project wazuh-app-environments - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: repository: matiasmoreno876/wazuh-app-environments ref: 'master' diff --git a/.github/workflows/cypress-xpack.yml b/.github/workflows/cypress-xpack.yml index 0d3c1d2f98..7fc5a8d321 100644 --- a/.github/workflows/cypress-xpack.yml +++ b/.github/workflows/cypress-xpack.yml @@ -42,7 +42,7 @@ jobs: url-package: ${{ github.event.inputs.url-package }}" - name: Step 02 - Download Project wazuh-app-environments - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: repository: matiasmoreno876/wazuh-app-environments ref: 'master' diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index fe461b4243..5545cd23be 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -15,6 +15,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Dependency Review' uses: actions/dependency-review-action@v2 diff --git a/.github/workflows/dev-environment.yml b/.github/workflows/dev-environment.yml index 32f0e7ac37..221a12de0f 100644 --- a/.github/workflows/dev-environment.yml +++ b/.github/workflows/dev-environment.yml @@ -68,7 +68,7 @@ jobs: steps: - name: Step 01 - Download the plugin's source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: wazuh/wazuh-dashboard-plugins ref: ${{ inputs.reference }} diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index 38954d9028..048e25207f 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -19,7 +19,7 @@ jobs: steps: # https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 # - https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#node-version-file - name: Install NodeJS diff --git a/.github/workflows/manual-build.yml b/.github/workflows/manual-build.yml index 4452e637dd..60617c25ac 100644 --- a/.github/workflows/manual-build.yml +++ b/.github/workflows/manual-build.yml @@ -39,7 +39,7 @@ jobs: steps: - name: Step 01 - Download the plugin's source code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: wazuh/wazuh-dashboard-plugins ref: ${{ inputs.reference }} diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml index 23de4aa1e6..224bdebb8b 100644 --- a/.github/workflows/prettier.yml +++ b/.github/workflows/prettier.yml @@ -10,7 +10,7 @@ jobs: steps: # https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 # - https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#node-version-file - name: Install NodeJS diff --git a/.github/workflows/wazuh-build-push-docker-action.yml b/.github/workflows/wazuh-build-push-docker-action.yml index 74be8e29e1..e6cbcd66e2 100644 --- a/.github/workflows/wazuh-build-push-docker-action.yml +++ b/.github/workflows/wazuh-build-push-docker-action.yml @@ -56,7 +56,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Step 01 - Download wazuh-kibana-app - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: path: wazuh-kibana-app - name: Step 02 - Login to quay.io @@ -80,7 +80,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Step 01 - Download wazuh-kibana-app - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: path: wazuh-kibana-app - name: Step 02 - Login to quay.io @@ -101,7 +101,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Step 01 - Download wazuh-kibana-app - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: path: wazuh-kibana-app - name: Step 02 - Login to quay.io From be7a9ad8d97227fbafb979afc0f58f3a76ce15a0 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Mon, 4 Nov 2024 16:32:20 -0300 Subject: [PATCH 57/61] ci: upgrade Node.js setup to actions/setup-node@v4 in eslint and prettier workflows for enhanced performance and consistency --- .github/workflows/eslint.yml | 2 +- .github/workflows/prettier.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index 048e25207f..a5cf29df76 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -23,7 +23,7 @@ jobs: # - https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#node-version-file - name: Install NodeJS - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml index 224bdebb8b..4e62af22ed 100644 --- a/.github/workflows/prettier.yml +++ b/.github/workflows/prettier.yml @@ -14,7 +14,7 @@ jobs: # - https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#node-version-file - name: Install NodeJS - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' From ece4522e6523849374c32c1d830a7d332a600fef Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Mon, 4 Nov 2024 16:33:25 -0300 Subject: [PATCH 58/61] ci: update manual-build workflow to use actions/download-artifact@v4 for improved functionality and consistency with other workflows --- .github/workflows/manual-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manual-build.yml b/.github/workflows/manual-build.yml index 60617c25ac..ed727fa7c5 100644 --- a/.github/workflows/manual-build.yml +++ b/.github/workflows/manual-build.yml @@ -53,7 +53,7 @@ jobs: echo "versionPlatform=$(jq -r '.pluginPlatform.version' $(pwd)/wazuh/plugins/main/package.json)" >> $GITHUB_ENV - name: Step 03 - Download the plugin's source code - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: wazuh-dashboard-plugins_${{ env.version }}-${{ env.revision }}_${{ inputs.reference }}.zip path: ${{ env.currentDir }}/wazuh/scripts/test-packages/wazuh-dashboard-plugins_${{ env.version }}-${{ env.revision }}_${{ inputs.reference }}.zip From 6701488add3590ac7bcd22c8616245238c0334f5 Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Mon, 4 Nov 2024 16:34:26 -0300 Subject: [PATCH 59/61] ci: upgrade actions/dependency-review-action to v4 for enhanced functionality and consistency in dependency review process --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 5545cd23be..0d4a01360d 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -17,4 +17,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@v4 - name: 'Dependency Review' - uses: actions/dependency-review-action@v2 + uses: actions/dependency-review-action@v4 From 26a4d284172b298cacf3cc47c0f5ae7d4b8c8eba Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 5 Nov 2024 12:25:14 -0300 Subject: [PATCH 60/61] ci: add overwrite option in Cypress report workflows for improved file handling and consistency across all test configurations --- .github/workflows/cypress-basic.yml | 1 + .github/workflows/cypress-odfe.yml | 1 + .github/workflows/cypress-wzd.yml | 1 + .github/workflows/cypress-xpack.yml | 1 + .github/workflows/dev-environment.yml | 1 + .github/workflows/manual-build.yml | 1 + 6 files changed, 6 insertions(+) diff --git a/.github/workflows/cypress-basic.yml b/.github/workflows/cypress-basic.yml index 5e7c824b7a..931295d300 100644 --- a/.github/workflows/cypress-basic.yml +++ b/.github/workflows/cypress-basic.yml @@ -91,6 +91,7 @@ jobs: with: name: cypress-reports_BASIC_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.elastic-version }} path: ${{ env.PATH_TEMPLATE }}/report/* + overwrite: true - name: Step 10 - Log parsing run: | cd ${{ env.PATH_TEMPLATE }} diff --git a/.github/workflows/cypress-odfe.yml b/.github/workflows/cypress-odfe.yml index d8fe5d7d41..0405b7184a 100644 --- a/.github/workflows/cypress-odfe.yml +++ b/.github/workflows/cypress-odfe.yml @@ -97,6 +97,7 @@ jobs: with: name: cypress-reports_ODFE_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.odfe-version }}-${{ github.event.inputs.elastic-version }} path: ${{ env.PATH_TEMPLATE }}/report/* + overwrite: true - name: Step 10 - Log parsing run: | cd ${{ env.PATH_TEMPLATE }} diff --git a/.github/workflows/cypress-wzd.yml b/.github/workflows/cypress-wzd.yml index 0669e3709d..dc6155ef83 100644 --- a/.github/workflows/cypress-wzd.yml +++ b/.github/workflows/cypress-wzd.yml @@ -88,6 +88,7 @@ jobs: with: name: cypress-reports_WZD_${{ github.event.inputs.wazuh-stack-version }} path: ${{ env.PATH_TEMPLATE }}/report/* + overwrite: true - name: Step 10 - Log parsing run: | cd ${{ env.PATH_TEMPLATE }} diff --git a/.github/workflows/cypress-xpack.yml b/.github/workflows/cypress-xpack.yml index 7fc5a8d321..03a3a69e67 100644 --- a/.github/workflows/cypress-xpack.yml +++ b/.github/workflows/cypress-xpack.yml @@ -92,6 +92,7 @@ jobs: with: name: cypress-reports_XPACK_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.elastic-version }} path: ${{ env.PATH_TEMPLATE }}/report/* + overwrite: true - name: Step 10 - Log parsing run: | cd ${{ env.PATH_TEMPLATE }} diff --git a/.github/workflows/dev-environment.yml b/.github/workflows/dev-environment.yml index 221a12de0f..b526d86a43 100644 --- a/.github/workflows/dev-environment.yml +++ b/.github/workflows/dev-environment.yml @@ -120,6 +120,7 @@ jobs: name: ${{ inputs.artifact_name }}_${{ env.version }}-${{ env.revision }}_${{ inputs.reference }}.zip path: ${{ matrix.plugins.path }}/${{ inputs.artifact_path }} if-no-files-found: 'error' + overwrite: true - name: Step 05 - Upload coverage results to GitHub if: ${{ inputs.notify_jest_coverage_summary && github.event_name == 'pull_request' }} diff --git a/.github/workflows/manual-build.yml b/.github/workflows/manual-build.yml index ed727fa7c5..a42e4e4566 100644 --- a/.github/workflows/manual-build.yml +++ b/.github/workflows/manual-build.yml @@ -57,6 +57,7 @@ jobs: with: name: wazuh-dashboard-plugins_${{ env.version }}-${{ env.revision }}_${{ inputs.reference }}.zip path: ${{ env.currentDir }}/wazuh/scripts/test-packages/wazuh-dashboard-plugins_${{ env.version }}-${{ env.revision }}_${{ inputs.reference }}.zip + overwrite: true - name: Step 04 - Build the Docker image run: | From 32506baad91b246d7fb1c73042324ea70785bdbc Mon Sep 17 00:00:00 2001 From: Guido Modarelli Date: Tue, 5 Nov 2024 12:31:35 -0300 Subject: [PATCH 61/61] ci: standardize YAML formatting in workflows for better readability and consistency across all templates and steps --- .github/workflows/codeql.yml | 61 ++++++----- .github/workflows/cypress-basic.yml | 153 +++++++++++++-------------- .github/workflows/cypress-odfe.yml | 157 ++++++++++++++-------------- .github/workflows/cypress-wzd.yml | 155 +++++++++++++-------------- .github/workflows/cypress-xpack.yml | 155 +++++++++++++-------------- 5 files changed, 342 insertions(+), 339 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f6e5d5feaa..d6623591c4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -9,11 +9,11 @@ # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # -name: "CodeQL" +name: 'CodeQL' on: schedule: - - cron: '0 8 * * *' + - cron: '0 8 * * *' workflow_dispatch: jobs: @@ -28,45 +28,44 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: ['javascript'] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Use only 'java' to analyze code written in Java, Kotlin or both # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: '/language:${{matrix.language}}' diff --git a/.github/workflows/cypress-basic.yml b/.github/workflows/cypress-basic.yml index 931295d300..d8c6725c5e 100644 --- a/.github/workflows/cypress-basic.yml +++ b/.github/workflows/cypress-basic.yml @@ -31,84 +31,85 @@ jobs: name: Run setup environment wazuh kibana app runs-on: ubuntu-latest steps: - - name: Step 01 - Set up environment variables - run: | - echo "PATH_TEMPLATE=$GITHUB_WORKSPACE/wazuh-app-environments/templates_elastic_prod/es_basic-wz_cluster-agent/" >> $GITHUB_ENV + - name: Step 01 - Set up environment variables + run: | + echo "PATH_TEMPLATE=$GITHUB_WORKSPACE/wazuh-app-environments/templates_elastic_prod/es_basic-wz_cluster-agent/" >> $GITHUB_ENV - echo "Information about the workflow (basic): - wazuh-version: ${{ github.event.inputs.wazuh-version }} - elastic-version: ${{ github.event.inputs.elastic-version }} - ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} - url-package: ${{ github.event.inputs.url-package }}" + echo "Information about the workflow (basic): + wazuh-version: ${{ github.event.inputs.wazuh-version }} + elastic-version: ${{ github.event.inputs.elastic-version }} + ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} + url-package: ${{ github.event.inputs.url-package }}" - - name: Step 02 - Download Project wazuh-app-environments - uses: actions/checkout@v4 - with: - repository: matiasmoreno876/wazuh-app-environments - ref: 'master' - path: wazuh-app-environments - token: ${{ secrets.FE_SECRET_TOKEN }} - - name: Step 03 - Configuring templates docker environment - run: | - cd $GITHUB_WORKSPACE/wazuh-app-environments/ - mkdir packages - cd ${{ env.PATH_TEMPLATE }} - sed -i -e 's|WAZUH_VERSION=.*|WAZUH_VERSION=${{ github.event.inputs.wazuh-version }}|g' ./.env - sed -i -e 's|ELASTIC_VERSION=.*|ELASTIC_VERSION=${{ github.event.inputs.elastic-version }}|g' ./.env - sed -i -e 's|UBUNTU_CYPRESS_VERSION=.*|UBUNTU_CYPRESS_VERSION=${{ github.event.inputs.ubuntu-cypress-version }}|g' ./.env - cat .env - - name: Step 04 - Starting containers - run: | - cd ${{ env.PATH_TEMPLATE }} - docker-compose up -d - echo CONTINUES AFTER 15 SECONDS ... - sleep 15s - - name: Step 05 - Installing package from url - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q kibana) bin/kibana-plugin install ${{ github.event.inputs.url-package }} - docker-compose restart kibana - echo CONTINUES AFTER 60 SECONDS ... - sleep 60s - docker-compose ps - - name: Step 06 - Configuring ip container into wazuh.yml - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q kibana) sed -i -e "s/url: https:\/\/localhost/url: https:\/\/wazuh-manager-master/g" /usr/share/kibana/data/wazuh/config/wazuh.yml - docker exec $(docker-compose ps -q kibana) cat /usr/share/kibana/data/wazuh/config/wazuh.yml - - name: Step 07 - Run Cypress tests - id: run-cypress-test - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:basic" | tee cypress.log - continue-on-error: true - - name: Step 08 - Run Cypress reports - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" - - name: Step 09 - Archive reports - uses: actions/upload-artifact@v4 - with: - name: cypress-reports_BASIC_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.elastic-version }} - path: ${{ env.PATH_TEMPLATE }}/report/* - overwrite: true - - name: Step 10 - Log parsing - run: | - cd ${{ env.PATH_TEMPLATE }} - echo "TEST_SKIPPED=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF)}')" >> $GITHUB_ENV - echo "TEST_PENDING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-1)}')" >> $GITHUB_ENV - echo "TEST_FAILING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-2)}')" >> $GITHUB_ENV - echo "TEST_PASSING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-3)}')" >> $GITHUB_ENV - echo "TEST_TOTAL=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-4)}')" >> $GITHUB_ENV - echo "TEST_TIME=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-5)}')" >> $GITHUB_ENV - - name: Step 11 - Post to a Slack channel - id: slack - uses: slackapi/slack-github-action@v1.19.0 - with: + - name: Step 02 - Download Project wazuh-app-environments + uses: actions/checkout@v4 + with: + repository: matiasmoreno876/wazuh-app-environments + ref: 'master' + path: wazuh-app-environments + token: ${{ secrets.FE_SECRET_TOKEN }} + - name: Step 03 - Configuring templates docker environment + run: | + cd $GITHUB_WORKSPACE/wazuh-app-environments/ + mkdir packages + cd ${{ env.PATH_TEMPLATE }} + sed -i -e 's|WAZUH_VERSION=.*|WAZUH_VERSION=${{ github.event.inputs.wazuh-version }}|g' ./.env + sed -i -e 's|ELASTIC_VERSION=.*|ELASTIC_VERSION=${{ github.event.inputs.elastic-version }}|g' ./.env + sed -i -e 's|UBUNTU_CYPRESS_VERSION=.*|UBUNTU_CYPRESS_VERSION=${{ github.event.inputs.ubuntu-cypress-version }}|g' ./.env + cat .env + - name: Step 04 - Starting containers + run: | + cd ${{ env.PATH_TEMPLATE }} + docker-compose up -d + echo CONTINUES AFTER 15 SECONDS ... + sleep 15s + - name: Step 05 - Installing package from url + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q kibana) bin/kibana-plugin install ${{ github.event.inputs.url-package }} + docker-compose restart kibana + echo CONTINUES AFTER 60 SECONDS ... + sleep 60s + docker-compose ps + - name: Step 06 - Configuring ip container into wazuh.yml + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q kibana) sed -i -e "s/url: https:\/\/localhost/url: https:\/\/wazuh-manager-master/g" /usr/share/kibana/data/wazuh/config/wazuh.yml + docker exec $(docker-compose ps -q kibana) cat /usr/share/kibana/data/wazuh/config/wazuh.yml + - name: Step 07 - Run Cypress tests + id: run-cypress-test + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:basic" | tee cypress.log + continue-on-error: true + - name: Step 08 - Run Cypress reports + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" + - name: Step 09 - Archive reports + uses: actions/upload-artifact@v4 + with: + name: cypress-reports_BASIC_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.elastic-version }} + path: ${{ env.PATH_TEMPLATE }}/report/* + overwrite: true + - name: Step 10 - Log parsing + run: | + cd ${{ env.PATH_TEMPLATE }} + echo "TEST_SKIPPED=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF)}')" >> $GITHUB_ENV + echo "TEST_PENDING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-1)}')" >> $GITHUB_ENV + echo "TEST_FAILING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-2)}')" >> $GITHUB_ENV + echo "TEST_PASSING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-3)}')" >> $GITHUB_ENV + echo "TEST_TOTAL=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-4)}')" >> $GITHUB_ENV + echo "TEST_TIME=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-5)}')" >> $GITHUB_ENV + - name: Step 11 - Post to a Slack channel + id: slack + uses: slackapi/slack-github-action@v1.19.0 + with: # Slack channel id, channel name, or user id to post message. # See also: https://api.slack.com/methods/chat.postMessage#channels - channel-id: ${{ secrets.SLACK_CHANNEL_ID }} - # For posting a simple plain text message - slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - env: + channel-id: + ${{ secrets.SLACK_CHANNEL_ID }} + # For posting a simple plain text message + slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + env: SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} diff --git a/.github/workflows/cypress-odfe.yml b/.github/workflows/cypress-odfe.yml index 0405b7184a..241c8e9cd1 100644 --- a/.github/workflows/cypress-odfe.yml +++ b/.github/workflows/cypress-odfe.yml @@ -35,86 +35,87 @@ jobs: name: Run setup environment wazuh kibana app runs-on: ubuntu-latest steps: - - name: Step 01 - Set up environment variables - run: | - echo "PATH_TEMPLATE=$GITHUB_WORKSPACE/wazuh-app-environments/templates_elastic_prod/es_odfe-wz_cluster-agent/" >> $GITHUB_ENV + - name: Step 01 - Set up environment variables + run: | + echo "PATH_TEMPLATE=$GITHUB_WORKSPACE/wazuh-app-environments/templates_elastic_prod/es_odfe-wz_cluster-agent/" >> $GITHUB_ENV - echo "Information about the workflow (odfe): - wazuh-version: ${{ github.event.inputs.wazuh-version }} - elastic-version: ${{ github.event.inputs.elastic-version }} - odfe-version: ${{ github.event.inputs.odfe-version }} - ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} - url-package: ${{ github.event.inputs.url-package }}" + echo "Information about the workflow (odfe): + wazuh-version: ${{ github.event.inputs.wazuh-version }} + elastic-version: ${{ github.event.inputs.elastic-version }} + odfe-version: ${{ github.event.inputs.odfe-version }} + ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} + url-package: ${{ github.event.inputs.url-package }}" - - name: Step 02 - Download Project wazuh-app-environments - uses: actions/checkout@v4 - with: - repository: matiasmoreno876/wazuh-app-environments - ref: 'master' - path: wazuh-app-environments - token: ${{ secrets.FE_SECRET_TOKEN }} - - name: Step 03 - Configuring templates docker environment - run: | - cd $GITHUB_WORKSPACE/wazuh-app-environments/ - mkdir packages - cd ${{ env.PATH_TEMPLATE }} - sed -i -e 's|WAZUH_VERSION=.*|WAZUH_VERSION=${{ github.event.inputs.wazuh-version }}|g' ./.env - sed -i -e 's|ELASTIC_VERSION=.*|ELASTIC_VERSION=${{ github.event.inputs.elastic-version }}|g' ./.env - sed -i -e 's|ODFE_VERSION=.*|ODFE_VERSION=${{ github.event.inputs.odfe-version }}|g' ./.env - sed -i -e 's|UBUNTU_CYPRESS_VERSION=.*|UBUNTU_CYPRESS_VERSION=${{ github.event.inputs.ubuntu-cypress-version }}|g' ./.env - cat .env - - name: Step 04 - Starting containers - run: | - cd ${{ env.PATH_TEMPLATE }} - docker-compose up -d - echo CONTINUES AFTER 15 SECONDS ... - sleep 15s - - name: Step 05 - Installing package from url - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q kibana) bin/kibana-plugin install ${{ github.event.inputs.url-package }} - docker-compose restart kibana - echo CONTINUES AFTER 60 SECONDS ... - sleep 60s - docker-compose ps - - name: Step 06 - Configuring ip container into wazuh.yml - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q kibana) sed -i -e "s/url: https:\/\/localhost/url: https:\/\/wazuh-manager-master/g" /usr/share/kibana/data/wazuh/config/wazuh.yml - docker exec $(docker-compose ps -q kibana) cat /usr/share/kibana/data/wazuh/config/wazuh.yml - - name: Step 07 - Run Cypress tests - id: run-cypress-test - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:odfe" | tee cypress.log - continue-on-error: true - - name: Step 08 - Run Cypress reports - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" - - name: Step 09 - Archive reports - uses: actions/upload-artifact@v4 - with: - name: cypress-reports_ODFE_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.odfe-version }}-${{ github.event.inputs.elastic-version }} - path: ${{ env.PATH_TEMPLATE }}/report/* - overwrite: true - - name: Step 10 - Log parsing - run: | - cd ${{ env.PATH_TEMPLATE }} - echo "TEST_SKIPPED=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF)}')" >> $GITHUB_ENV - echo "TEST_PENDING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-1)}')" >> $GITHUB_ENV - echo "TEST_FAILING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-2)}')" >> $GITHUB_ENV - echo "TEST_PASSING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-3)}')" >> $GITHUB_ENV - echo "TEST_TOTAL=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-4)}')" >> $GITHUB_ENV - echo "TEST_TIME=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-5)}')" >> $GITHUB_ENV - - name: Step 11 - Post to a Slack channel - id: slack - uses: slackapi/slack-github-action@v1.19.0 - with: + - name: Step 02 - Download Project wazuh-app-environments + uses: actions/checkout@v4 + with: + repository: matiasmoreno876/wazuh-app-environments + ref: 'master' + path: wazuh-app-environments + token: ${{ secrets.FE_SECRET_TOKEN }} + - name: Step 03 - Configuring templates docker environment + run: | + cd $GITHUB_WORKSPACE/wazuh-app-environments/ + mkdir packages + cd ${{ env.PATH_TEMPLATE }} + sed -i -e 's|WAZUH_VERSION=.*|WAZUH_VERSION=${{ github.event.inputs.wazuh-version }}|g' ./.env + sed -i -e 's|ELASTIC_VERSION=.*|ELASTIC_VERSION=${{ github.event.inputs.elastic-version }}|g' ./.env + sed -i -e 's|ODFE_VERSION=.*|ODFE_VERSION=${{ github.event.inputs.odfe-version }}|g' ./.env + sed -i -e 's|UBUNTU_CYPRESS_VERSION=.*|UBUNTU_CYPRESS_VERSION=${{ github.event.inputs.ubuntu-cypress-version }}|g' ./.env + cat .env + - name: Step 04 - Starting containers + run: | + cd ${{ env.PATH_TEMPLATE }} + docker-compose up -d + echo CONTINUES AFTER 15 SECONDS ... + sleep 15s + - name: Step 05 - Installing package from url + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q kibana) bin/kibana-plugin install ${{ github.event.inputs.url-package }} + docker-compose restart kibana + echo CONTINUES AFTER 60 SECONDS ... + sleep 60s + docker-compose ps + - name: Step 06 - Configuring ip container into wazuh.yml + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q kibana) sed -i -e "s/url: https:\/\/localhost/url: https:\/\/wazuh-manager-master/g" /usr/share/kibana/data/wazuh/config/wazuh.yml + docker exec $(docker-compose ps -q kibana) cat /usr/share/kibana/data/wazuh/config/wazuh.yml + - name: Step 07 - Run Cypress tests + id: run-cypress-test + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:odfe" | tee cypress.log + continue-on-error: true + - name: Step 08 - Run Cypress reports + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" + - name: Step 09 - Archive reports + uses: actions/upload-artifact@v4 + with: + name: cypress-reports_ODFE_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.odfe-version }}-${{ github.event.inputs.elastic-version }} + path: ${{ env.PATH_TEMPLATE }}/report/* + overwrite: true + - name: Step 10 - Log parsing + run: | + cd ${{ env.PATH_TEMPLATE }} + echo "TEST_SKIPPED=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF)}')" >> $GITHUB_ENV + echo "TEST_PENDING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-1)}')" >> $GITHUB_ENV + echo "TEST_FAILING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-2)}')" >> $GITHUB_ENV + echo "TEST_PASSING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-3)}')" >> $GITHUB_ENV + echo "TEST_TOTAL=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-4)}')" >> $GITHUB_ENV + echo "TEST_TIME=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-5)}')" >> $GITHUB_ENV + - name: Step 11 - Post to a Slack channel + id: slack + uses: slackapi/slack-github-action@v1.19.0 + with: # Slack channel id, channel name, or user id to post message. # See also: https://api.slack.com/methods/chat.postMessage#channels - channel-id: ${{ secrets.SLACK_CHANNEL_ID }} - # For posting a simple plain text message - slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nODFE version: ${{ github.event.inputs.odfe-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - env: + channel-id: + ${{ secrets.SLACK_CHANNEL_ID }} + # For posting a simple plain text message + slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nODFE version: ${{ github.event.inputs.odfe-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + env: SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} diff --git a/.github/workflows/cypress-wzd.yml b/.github/workflows/cypress-wzd.yml index dc6155ef83..b4abd30034 100644 --- a/.github/workflows/cypress-wzd.yml +++ b/.github/workflows/cypress-wzd.yml @@ -27,85 +27,86 @@ jobs: name: Run setup environment wazuh dashboard app runs-on: ubuntu-latest steps: - - name: Step 01 - Set up environment variables - run: | - echo "PATH_TEMPLATE=$GITHUB_WORKSPACE/wazuh-app-environments/templates_wazuh_prod/" >> $GITHUB_ENV + - name: Step 01 - Set up environment variables + run: | + echo "PATH_TEMPLATE=$GITHUB_WORKSPACE/wazuh-app-environments/templates_wazuh_prod/" >> $GITHUB_ENV - echo "Information about the workflow (wzd): - wazuh-stack-version: ${{ github.event.inputs.wazuh-stack-version }} - ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} - url-package: ${{ github.event.inputs.url-package }}" + echo "Information about the workflow (wzd): + wazuh-stack-version: ${{ github.event.inputs.wazuh-stack-version }} + ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} + url-package: ${{ github.event.inputs.url-package }}" - - name: Step 02 - Download Project wazuh-app-environments - uses: actions/checkout@v4 - with: - repository: matiasmoreno876/wazuh-app-environments - ref: 'master' - path: wazuh-app-environments - token: ${{ secrets.FE_SECRET_TOKEN }} - - name: Step 03 - Configuring templates docker environment - run: | - cd $GITHUB_WORKSPACE/wazuh-app-environments/ - mkdir packages - cd ${{ env.PATH_TEMPLATE }} - sed -i -e 's|WAZUH_STACK_VERSION=.*|WAZUH_STACK_VERSION=${{ github.event.inputs.wazuh-stack-version }}|g' ./.env - sed -i -e 's|UBUNTU_CYPRESS_VERSION=.*|UBUNTU_CYPRESS_VERSION=${{ github.event.inputs.ubuntu-cypress-version }}|g' ./.env - cat .env - - name: Step 04 - Starting containers - run: | - cd ${{ env.PATH_TEMPLATE }} - docker-compose up -d - echo CONTINUES AFTER 30 SECONDS ... - sleep 30s - - name: Step 05 - Remove Wazuh - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q wazuh.dashboard) bin/opensearch-dashboards-plugin remove wazuh - docker-compose restart wazuh.dashboard - echo CONTINUES AFTER 30 SECONDS ... - sleep 30s - docker-compose ps - - name: Step 06 - Installing package from url - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q wazuh.dashboard) bin/opensearch-dashboards-plugin install ${{ github.event.inputs.url-package }} - docker-compose restart wazuh.dashboard - echo CONTINUES AFTER 60 SECONDS ... - sleep 60s - docker-compose ps - - name: Step 07 - Run Cypress tests - id: run-cypress-test - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:wzd" | tee cypress.log - continue-on-error: true - - name: Step 08 - Run Cypress reports - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" - - name: Step 09 - Archive reports - uses: actions/upload-artifact@v4 - with: - name: cypress-reports_WZD_${{ github.event.inputs.wazuh-stack-version }} - path: ${{ env.PATH_TEMPLATE }}/report/* - overwrite: true - - name: Step 10 - Log parsing - run: | - cd ${{ env.PATH_TEMPLATE }} - echo "TEST_SKIPPED=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF)}')" >> $GITHUB_ENV - echo "TEST_PENDING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-1)}')" >> $GITHUB_ENV - echo "TEST_FAILING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-2)}')" >> $GITHUB_ENV - echo "TEST_PASSING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-3)}')" >> $GITHUB_ENV - echo "TEST_TOTAL=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-4)}')" >> $GITHUB_ENV - echo "TEST_TIME=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-5)}')" >> $GITHUB_ENV - - name: Step 11 - Post to a Slack channel - id: slack - uses: slackapi/slack-github-action@v1.19.0 - with: + - name: Step 02 - Download Project wazuh-app-environments + uses: actions/checkout@v4 + with: + repository: matiasmoreno876/wazuh-app-environments + ref: 'master' + path: wazuh-app-environments + token: ${{ secrets.FE_SECRET_TOKEN }} + - name: Step 03 - Configuring templates docker environment + run: | + cd $GITHUB_WORKSPACE/wazuh-app-environments/ + mkdir packages + cd ${{ env.PATH_TEMPLATE }} + sed -i -e 's|WAZUH_STACK_VERSION=.*|WAZUH_STACK_VERSION=${{ github.event.inputs.wazuh-stack-version }}|g' ./.env + sed -i -e 's|UBUNTU_CYPRESS_VERSION=.*|UBUNTU_CYPRESS_VERSION=${{ github.event.inputs.ubuntu-cypress-version }}|g' ./.env + cat .env + - name: Step 04 - Starting containers + run: | + cd ${{ env.PATH_TEMPLATE }} + docker-compose up -d + echo CONTINUES AFTER 30 SECONDS ... + sleep 30s + - name: Step 05 - Remove Wazuh + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q wazuh.dashboard) bin/opensearch-dashboards-plugin remove wazuh + docker-compose restart wazuh.dashboard + echo CONTINUES AFTER 30 SECONDS ... + sleep 30s + docker-compose ps + - name: Step 06 - Installing package from url + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q wazuh.dashboard) bin/opensearch-dashboards-plugin install ${{ github.event.inputs.url-package }} + docker-compose restart wazuh.dashboard + echo CONTINUES AFTER 60 SECONDS ... + sleep 60s + docker-compose ps + - name: Step 07 - Run Cypress tests + id: run-cypress-test + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:wzd" | tee cypress.log + continue-on-error: true + - name: Step 08 - Run Cypress reports + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" + - name: Step 09 - Archive reports + uses: actions/upload-artifact@v4 + with: + name: cypress-reports_WZD_${{ github.event.inputs.wazuh-stack-version }} + path: ${{ env.PATH_TEMPLATE }}/report/* + overwrite: true + - name: Step 10 - Log parsing + run: | + cd ${{ env.PATH_TEMPLATE }} + echo "TEST_SKIPPED=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF)}')" >> $GITHUB_ENV + echo "TEST_PENDING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-1)}')" >> $GITHUB_ENV + echo "TEST_FAILING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-2)}')" >> $GITHUB_ENV + echo "TEST_PASSING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-3)}')" >> $GITHUB_ENV + echo "TEST_TOTAL=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-4)}')" >> $GITHUB_ENV + echo "TEST_TIME=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-5)}')" >> $GITHUB_ENV + - name: Step 11 - Post to a Slack channel + id: slack + uses: slackapi/slack-github-action@v1.19.0 + with: # Slack channel id, channel name, or user id to post message. # See also: https://api.slack.com/methods/chat.postMessage#channels - channel-id: ${{ secrets.SLACK_CHANNEL_ID }} - # For posting a simple plain text message - slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh stack version: ${{ github.event.inputs.wazuh-stack-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - env: + channel-id: + ${{ secrets.SLACK_CHANNEL_ID }} + # For posting a simple plain text message + slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh stack version: ${{ github.event.inputs.wazuh-stack-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + env: SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }} diff --git a/.github/workflows/cypress-xpack.yml b/.github/workflows/cypress-xpack.yml index 03a3a69e67..aa4a46be3a 100644 --- a/.github/workflows/cypress-xpack.yml +++ b/.github/workflows/cypress-xpack.yml @@ -31,85 +31,86 @@ jobs: name: Run setup environment wazuh kibana app runs-on: ubuntu-latest steps: - - name: Step 01 - Set up environment variables - run: | - echo "PATH_TEMPLATE=$GITHUB_WORKSPACE/wazuh-app-environments/templates_elastic_prod/es_xpack-wz_cluster-agent/" >> $GITHUB_ENV + - name: Step 01 - Set up environment variables + run: | + echo "PATH_TEMPLATE=$GITHUB_WORKSPACE/wazuh-app-environments/templates_elastic_prod/es_xpack-wz_cluster-agent/" >> $GITHUB_ENV - echo "Information about the workflow (xpack): - wazuh-version: ${{ github.event.inputs.wazuh-version }} - elastic-version: ${{ github.event.inputs.elastic-version }} - ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} - url-package: ${{ github.event.inputs.url-package }}" + echo "Information about the workflow (xpack): + wazuh-version: ${{ github.event.inputs.wazuh-version }} + elastic-version: ${{ github.event.inputs.elastic-version }} + ubuntu-cypress-version: ${{ github.event.inputs.ubuntu-cypress-version }} + url-package: ${{ github.event.inputs.url-package }}" - - name: Step 02 - Download Project wazuh-app-environments - uses: actions/checkout@v4 - with: - repository: matiasmoreno876/wazuh-app-environments - ref: 'master' - path: wazuh-app-environments - token: ${{ secrets.FE_SECRET_TOKEN }} - - name: Step 03 - Configuring templates docker environment - run: | - cd $GITHUB_WORKSPACE/wazuh-app-environments/ - mkdir packages - cd ${{ env.PATH_TEMPLATE }} - sed -i -e 's|WAZUH_VERSION=.*|WAZUH_VERSION=${{ github.event.inputs.wazuh-version }}|g' ./.env - sed -i -e 's|ELASTIC_VERSION=.*|ELASTIC_VERSION=${{ github.event.inputs.elastic-version }}|g' ./.env - sed -i -e 's|UBUNTU_CYPRESS_VERSION=.*|UBUNTU_CYPRESS_VERSION=${{ github.event.inputs.ubuntu-cypress-version }}|g' ./.env - cat .env - - name: Step 04 - Starting containers - run: | - cd ${{ env.PATH_TEMPLATE }} - sed -i -e 's|docker-compose exec elasticsearch|docker exec $(docker-compose ps -q elasticsearch)|g' ./setup.sh - sudo sh setup.sh - echo CONTINUES AFTER 15 SECONDS ... - sleep 15s - - name: Step 05 - Installing package from url - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q kibana) bin/kibana-plugin install ${{ github.event.inputs.url-package }} - docker-compose restart kibana - echo CONTINUES AFTER 60 SECONDS ... - sleep 60s - docker-compose ps - - name: Step 06 - Configuring ip container into wazuh.yml - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q kibana) sed -i -e "s/url: https:\/\/localhost/url: https:\/\/wazuh-manager-master/g" /usr/share/kibana/data/wazuh/config/wazuh.yml - docker exec $(docker-compose ps -q kibana) cat /usr/share/kibana/data/wazuh/config/wazuh.yml - - name: Step 07 - Run Cypress tests - id: run-cypress-test - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:xpack" | tee cypress.log - continue-on-error: true - - name: Step 08 - Run Cypress reports - run: | - cd ${{ env.PATH_TEMPLATE }} - docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" - - name: Step 09 - Archive reports - uses: actions/upload-artifact@v4 - with: - name: cypress-reports_XPACK_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.elastic-version }} - path: ${{ env.PATH_TEMPLATE }}/report/* - overwrite: true - - name: Step 10 - Log parsing - run: | - cd ${{ env.PATH_TEMPLATE }} - echo "TEST_SKIPPED=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF)}')" >> $GITHUB_ENV - echo "TEST_PENDING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-1)}')" >> $GITHUB_ENV - echo "TEST_FAILING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-2)}')" >> $GITHUB_ENV - echo "TEST_PASSING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-3)}')" >> $GITHUB_ENV - echo "TEST_TOTAL=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-4)}')" >> $GITHUB_ENV - echo "TEST_TIME=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-5)}')" >> $GITHUB_ENV - - name: Step 11 - Post to a Slack channel - id: slack - uses: slackapi/slack-github-action@v1.19.0 - with: + - name: Step 02 - Download Project wazuh-app-environments + uses: actions/checkout@v4 + with: + repository: matiasmoreno876/wazuh-app-environments + ref: 'master' + path: wazuh-app-environments + token: ${{ secrets.FE_SECRET_TOKEN }} + - name: Step 03 - Configuring templates docker environment + run: | + cd $GITHUB_WORKSPACE/wazuh-app-environments/ + mkdir packages + cd ${{ env.PATH_TEMPLATE }} + sed -i -e 's|WAZUH_VERSION=.*|WAZUH_VERSION=${{ github.event.inputs.wazuh-version }}|g' ./.env + sed -i -e 's|ELASTIC_VERSION=.*|ELASTIC_VERSION=${{ github.event.inputs.elastic-version }}|g' ./.env + sed -i -e 's|UBUNTU_CYPRESS_VERSION=.*|UBUNTU_CYPRESS_VERSION=${{ github.event.inputs.ubuntu-cypress-version }}|g' ./.env + cat .env + - name: Step 04 - Starting containers + run: | + cd ${{ env.PATH_TEMPLATE }} + sed -i -e 's|docker-compose exec elasticsearch|docker exec $(docker-compose ps -q elasticsearch)|g' ./setup.sh + sudo sh setup.sh + echo CONTINUES AFTER 15 SECONDS ... + sleep 15s + - name: Step 05 - Installing package from url + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q kibana) bin/kibana-plugin install ${{ github.event.inputs.url-package }} + docker-compose restart kibana + echo CONTINUES AFTER 60 SECONDS ... + sleep 60s + docker-compose ps + - name: Step 06 - Configuring ip container into wazuh.yml + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q kibana) sed -i -e "s/url: https:\/\/localhost/url: https:\/\/wazuh-manager-master/g" /usr/share/kibana/data/wazuh/config/wazuh.yml + docker exec $(docker-compose ps -q kibana) cat /usr/share/kibana/data/wazuh/config/wazuh.yml + - name: Step 07 - Run Cypress tests + id: run-cypress-test + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:run-headless:github-actions:xpack" | tee cypress.log + continue-on-error: true + - name: Step 08 - Run Cypress reports + run: | + cd ${{ env.PATH_TEMPLATE }} + docker exec $(docker-compose ps -q cypress) bash -c " . /home/automation/nvm/nvm.sh && nvm use && npm run cypress:report" + - name: Step 09 - Archive reports + uses: actions/upload-artifact@v4 + with: + name: cypress-reports_XPACK_${{ github.event.inputs.wazuh-version }}-${{ github.event.inputs.elastic-version }} + path: ${{ env.PATH_TEMPLATE }}/report/* + overwrite: true + - name: Step 10 - Log parsing + run: | + cd ${{ env.PATH_TEMPLATE }} + echo "TEST_SKIPPED=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF)}')" >> $GITHUB_ENV + echo "TEST_PENDING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-1)}')" >> $GITHUB_ENV + echo "TEST_FAILING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-2)}')" >> $GITHUB_ENV + echo "TEST_PASSING=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-3)}')" >> $GITHUB_ENV + echo "TEST_TOTAL=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-4)}')" >> $GITHUB_ENV + echo "TEST_TIME=$(grep -E "failed \(|passed" cypress.log | awk ' { print $(NF-5)}')" >> $GITHUB_ENV + - name: Step 11 - Post to a Slack channel + id: slack + uses: slackapi/slack-github-action@v1.19.0 + with: # Slack channel id, channel name, or user id to post message. # See also: https://api.slack.com/methods/chat.postMessage#channels - channel-id: ${{ secrets.SLACK_CHANNEL_ID }} - # For posting a simple plain text message - slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" - env: + channel-id: + ${{ secrets.SLACK_CHANNEL_ID }} + # For posting a simple plain text message + slack-message: "The following workflow was executed: ${{ github.workflow }}\nWazuh version: ${{ github.event.inputs.wazuh-version }}\nElastic version: ${{ github.event.inputs.elastic-version }}\nUbuntu Cypress version: ${{ github.event.inputs.ubuntu-cypress-version }}\nPackage used: ${{ github.event.inputs.url-package }}\n\nTest summary:\n\tTotal Test: ${{ env.TEST_TOTAL }}\n\tPassing: ${{ env.TEST_PASSING }}\n\tFailing: ${{ env.TEST_FAILING }}\n\tPending: ${{ env.TEST_PENDING }}\n\tSkipped: ${{ env.TEST_SKIPPED }}\n\tTotal Time: ${{ env.TEST_TIME }}\n\nFor more information visit: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + env: SLACK_BOT_TOKEN: ${{ secrets.ACTIONS_SLACK_TOKEN }}