diff --git a/deployability/modules/testing/tests/helpers/agent.py b/deployability/modules/testing/tests/helpers/agent.py index 758eea6a2e..98e92d93be 100644 --- a/deployability/modules/testing/tests/helpers/agent.py +++ b/deployability/modules/testing/tests/helpers/agent.py @@ -306,6 +306,29 @@ def assert_results(result, agent_params) -> None: for action in actions: assert result[category][action] == [], logger.error(f'{result[category][action]} was found in: {category}{action}') + def areAgent_processes_active(agent_params): + """ + Check if agent processes are active + + Args: + agent_name (str): Agent name. + + Returns: + str: Os name. + """ + return bool([int(numero) for numero in Executor.execute_command(agent_params, 'pgrep wazuh').splitlines()]) + + def isAgent_port_open(agent_params): + """ + Check if agent port is open + + Args: + agent_name (str): Agent name. + + Returns: + str: Os name. + """ + return 'ESTAB' in Executor.execute_command(agent_params, 'ss -t -a -n | grep ":1514" | grep ESTAB') def get_agents_information(wazuh_api: WazuhAPI) -> list: """ @@ -382,6 +405,47 @@ def get_agent_ip_status_and_name_by_id(wazuh_api: WazuhAPI, identifier): return [None, None, None] + def get_agent_os_version_by_name(wazuh_api: WazuhAPI, agent_name): + """ + Get Agent os version by Agent name + + Args: + agent_name (str): Agent name. + + Returns: + str: Os version. + """ + response = requests.get(f"{wazuh_api.api_url}/agents", headers=wazuh_api.headers, verify=False) + try: + for agent_data in eval(response.text)['data']['affected_items']: + if agent_data.get('name') == agent_name: + return agent_data.get('os', {}).get('version') + except Exception as e: + logger.error(f"Unexpected error: {e}") + return f"Unexpected error: {e}" + + + def get_agent_os_name_by_name(wazuh_api: WazuhAPI, agent_name): + """ + Get Agent os name by Agent name + + Args: + agent_name (str): Agent name. + + Returns: + str: Os name. + """ + response = requests.get(f"{wazuh_api.api_url}/agents", headers=wazuh_api.headers, verify=False) + try: + for agent_data in eval(response.text)['data']['affected_items']: + if agent_data.get('name') == agent_name: + return 'suse' if agent_data.get('os', {}).get('name', '').lower() == 'sles' else agent_data.get('os', {}).get('name', '').lower() + except Exception as e: + logger.error(f"Unexpected error: {e}") + return f"Unexpected error: {e}" + return None + + def add_agent_to_manager(wazuh_api: WazuhAPI, name, ip) -> str: """ Add an agent to the manager. diff --git a/deployability/modules/testing/tests/helpers/generic.py b/deployability/modules/testing/tests/helpers/generic.py index fc3b6a6782..b55ecc75a0 100644 --- a/deployability/modules/testing/tests/helpers/generic.py +++ b/deployability/modules/testing/tests/helpers/generic.py @@ -174,6 +174,16 @@ def get_os_name_and_version_from_inventory(inventory_path) -> tuple: else: return None + @staticmethod + def get_os_version_from_inventory(inventory_path) -> str: + if 'manager' in inventory_path: + os_version = re.search(r".*?/manager-linux-.*?-(.*?)-.*?/inventory.yaml", inventory_path).group(1) + elif 'agent' in inventory_path: + os_version = re.search(r".*?/agent-linux-.*?-(.*?)-.*?/inventory.yaml", inventory_path).group(1) + return os_version + else: + return None + @staticmethod def get_current_dir(inventory_path) -> str: """ diff --git a/deployability/modules/testing/tests/test_agent/test_basic_info.py b/deployability/modules/testing/tests/test_agent/test_basic_info.py new file mode 100644 index 0000000000..3b81a0765f --- /dev/null +++ b/deployability/modules/testing/tests/test_agent/test_basic_info.py @@ -0,0 +1,84 @@ +# Copyright (C) 2015, Wazuh Inc. +# Created by Wazuh, Inc. . +# This program is a free software; you can redistribute it and/or modify it under the terms of GPLv2 + +import pytest +import re + +from ..helpers.agent import WazuhAgent, WazuhAPI +from ..helpers.constants import WAZUH_ROOT +from ..helpers.generic import HostConfiguration, HostInformation, GeneralComponentActions, Waits +from modules.testing.utils import logger +from ..helpers.manager import WazuhManager +from ..helpers.utils import Utils + + +@pytest.fixture(scope="module", autouse=True) +def wazuh_params(request): + wazuh_version = request.config.getoption('--wazuh_version') + wazuh_revision = request.config.getoption('--wazuh_revision') + dependencies = request.config.getoption('--dependencies') + targets = request.config.getoption('--targets') + live = request.config.getoption('--live') + + return { + 'wazuh_version': wazuh_version, + 'wazuh_revision': wazuh_revision, + 'dependencies': dependencies, + 'targets': targets, + 'live': live + } + + +@pytest.fixture(scope="module", autouse=True) +def setup_test_environment(wazuh_params): + targets = wazuh_params['targets'] + # Clean the string and split it into key-value pairs + targets = targets.replace(' ', '') + targets = targets.replace(' ', '') + pairs = [pair.strip() for pair in targets.strip('{}').split(',')] + targets_dict = dict(pair.split(':') for pair in pairs) + + wazuh_params['master'] = targets_dict.get('wazuh-1') + wazuh_params['workers'] = [value for key, value in targets_dict.items() if key.startswith('wazuh-') and key != 'wazuh-1'] + wazuh_params['agents'] = [value for key, value in targets_dict.items() if key.startswith('agent')] + wazuh_params['indexers'] = [value for key, value in targets_dict.items() if key.startswith('node-')] + wazuh_params['dashboard'] = targets_dict.get('dashboard', wazuh_params['master']) + + # If there are no indexers, we choose wazuh-1 by default + if not wazuh_params['indexers']: + wazuh_params['indexers'].append(wazuh_params['master']) + wazuh_params['managers'] = {key: value for key, value in targets_dict.items() if key.startswith('wazuh-')} + wazuh_params['agents'] = {key + '-' + re.findall(r'agent-(.*?)/', value)[0].replace('.',''): value for key, value in targets_dict.items() if key.startswith('agent')} + + updated_agents = {} + for agent_name, agent_params in wazuh_params['agents'].items(): + Utils.check_inventory_connection(agent_params) + if GeneralComponentActions.isComponentActive(agent_params, 'wazuh-agent') and GeneralComponentActions.hasAgentClientKeys(agent_params): + if HostInformation.get_client_keys(agent_params) != []: + client_name = HostInformation.get_client_keys(agent_params)[0]['name'] + updated_agents[client_name] = agent_params + else: + updated_agents[agent_name] = agent_params + if updated_agents != {}: + wazuh_params['agents'] = updated_agents + + +def test_wazuh_os_version(wazuh_params): + wazuh_api = WazuhAPI(wazuh_params['master']) + for agent_names, agent_params in wazuh_params['agents'].items(): + assert HostInformation.dir_exists(agent_params, WAZUH_ROOT), logger.error(f'The {WAZUH_ROOT} is not present in {HostInformation.get_os_name_and_version_from_inventory(agent_params)}') + expected_condition_func = lambda: 'active' == WazuhAgent.get_agent_status(wazuh_api, agent_names) + Waits.dynamic_wait(expected_condition_func, cycles=20, waiting_time=30) + assert HostInformation.get_os_version_from_inventory(agent_params) in WazuhAgent.get_agent_os_version_by_name(wazuh_api, agent_names), logger.error('There is a mismatch between the OS version and the OS version of the installed agent') + assert HostInformation.get_os_name_from_inventory(agent_params) in WazuhAgent.get_agent_os_name_by_name(wazuh_api, agent_names).replace(' ', ''), logger.error('There is a mismatch between the OS name and the OS name of the installed agent') + + +def test_wazuh_version(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert wazuh_params['wazuh_version'] in GeneralComponentActions.get_component_version(agent_params), logger.error(f"The version {HostInformation.get_os_name_and_version_from_inventory(agent_params)} is not {wazuh_params['wazuh_version']} by command") + + +def test_wazuh_revision(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert wazuh_params['wazuh_revision'] in GeneralComponentActions.get_component_revision(agent_params), logger.error(f"The revision {HostInformation.get_os_name_and_version_from_inventory(agent_params)} is not {wazuh_params['wazuh_revision']} by command") diff --git a/deployability/modules/testing/tests/test_agent/test_connection.py b/deployability/modules/testing/tests/test_agent/test_connection.py new file mode 100644 index 0000000000..4a7297596a --- /dev/null +++ b/deployability/modules/testing/tests/test_agent/test_connection.py @@ -0,0 +1,100 @@ +# Copyright (C) 2015, Wazuh Inc. +# Created by Wazuh, Inc. . +# This program is a free software; you can redistribute it and/or modify it under the terms of GPLv2 + +import pytest +import re + +from ..helpers.agent import WazuhAgent, WazuhAPI +from ..helpers.generic import HostInformation, GeneralComponentActions, Waits +from ..helpers.manager import WazuhManager, WazuhAPI +from modules.testing.utils import logger +from ..helpers.utils import Utils + + +@pytest.fixture(scope="module", autouse=True) +def wazuh_params(request): + wazuh_version = request.config.getoption('--wazuh_version') + wazuh_revision = request.config.getoption('--wazuh_revision') + dependencies = request.config.getoption('--dependencies') + targets = request.config.getoption('--targets') + live = request.config.getoption('--live') + + return { + 'wazuh_version': wazuh_version, + 'wazuh_revision': wazuh_revision, + 'dependencies': dependencies, + 'targets': targets, + 'live': live + } + + +@pytest.fixture(scope="module", autouse=True) +def setup_test_environment(wazuh_params): + targets = wazuh_params['targets'] + # Clean the string and split it into key-value pairs + targets = targets.replace(' ', '') + targets = targets.replace(' ', '') + pairs = [pair.strip() for pair in targets.strip('{}').split(',')] + targets_dict = dict(pair.split(':') for pair in pairs) + + wazuh_params['master'] = targets_dict.get('wazuh-1') + wazuh_params['workers'] = [value for key, value in targets_dict.items() if key.startswith('wazuh-') and key != 'wazuh-1'] + wazuh_params['agents'] = [value for key, value in targets_dict.items() if key.startswith('agent')] + wazuh_params['indexers'] = [value for key, value in targets_dict.items() if key.startswith('node-')] + wazuh_params['dashboard'] = targets_dict.get('dashboard', wazuh_params['master']) + + # If there are no indexers, we choose wazuh-1 by default + if not wazuh_params['indexers']: + wazuh_params['indexers'].append(wazuh_params['master']) + wazuh_params['managers'] = {key: value for key, value in targets_dict.items() if key.startswith('wazuh-')} + wazuh_params['agents'] = {key + '-' + re.findall(r'agent-(.*?)/', value)[0].replace('.',''): value for key, value in targets_dict.items() if key.startswith('agent')} + + updated_agents = {} + for agent_name, agent_params in wazuh_params['agents'].items(): + Utils.check_inventory_connection(agent_params) + if GeneralComponentActions.isComponentActive(agent_params, 'wazuh-agent') and GeneralComponentActions.hasAgentClientKeys(agent_params): + if HostInformation.get_client_keys(agent_params) != []: + client_name = HostInformation.get_client_keys(agent_params)[0]['name'] + updated_agents[client_name] = agent_params + else: + updated_agents[agent_name] = agent_params + if updated_agents != {}: + wazuh_params['agents'] = updated_agents + + +def test_connection(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + WazuhAgent.set_protocol_agent_connection(agent_params, 'tcp') + assert agent_names in WazuhManager.get_agent_control_info(wazuh_params['master']), f'The {agent_names} is not present in the master by command' + wazuh_api = WazuhAPI(wazuh_params['master']) + assert any(d.get('name') == agent_names for d in WazuhAgent.get_agents_information(wazuh_api)), logger.error(f'The {agent_names} is not present in the master by API') + + +def test_status(wazuh_params): + for agent in wazuh_params['agents'].values(): + assert 'active' in GeneralComponentActions.get_component_status(agent, 'wazuh-agent'), logger.error(f'The {HostInformation.get_os_name_and_version_from_inventory(agent)} is not active') + + +def test_service(wazuh_params): + wazuh_api = WazuhAPI(wazuh_params['master']) + for agent_names, agent_params in wazuh_params['agents'].items(): + assert GeneralComponentActions.isComponentActive(agent_params, 'wazuh-agent'), logger.error(f'{agent_names} is not active by API') + + expected_condition_func = lambda: 'active' == WazuhAgent.get_agent_status(wazuh_api, agent_names) + Waits.dynamic_wait(expected_condition_func, cycles=20, waiting_time=30) + + +def test_clientKeys(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert GeneralComponentActions.hasAgentClientKeys(agent_params), logger.error(f'{agent_names} has not ClientKeys file') + + +def test_port(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert WazuhAgent.isAgent_port_open(agent_params), logger.error('Port is closed') + + +def test_processes(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert WazuhAgent.areAgent_processes_active(agent_params), logger.error('Agent processes are not active') diff --git a/deployability/modules/testing/tests/test_agent/test_install.py b/deployability/modules/testing/tests/test_agent/test_install.py index bca54f2af7..c922c0230a 100644 --- a/deployability/modules/testing/tests/test_agent/test_install.py +++ b/deployability/modules/testing/tests/test_agent/test_install.py @@ -97,14 +97,4 @@ def test_installation(wazuh_params): def test_status(wazuh_params): for agent in wazuh_params['agents'].values(): agent_status = GeneralComponentActions.get_component_status(agent, 'wazuh-agent') - assert 'loaded' in agent_status or 'not running' in agent_status, logger.error(f'The {HostInformation.get_os_name_and_version_from_inventory(agent)} status is not loaded') - - -def test_version(wazuh_params): - for agent_names, agent_params in wazuh_params['agents'].items(): - assert wazuh_params['wazuh_version'] in GeneralComponentActions.get_component_version(agent_params), logger.error(f"The version {HostInformation.get_os_name_and_version_from_inventory(agent_params)} is not {wazuh_params['wazuh_version']} by command") - - -def test_revision(wazuh_params): - for agent_names, agent_params in wazuh_params['agents'].items(): - assert wazuh_params['wazuh_revision'] in GeneralComponentActions.get_component_revision(agent_params), logger.error(f"The revision {HostInformation.get_os_name_and_version_from_inventory(agent_params)} is not {wazuh_params['wazuh_revision']} by command") + assert 'loaded' in agent_status, logger.error(f'The {HostInformation.get_os_name_and_version_from_inventory(agent)} status is not loaded') diff --git a/deployability/modules/testing/tests/test_agent/test_registration.py b/deployability/modules/testing/tests/test_agent/test_registration.py index 05231a1594..fa1a5d911f 100644 --- a/deployability/modules/testing/tests/test_agent/test_registration.py +++ b/deployability/modules/testing/tests/test_agent/test_registration.py @@ -62,12 +62,11 @@ def setup_test_environment(wazuh_params): if updated_agents != {}: wazuh_params['agents'] = updated_agents -def test_registration(wazuh_params): - for agent_names, agent_params in wazuh_params['agents'].items(): - WazuhAgent.register_agent(agent_params, wazuh_params['master']) def test_status(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + WazuhAgent.register_agent(agent_params, wazuh_params['master']) for agent in wazuh_params['agents'].values(): assert 'active' in GeneralComponentActions.get_component_status(agent, 'wazuh-agent') or 'is running' in GeneralComponentActions.get_component_status(agent, 'wazuh-agent'), logger.error(f'The {HostInformation.get_os_name_and_version_from_inventory(agent)} is not active') @@ -79,7 +78,7 @@ def test_connection(wazuh_params): assert any(d.get('name') == agent_names for d in WazuhAgent.get_agents_information(wazuh_api)), logger.error(f'The {agent_names} is not present in the master by API') -def test_isActive(wazuh_params): +def test_service(wazuh_params): wazuh_api = WazuhAPI(wazuh_params['master']) for agent_names, agent_params in wazuh_params['agents'].items(): assert GeneralComponentActions.isComponentActive(agent_params, 'wazuh-agent'), logger.error(f'{agent_names} is not active by command') diff --git a/deployability/modules/testing/tests/test_agent/test_restart.py b/deployability/modules/testing/tests/test_agent/test_restart.py index b162cc9a7b..6fee856ec0 100644 --- a/deployability/modules/testing/tests/test_agent/test_restart.py +++ b/deployability/modules/testing/tests/test_agent/test_restart.py @@ -5,6 +5,7 @@ import pytest import re +from ..helpers.agent import WazuhAgent, WazuhAPI from ..helpers.generic import GeneralComponentActions, HostInformation from modules.testing.utils import logger from ..helpers.manager import WazuhManager @@ -84,3 +85,13 @@ def test_isActive(wazuh_params): def test_clientKeys(wazuh_params): for agent_names, agent_params in wazuh_params['agents'].items(): assert GeneralComponentActions.hasAgentClientKeys(agent_params), logger.error(f'{agent_names} has not ClientKeys file') + + +def test_port(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert WazuhAgent.isAgent_port_open(agent_params), logger.error('Port is closed') + + +def test_processes(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert WazuhAgent.areAgent_processes_active(agent_params), logger.error('Agent processes are not active') \ No newline at end of file diff --git a/deployability/modules/testing/tests/test_agent/test_stop.py b/deployability/modules/testing/tests/test_agent/test_stop.py index 510ce26a76..7d7eda4bfc 100644 --- a/deployability/modules/testing/tests/test_agent/test_stop.py +++ b/deployability/modules/testing/tests/test_agent/test_stop.py @@ -65,7 +65,7 @@ def setup_test_environment(wazuh_params): if updated_agents != {}: wazuh_params['agents'] = updated_agents -def test_stop(wazuh_params): +def test_service(wazuh_params): wazuh_api = WazuhAPI(wazuh_params['master']) for agent_names, agent_params in wazuh_params['agents'].items(): GeneralComponentActions.component_stop(agent_params, 'wazuh-agent') @@ -75,3 +75,13 @@ def test_stop(wazuh_params): expected_condition_func = lambda: 'disconnected' == WazuhAgent.get_agent_status(wazuh_api, agent_names) Waits.dynamic_wait(expected_condition_func, cycles=20, waiting_time=30) + + +def test_port(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert not WazuhAgent.isAgent_port_open(agent_params), logger.error('Port is still opened') + + +def test_processes(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert not WazuhAgent.areAgent_processes_active(agent_params), logger.error('Agent processes are still active') diff --git a/deployability/modules/testing/tests/test_agent/test_uninstall.py b/deployability/modules/testing/tests/test_agent/test_uninstall.py index e15daf6756..b61e952f34 100644 --- a/deployability/modules/testing/tests/test_agent/test_uninstall.py +++ b/deployability/modules/testing/tests/test_agent/test_uninstall.py @@ -86,10 +86,20 @@ def test_agent_uninstalled_directory(wazuh_params): assert not HostInformation.dir_exists(agent_params, WAZUH_ROOT), logger.error(f'The {WAZUH_ROOT} is still present in the agent {agent_names}') -def test_isActive(wazuh_params): +def test_service(wazuh_params): wazuh_api = WazuhAPI(wazuh_params['master']) for agent_names, agent_params in wazuh_params['agents'].items(): assert not GeneralComponentActions.isComponentActive(agent_params, 'wazuh-agent'), logger.error(f'{agent_names} is not inactive by command') expected_condition_func = lambda: 'disconnected' == WazuhAgent.get_agent_status(wazuh_api, agent_names) - Waits.dynamic_wait(expected_condition_func, cycles=20, waiting_time=30) \ No newline at end of file + Waits.dynamic_wait(expected_condition_func, cycles=20, waiting_time=30) + + +def test_port(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert not WazuhAgent.isAgent_port_open(agent_params), logger.error('Port is still opened') + + +def test_processes(wazuh_params): + for agent_names, agent_params in wazuh_params['agents'].items(): + assert not WazuhAgent.areAgent_processes_active(agent_params), logger.error('Agent processes are still active') diff --git a/deployability/modules/workflow_engine/examples/agent/aws/test-agent-complete.yaml b/deployability/modules/workflow_engine/examples/agent/aws/test-agent-complete.yaml index dcfe7f0ecd..d9d581b111 100755 --- a/deployability/modules/workflow_engine/examples/agent/aws/test-agent-complete.yaml +++ b/deployability/modules/workflow_engine/examples/agent/aws/test-agent-complete.yaml @@ -110,7 +110,7 @@ tasks: - targets: - wazuh-1: "{working-dir}/manager-{manager-os}/inventory.yaml" - agent: "{working-dir}/agent-{agent}/inventory.yaml" - - tests: "install,registration,restart,stop,uninstall" + - tests: "install,registration,connection,basic_info,restart,stop,uninstall" - component: "agent" - wazuh-version: "4.7.3" - wazuh-revision: "40714" diff --git a/deployability/modules/workflow_engine/examples/agent/vagrant/test-agent-complete-1.yaml b/deployability/modules/workflow_engine/examples/agent/vagrant/test-agent-complete-1.yaml index ea9907ff0a..0d1780775e 100755 --- a/deployability/modules/workflow_engine/examples/agent/vagrant/test-agent-complete-1.yaml +++ b/deployability/modules/workflow_engine/examples/agent/vagrant/test-agent-complete-1.yaml @@ -104,7 +104,7 @@ tasks: - targets: - wazuh-1: "{working-dir}/manager-{manager-os}/inventory.yaml" - agent: "{working-dir}/agent-{agent}/inventory.yaml" - - tests: "install,registration,restart,stop,uninstall" + - tests: "install,registration,connection,basic_info,restart,stop,uninstall" - component: "agent" - wazuh-version: "4.7.3" - wazuh-revision: "40714" diff --git a/deployability/modules/workflow_engine/examples/agent/vagrant/test-agent-complete-2.yaml b/deployability/modules/workflow_engine/examples/agent/vagrant/test-agent-complete-2.yaml index 428e6e5baa..2af6a19463 100755 --- a/deployability/modules/workflow_engine/examples/agent/vagrant/test-agent-complete-2.yaml +++ b/deployability/modules/workflow_engine/examples/agent/vagrant/test-agent-complete-2.yaml @@ -104,7 +104,7 @@ tasks: - targets: - wazuh-1: "{working-dir}/manager-{manager-os}/inventory.yaml" - agent: "{working-dir}/agent-{agent}/inventory.yaml" - - tests: "install,registration,restart,stop,uninstall" + - tests: "install,registration,connection,basic_info,restart,stop,uninstall" - component: "agent" - wazuh-version: "4.7.3" - wazuh-revision: "40714"