diff --git a/deps/wazuh_testing/wazuh_testing/tools/__init__.py b/deps/wazuh_testing/wazuh_testing/tools/__init__.py index 6538261ac7..571a583c4d 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/__init__.py +++ b/deps/wazuh_testing/wazuh_testing/tools/__init__.py @@ -10,6 +10,7 @@ if sys.platform == 'win32': WAZUH_PATH = os.path.join("C:", os.sep, "Program Files (x86)", "ossec-agent") WAZUH_CONF = os.path.join(WAZUH_PATH, 'ossec.conf') + WAZUH_LOCAL_INTERNAL_OPTIONS = os.path.join(WAZUH_PATH, 'local_internal_options.conf') WAZUH_SOURCES = os.path.join('/', 'wazuh') LOG_FILE_PATH = os.path.join(WAZUH_PATH, 'ossec.log') PREFIX = os.path.join('c:', os.sep) @@ -23,7 +24,6 @@ ANALYSIS_STATISTICS_FILE = None UPGRADE_PATH = os.path.join(WAZUH_PATH, 'upgrade') - else: WAZUH_SOURCES = os.path.join('/', 'wazuh') @@ -38,7 +38,7 @@ PREFIX = os.sep WAZUH_CONF_RELATIVE = os.path.join('etc', 'ossec.conf') - + WAZUH_LOCAL_INTERNAL_OPTIONS = os.path.join(f'{WAZUH_PATH}/etc', 'local_internal_options.conf') WAZUH_CONF = os.path.join(WAZUH_PATH, WAZUH_CONF_RELATIVE) WAZUH_API_CONF = os.path.join(WAZUH_PATH, 'api', 'configuration', 'api.yaml') WAZUH_SECURITY_CONF = os.path.join(WAZUH_PATH, 'api', 'configuration', 'security', 'security.yaml') @@ -87,10 +87,10 @@ def get_service(): _data_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data') + WAZUH_LOGS_PATH = os.path.join(WAZUH_PATH, 'logs') ALERT_FILE_PATH = os.path.join(WAZUH_LOGS_PATH, 'alerts', 'alerts.json') CLUSTER_LOGS_PATH = os.path.join(WAZUH_LOGS_PATH, 'cluster.log') - QUEUE_SOCKETS_PATH = os.path.join(WAZUH_PATH, 'queue', 'sockets') QUEUE_ALERTS_PATH = os.path.join(WAZUH_PATH, 'queue', 'alerts') QUEUE_DB_PATH = os.path.join(WAZUH_PATH, 'queue', 'db') @@ -111,10 +111,13 @@ def get_service(): MODULESD_CONTROL_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'control') MODULESD_KREQUEST_SOCKET_PATH = os.path.join(QUEUE_SOCKETS_PATH, 'krequest') MODULESD_C_INTERNAL_SOCKET_PATH = os.path.join(CLUSTER_SOCKET_PATH, 'c-internal.sock') -ACTIVE_RESPONSE_SOCKET_PATH = os.path.join(QUEUE_ALERTS_PATH,'ar') +ACTIVE_RESPONSE_SOCKET_PATH = os.path.join(QUEUE_ALERTS_PATH, 'ar') WAZUH_SOCKETS = { 'wazuh-agentd': [], + 'wazuh-apid': [], + 'wazuh-agentlessd': [], + 'wazuh-csyslogd': [], 'wazuh-analysisd': [ ANALYSISD_ANALISIS_SOCKET_PATH, ANALYSISD_QUEUE_SOCKET_PATH @@ -124,6 +127,7 @@ def get_service(): 'wazuh-logcollector': [LOGCOLLECTOR_SOCKET_PATH], 'wazuh-monitord': [MONITORD_SOCKET_PATH], 'wazuh-remoted': [REMOTED_SOCKET_PATH], + 'wazuh-maild': [], 'wazuh-syscheckd': [SYSCHECKD_SOCKET_PATH], 'wazuh-db': [WAZUH_DB_SOCKET_PATH], 'wazuh-modulesd': [ @@ -140,3 +144,48 @@ def get_service(): MODULESD_KREQUEST_SOCKET_PATH, AUTHD_SOCKET_PATH ] + +DISABLE_MONITORD_ROTATE_LOG_OPTION = {'monitord.rotate_log': '0'} +REMOTED_LOCAL_INTERNAL_OPTIONS = {'remoted.debug': '2'}.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) +ANALYSISD_LOCAL_INTERNAL_OPTIONS = {'analysisd.debug': '2'}.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) +AGENTD_LOCAL_INTERNAL_OPTIONS = {'agent.debug': '2', 'execd': '2'}.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) + +FIM_LOCAL_INTERNAL_OPTIONS_MANAGER = {'syscheck.debug': '2', + 'analysisd.debug': '2'}.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) +FIM_LOCAL_INTERNAL_OPTIONS_AGENT_UNIX = {'syscheck.debug': '2', + 'agent.debug': '2'}.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) +FIM_LOCAL_INTERNAL_OPTIONS_AGENT_WINDOWS = {'syscheck.debug': '2', + 'windows.debug': '2'}.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) + +GCLOUD_LOCAL_INTERNAL_OPTIONS = {'analysisd.debug': '2', + 'wazuh_modules.debug': '2'}.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) +LOGTEST_LOCAL_INTERNAL_OPTIONS = {'analysisd.debug': '2'} +REMOTED_LOCAL_INTERNAL_OPTIONS = {'remoted.debug': '2', 'wazuh_database.interval': '2', 'wazuh_db.commit_time': '2', + 'wazuh_db.commit_time_max': '3' }.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) +VD_LOCAL_INTERNAL_OPTIONS = {'wazuh_modules.debug': '2'}.update(DISABLE_MONITORD_ROTATE_LOG_OPTION) +WPK_LOCAL_INTERNAL_OPTIONS = {'wazuh_modules.debug': '2'} + + +# Wazuh daemons +LOGCOLLECTOR_DAEMON = 'wazuh-logcollector' +AGENTLESS_DAEMON = 'wazuh-agentlessd' +CSYSLOG_DAEMON = 'wazuh-csyslogd' +REMOTE_DAEMON = 'wazuh-remoted' +ANALYSISD_DAEMON = 'wazuh-analysisd' +API_DAEMON = 'wazuh-apid' +MAIL_DAEMON = 'wazuh-maild' +SYSCHECK_DAEMON = 'wazuh-syscheckd' +EXEC_DAEMON = 'wazuh-execd' +MODULES_DAEMON = 'wazuh-modulesd' +CLUSTER_DAEMON = 'wazuh-clusterd' +INTEGRATOR_DAEMON = 'wazuh-integratord' +MONITOR_DAEMON = 'wazuh-monitord' +DB_DAEMON = 'wazuh-db' +AGENT_DAEMON = 'wazuh-agentd' + + +ALL_MANAGER_DAEMONS = [LOGCOLLECTOR_DAEMON, AGENTLESS_DAEMON, CSYSLOG_DAEMON, REMOTE_DAEMON, ANALYSISD_DAEMON, + API_DAEMON, MAIL_DAEMON, SYSCHECK_DAEMON, EXEC_DAEMON, MODULES_DAEMON, CLUSTER_DAEMON, + INTEGRATOR_DAEMON, MONITOR_DAEMON, DB_DAEMON] +ALL_AGENT_DAEMONS = [AGENT_DAEMON, EXEC_DAEMON, LOGCOLLECTOR_DAEMON, SYSCHECK_DAEMON, MODULES_DAEMON] +API_DAEMONS_REQUIREMENTS = [API_DAEMON, MODULES_DAEMON, ANALYSISD_DAEMON, EXEC_DAEMON, DB_DAEMON, REMOTE_DAEMON] diff --git a/deps/wazuh_testing/wazuh_testing/tools/configuration.py b/deps/wazuh_testing/wazuh_testing/tools/configuration.py index e3e231f068..4d4dab90da 100644 --- a/deps/wazuh_testing/wazuh_testing/tools/configuration.py +++ b/deps/wazuh_testing/wazuh_testing/tools/configuration.py @@ -12,7 +12,7 @@ import pytest import yaml from wazuh_testing import global_parameters -from wazuh_testing.tools import WAZUH_PATH, GEN_OSSEC, WAZUH_CONF, PREFIX +from wazuh_testing.tools import WAZUH_PATH, GEN_OSSEC, WAZUH_CONF, PREFIX, WAZUH_LOCAL_INTERNAL_OPTIONS # customize _serialize_xml to avoid lexicographical order in XML attributes @@ -540,3 +540,32 @@ def generate_syscheck_registry_config(): for yn_values, tag_value in itertools.product(values_list, tags): yn_str = ' '.join([f'{name}="{value}"' for name, value in zip(check_names, yn_values)]) yield ' '.join([yn_str, tag_value]) + + +def get_local_internal_options_dict(): + """Return the local internal options in a dictionary. + + Returns: + dict: Local internal options. + """ + local_internal_option_dict = {} + with open(WAZUH_LOCAL_INTERNAL_OPTIONS, 'r') as local_internal_option_file: + configuration_options = local_internal_option_file.readlines() + for configuration_option in configuration_options: + if not configuration_option.startswith('#'): + option_name, option_value = configuration_option.split('=') + local_internal_option_dict[option_name] = option_value + + return local_internal_option_dict + + +def set_local_internal_options_dict(dict_local_internal_options): + """Set the local internal options using a dictionary. + + Args: + local_internal_options_dict (dict): A dictionary containing local internal options. + """ + with open(WAZUH_LOCAL_INTERNAL_OPTIONS, 'w') as local_internal_option_file: + for option_name, option_value in dict_local_internal_options.items(): + local_internal_configuration_string = f"{str(option_name)}={str(option_value)}\n" + local_internal_option_file.write(local_internal_configuration_string) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 27cbbcff78..55b51f355f 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -14,7 +14,9 @@ import pytest from numpydoc.docscrape import FunctionDoc from py.xml import html -from wazuh_testing import global_parameters + +import wazuh_testing.tools.configuration as conf +from wazuh_testing import global_parameters, logger from wazuh_testing.tools import LOG_FILE_PATH, WAZUH_CONF, get_service, ALERT_FILE_PATH from wazuh_testing.tools.configuration import get_wazuh_conf, set_section_wazuh_conf, write_wazuh_conf from wazuh_testing.tools.file import truncate_file @@ -574,3 +576,124 @@ def put_env_variables(get_configuration, request): for env in environment_variables: if sys.platform != 'win32': os.unsetenv(env[0]) + + +@pytest.fixture(scope='module') +def configure_local_internal_options_module(request): + """Fixture to configure the local internal options file. + + It uses the test variable local_internal_options. This should be + a dictionary wich keys and values corresponds to the internal option configuration, For example: + local_internal_options = {'monitord.rotate_log': '0', 'syscheck.debug': '0' } + """ + try: + local_internal_options = getattr(request.module, 'local_internal_options') + except AttributeError as local_internal_configuration_not_set: + logger.debug('local_internal_options is not set') + raise local_internal_configuration_not_set + + backup_local_internal_options = conf.get_local_internal_options_dict() + + logger.debug(f"Set local_internal_option to {str(local_internal_options)}") + conf.set_local_internal_options_dict(local_internal_options) + + yield + + logger.debug(f"Restore local_internal_option to {str(backup_local_internal_options)}") + conf.set_local_internal_options_dict(backup_local_internal_options) + + +@pytest.fixture(scope='module') +def daemons_handler(get_configuration, request): + """Handler of Wazuh daemons. + + It uses `daemons_handler_configuration` of each module in order to configure the behavior of the fixture. + The `daemons_handler_configuration` should be a dictionary with the following keys: + daemons (list, optional): List with every daemon to be used by the module. In case of empty a ValueError + will be raised + all_daemons (boolean): Configure to restart all wazuh services. Default `False`. + ignore_errors (boolean): Configure if errors in daemon handling should be ignored. This option is available + in order to use this fixture along with invalid configuration. Default `False` + + Args: + get_configuration (fixture): Gets the current configuration of the test. + request (fixture): Provide information on the executing test function. + """ + daemons = [] + ignore_errors = False + all_daemons = False + + try: + daemons_handler_configuration = getattr(request.module, 'daemons_handler_configuration') + if 'daemons' in daemons_handler_configuration and not all_daemons: + daemons = daemons_handler_configuration['daemons'] + if not daemons or (type(daemons) == list and len(daemons) == 0): + logger.error('Daemons list is not set') + raise ValueError + + if 'all_daemons' in daemons_handler_configuration: + logger.debug(f"Wazuh control set to {daemons_handler_configuration['all_daemons']}") + all_daemons = daemons_handler_configuration['all_daemons'] + + if 'ignore_errors' in daemons_handler_configuration: + logger.debug(f"Ignore error set to {daemons_handler_configuration['ignore_errors']}") + ignore_errors = daemons_handler_configuration['ignore_errors'] + + except AttributeError as daemon_configuration_not_set: + logger.error('daemons_handler_configuration is not set') + raise daemon_configuration_not_set + + try: + if all_daemons: + logger.debug('Restarting wazuh using wazuh-control') + # Restart daemon instead of starting due to legacy used fixture in the test suite. + control_service('restart') + else: + for daemon in daemons: + logger.debug(f"Restarting {daemon}") + # Restart daemon instead of starting due to legacy used fixture in the test suite. + control_service('restart', daemon=daemon) + + except ValueError as value_error: + logger.error(f"{str(value_error)}") + if not ignore_errors: + raise value_error + except subprocess.CalledProcessError as called_process_error: + logger.error(f"{str(called_process_error)}") + if not ignore_errors: + raise called_process_error + + yield + + if all_daemons: + logger.debug('Stopping wazuh using wazuh-control') + control_service('stop') + else: + for daemon in daemons: + logger.debug(f"Stopping {daemon}") + control_service('stop', daemon=daemon) + + +@pytest.fixture(scope='function') +def file_monitoring(request): + """Fixture to handle the monitoring of a specified file. + + It uses de variable `file_to_monitor` to determinate the file to monitor. Default `LOG_FILE_PATH` + + Args: + request (fixture): Provide information on the executing test function. + """ + if hasattr(request.module, 'file_to_monitor'): + file_to_monitor = getattr(request.module, 'file_to_monitor') + else: + file_to_monitor = LOG_FILE_PATH + + logger.debug(f"Initializing file to monitor to {file_to_monitor}") + + file_monitor = FileMonitor(file_to_monitor) + setattr(request.module, 'log_monitor', file_monitor) + + yield + + truncate_file(file_to_monitor) + logger.debug(f"Trucanted {file_to_monitor}")