diff --git a/CHANGELOG.md b/CHANGELOG.md index cef6a2af3c..5a3ebc001e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Wazuh commit: TBD \ Release report: TBD ### Added + +- Test `sync-agens-groups-get` WDB command ([#2626](https://github.com/wazuh/wazuh-qa/pull/2626) - Test `wazuhdb getconfig` WDB command ([2627#](https://github.com/wazuh/wazuh-qa/pull/2627)) - Test `get-groups-integrity` WDB command ([#2607](https://github.com/wazuh/wazuh-qa/pull/2607)) - Test `set-agent-groups` WDB command ([#2602](https://github.com/wazuh/wazuh-qa/pull/2602)) diff --git a/deps/wazuh_testing/wazuh_testing/wazuh_db.py b/deps/wazuh_testing/wazuh_testing/wazuh_db.py index 320c0da52d..b25671d78b 100644 --- a/deps/wazuh_testing/wazuh_testing/wazuh_db.py +++ b/deps/wazuh_testing/wazuh_testing/wazuh_db.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015-2021, Wazuh Inc. +# Copyright (C) 2015-2022, Wazuh Inc. # Created by Wazuh, Inc. . # This program is free software; you can redistribute it and/or modify it under the terms of GPLv2 import functools @@ -6,11 +6,13 @@ import logging import socket import sqlite3 +import time from wazuh_testing.tools import GLOBAL_DB_PATH, WAZUH_DB_SOCKET_PATH from wazuh_testing.tools.monitoring import wazuh_pack, wazuh_unpack from wazuh_testing.tools.services import control_service + def callback_wazuhdb_response(item): if isinstance(item, tuple): data, response = item @@ -167,6 +169,28 @@ def clean_agents_from_db(): raise Exception('Unable to clean agents') +def clean_groups_from_db(): + """ + Clean groups table from global.db + """ + command = 'global sql DELETE FROM "group"' + try: + query_wdb(command) + except Exception: + raise Exception('Unable to clean groups table.') + + +def clean_belongs(): + """ + Clean belong table from global.db + """ + command = 'global sql DELETE FROM belongs' + try: + query_wdb(command) + except Exception: + raise Exception('Unable to clean belongs table.') + + def insert_agent_in_db(id=1, name='TestAgent', ip='any', registration_time=0, connection_status="never_connected", disconnection_time=0): """ @@ -182,6 +206,22 @@ def insert_agent_in_db(id=1, name='TestAgent', ip='any', registration_time=0, co raise Exception(f"Unable to add agent {id}") +# Insert agents into DB and assign them into a group +def insert_agent_into_group(total_agents): + for i in range(total_agents): + id = i + 1 + name = 'Agent-test' + str(id) + date = time.time() + command = f'global insert-agent {{"id":{id},"name":"{name}","date_add":{date}}}' + results = query_wdb(command) + assert results == 'ok' + + command = f'''global set-agent-groups {{"mode":"append","sync_status":"syncreq", + "source":"remote","data":[{{"id":{id},"groups":["Test_group{id}"]}}]}}''' + results = query_wdb(command) + assert results == 'ok' + + def remove_agent(agent_id): """Function that wraps the needed queries to remove an agent. diff --git a/tests/integration/test_wazuh_db/data/global/sync_agent_groups_get.yaml b/tests/integration/test_wazuh_db/data/global/sync_agent_groups_get.yaml new file mode 100644 index 0000000000..f5fd694d12 --- /dev/null +++ b/tests/integration/test_wazuh_db/data/global/sync_agent_groups_get.yaml @@ -0,0 +1,171 @@ +--- +- + name: "Test sync_status with response" + test_case: + - + input: 'global sync-agent-groups-get {"condition":"sync_status"}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test sync_status without response" + test_case: + - + pre_input: ['global sql UPDATE agent SET group_sync_status="synced"'] + input: 'global sync-agent-groups-get {"condition":"sync_status"}' + output: "[{'data': []}]" + +- + name: "Test 'all' condition when agent groups are in 'sync_req'" + test_case: + - + input: 'global sync-agent-groups-get {"condition":"all"}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test 'all' condition when agent groups are in 'synced'" + test_case: + - + pre_input: ['global sql UPDATE agent SET group_sync_status="synced"'] + input: 'global sync-agent-groups-get {"condition":"all"}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test 'sync_status' condition when one agent groups are in 'synced'" + test_case: + - + pre_input: ['global sql UPDATE agent SET group_sync_status="synced" WHERE id = 2'] + input: 'global sync-agent-groups-get {"condition":"sync_status"}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}]}]" + +- + name: "Test 'all' condition when one agent groups are in 'synced'" + test_case: + - + pre_input: ['global sql UPDATE agent SET group_sync_status="synced" WHERE id = 2'] + input: 'global sync-agent-groups-get {"condition":"all"}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test with and invalid filter in condition" + test_case: + - + input: 'global sync-agent-groups-get {"condition":"testinvalid"}' + output: 'err Could not obtain a response from wdb_global_sync_agent_groups_get' + +- + name: "Test without condition" + test_case: + - + input: 'global sync-agent-groups-get {"last_id":0}' + output: "err Invalid JSON data, missing required 'condition' field" + +- + name: "Test set_synced in True" + test_case: + - + input: 'global sync-agent-groups-get {"condition":"sync_status", "set_synced":true}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + new_status: "synced" + agent_id: "[1,2]" + +- + name: "Test set_synced with invalid value - false" + test_case: + - + input: 'global sync-agent-groups-get {"condition":"sync_status", "set_synced":false}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + new_status: "syncreq" + agent_id: "[1,2]" + +- + name: "Test set_synced with invalid value - String" + test_case: + - + input: 'global sync-agent-groups-get {"condition":"sync_status", "set_synced":"set"}' + output: "err Invalid JSON data, invalid alternative fields data type" + new_status: "syncreq" + agent_id: "[1,2]" + +- + name: "Test get_global_hash in true" + test_case: + - + pre_input: ['global sql UPDATE agent SET group_hash = "DUMMY"'] + input: 'global sync-agent-groups-get {"last_id":0, "condition":"sync_status", "get_global_hash":true}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}], 'hash': '49087946dd7a587ae30ae89cbc8084cad2cb0bfd'}]" + +- + name: "Test get_global_hash in false" + test_case: + - + pre_input: ['global sql UPDATE agent SET group_hash = "DUMMY"'] + input: 'global sync-agent-groups-get {"last_id":0, "condition":"sync_status", "get_global_hash":false}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test get_global_hash with invalid value" + test_case: + - + pre_input: ['global sql UPDATE agent SET group_hash = "DUMMY"'] + input: 'global sync-agent-groups-get {"last_id":0, "condition":"sync_status", "get_global_hash":"set"}' + output: "err Invalid JSON data, invalid alternative fields data type" + +- + name: "Test 'agent_registration_delta' in 0 and sync_status" + test_case: + - + input: 'global sync-agent-groups-get {"condition":"sync_status", "agent_registration_delta":0}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test 'agent_registration_delta' in 0 and all condition " + test_case: + - + input: 'global sync-agent-groups-get {"condition":"all", "agent_registration_delta":0}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test 'agent_registration_delta' with delta in 10000 and sync_status" + test_case: + - + pre_input: ['global insert-agent {"id":5,"name":"Agent-test5","date_add":1545753642}', 'global set-agent-groups {"mode":"append","sync_status":"syncreq", + "source":"remote","data":[{"id":5,"groups":["Test_group5"]}]}'] + input: 'global sync-agent-groups-get {"condition":"sync_status", "agent_registration_delta":10000}' + output: "[{'data': [{'id': 5, 'groups': ['Test_group5']}]}]" + +- + name: "Test 'agent_registration_delta' with delta in 10000 and all" + test_case: + - + pre_input: ['global insert-agent {"id":6,"name":"Agent-test6","date_add":1545753642}', 'global set-agent-groups {"mode":"append","sync_status":"syncreq", + "source":"remote","data":[{"id":6,"groups":["Test_group6"]}]}'] + input: 'global sync-agent-groups-get {"condition":"all", "agent_registration_delta":10000}' + output: "[{'data': [{'id': 6, 'groups': ['Test_group6']}]}]" + +- + name: "Test last_id - by default" + test_case: + - + input: 'global sync-agent-groups-get {"last_id":0, "condition":"sync_status"}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test last_id - obtain from second group" + test_case: + - + input: 'global sync-agent-groups-get {"last_id":1, "condition":"sync_status"}' + output: "[{'data': [{'id': 2, 'groups': ['Test_group2']}]}]" + +- + name: "Test last_id - with not exist id" + test_case: + - + input: 'global sync-agent-groups-get {"last_id":3, "condition":"sync_status"}' + output: "[{'data': []}]" + +- + name: "Test last_id - with negative value" + test_case: + - + input: 'global sync-agent-groups-get {"last_id":-3, "condition":"sync_status"}' + output: "[{'data': [{'id': 1, 'groups': ['Test_group1']}, {'id': 2, 'groups': ['Test_group2']}]}]" diff --git a/tests/integration/test_wazuh_db/test_sync_agent_groups_get.py b/tests/integration/test_wazuh_db/test_sync_agent_groups_get.py new file mode 100644 index 0000000000..fb206e9164 --- /dev/null +++ b/tests/integration/test_wazuh_db/test_sync_agent_groups_get.py @@ -0,0 +1,138 @@ +''' +copyright: Copyright (C) 2015-2022, Wazuh Inc. + Created by Wazuh, Inc. . + This program is free software; you can redistribute it and/or modify it under the terms of GPLv2 +type: integration +brief: Wazuh-db is the daemon in charge of the databases with all the Wazuh persistent information, exposing a socket + to receive requests and provide information. The Wazuh core uses list-based databases to store information + related to agent keys, and FIM/Rootcheck event data. + This test checks the usage of the sync-agent-groups-get command used to allow the cluster getting the + information to be synchronized.. +tier: 0 +modules: + - wazuh_db +components: + - manager +daemons: + - wazuh-db +os_platform: + - linux +os_version: + - Arch Linux + - Amazon Linux 2 + - Amazon Linux 1 + - CentOS 8 + - CentOS 7 + - CentOS 6 + - Ubuntu Focal + - Ubuntu Bionic + - Ubuntu Xenial + - Ubuntu Trusty + - Debian Buster + - Debian Stretch + - Debian Jessie + - Debian Wheezy + - Red Hat 8 + - Red Hat 7 + - Red Hat 6 +references: + - https://documentation.wazuh.com/current/user-manual/reference/daemons/wazuh-db.html +tags: + - wazuh_db +''' +import os + +import time +import pytest +import json + +from wazuh_testing.tools import WAZUH_PATH +from wazuh_testing.wazuh_db import (query_wdb, insert_agent_into_group, clean_agents_from_db, + clean_groups_from_db, clean_belongs) +from wazuh_testing.tools.file import get_list_of_content_yml +from wazuh_testing.modules import TIER0, SERVER, LINUX + +# Marks +pytestmark = [LINUX, TIER0, SERVER] + +# Configurations +test_data_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data') +messages_file = os.path.join(os.path.join(test_data_path, 'global'), 'sync_agent_groups_get.yaml') +module_tests = get_list_of_content_yml(messages_file, ".split('_')[0]") + +log_monitor_paths = [] +wdb_path = os.path.join(os.path.join(WAZUH_PATH, 'queue', 'db', 'wdb')) +receiver_sockets_params = [(wdb_path, 'AF_UNIX', 'TCP')] +monitored_sockets_params = [('wazuh-db', None, True)] +receiver_sockets = None # Set in the fixtures + + +# Fixtures + +# Insert agents into DB and assign them into a group +@pytest.fixture(scope='function') +def pre_insert_agents_into_group(): + insert_agent_into_group(2) + + yield + clean_agents_from_db() + clean_groups_from_db() + clean_belongs() + + +# Tests +@pytest.mark.parametrize('test_case', + [case['test_case'] for module_data in module_tests for case in module_data[0]], + ids=[f"{module_name}: {case['name']}" + for module_data, module_name in module_tests + for case in module_data] + ) +def test_sync_agent_groups(configure_sockets_environment, connect_to_sockets_module, + test_case, pre_insert_agents_into_group): + ''' + description: Check that commands about sync_aget_groups_get works properly. + wazuh_min_version: 4.4.0 + parameters: + - configure_sockets_environment: + type: fixture + brief: Configure environment for sockets and MITM. + - connect_to_sockets_module: + type: fixture + brief: Module scope version of 'connect_to_sockets' fixture. + - test_case: + type: fixture + brief: List of test_case stages (dicts with input, output and agent_id and expected_groups keys). + - pre_insert_agents_into_group: + type: fixture + brief: fixture in charge of insert agents and groups into DB. + assertions: + - Verify that the socket response matches the expected output. + input_description: + - Test cases are defined in the sync_agent_groups_get.yaml file. + expected_output: + - an array with all the agents that match with the search criteria + tags: + - wazuh_db + - wdb_socket + ''' + # Set each case + case_data = test_case[0] + output = case_data["output"] + + # Check if it requires any special configuration + if 'pre_input' in case_data: + for command in case_data['pre_input']: + query_wdb(command) + + time.sleep(1) + response = query_wdb(case_data["input"]) + + # Validate response + assert str(response) == output + + # Validate if the status of the group has change + if "new_status" in case_data: + agent_id = json.loads(case_data["agent_id"]) + for id in agent_id: + response = query_wdb(f'global get-agent-info {id}') + assert case_data["new_status"] == response[0]['group_sync_status']