-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of agent remove method in WazuhHandler #50
base: system-refactor
Are you sure you want to change the base?
Changes from 6 commits
00d95dc
da86fb5
e694057
f5c1621
b15ad7e
172235f
508698d
007d5ac
75bb26a
cc9476b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,13 @@ | |
|
||
import os | ||
import re | ||
from multiprocessing.pool import ThreadPool | ||
|
||
from wazuh_qa_framework.system.host_manager import HostManager | ||
|
||
DEFAULT_INSTALL_PATH = { | ||
'linux': '/var/ossec', | ||
'windows': 'C:\\Program Files\\ossec-agent', | ||
'windows': 'C:\\Program Files (x86)\\ossec-agent', | ||
'darwin': '/Library/Ossec' | ||
} | ||
|
||
|
@@ -51,7 +52,7 @@ def get_archives_directory_path(custom_installation_path=None): | |
|
||
def get_logs_directory_path(custom_installation_path=None, os_host='linux'): | ||
installation_path = custom_installation_path if custom_installation_path else DEFAULT_INSTALL_PATH[os_host] | ||
return installation_path if os_host == 'windows' else os.path.join(installation_path, 'logs') | ||
return installation_path + '\\logs' if os_host == 'windows' else os.path.join(installation_path, 'logs') | ||
|
||
|
||
def get_shared_directory_path(custom_installation_path=None, os_host='linux'): | ||
|
@@ -122,7 +123,7 @@ def get_wazuh_file_path(custom_installation_path=None, os_host='linux', file_nam | |
'custom_rule_directory': { | ||
'files': ['local_rules.xml'], | ||
'path_calculator': lambda filename: os.path.join(get_custom_rules_directory_path(installation_path), | ||
filename) | ||
filename) | ||
}, | ||
'group_configuration': { | ||
'files': ['agent.conf'], | ||
|
@@ -139,8 +140,9 @@ def get_wazuh_file_path(custom_installation_path=None, os_host='linux', file_nam | |
|
||
|
||
class WazuhEnvironmentHandler(HostManager): | ||
def __init__(self, inventory_path): | ||
def __init__(self, inventory_path, debug=False, max_workers=10): | ||
super().__init__(inventory_path) | ||
self.pool = ThreadPool(max_workers) | ||
|
||
def get_file_fullpath(self, host, filename, group=None): | ||
"""Get the path of common configuration and log file in the specified host. | ||
|
@@ -485,15 +487,6 @@ def get_ansible_host_component(self, host): | |
manager_list = self.get_managers() | ||
return 'agent' if host in agent_list else 'manager' if host in manager_list else None | ||
|
||
def restart_agent(self, host): | ||
"""Restart agent | ||
|
||
Args: | ||
host (str): Hostname | ||
systemd (bool, optional): Restart using systemd. Defaults to False. | ||
""" | ||
pass | ||
|
||
def get_agents_info(self): | ||
"""Get registered agents information. | ||
|
||
|
@@ -502,21 +495,32 @@ def get_agents_info(self): | |
""" | ||
pass | ||
|
||
def get_agents_id(self, agents_list=None): | ||
"""Get agents id | ||
|
||
Returns: | ||
List: Agents id list | ||
def get_agents_id(self, agent_list): | ||
"""Get agent ids | ||
Args: | ||
agents_list (_type_, agents_list): Agents list. | ||
Return: | ||
dict: agent_ids | ||
""" | ||
pass | ||
# Getting hostnames | ||
host_names = [] | ||
for agent in agent_list: | ||
host_names.append(self.run_command(agent, 'hostname')[1]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agents typically utilize the hostname as their default agent name, although it is possible to modify this setting. For further information on how to make adjustments, you can refer to the documentation page provided here. However, it seems that the current implementation does not support this particular scenario. To address this limitation, I recommend to create a separate method specifically dedicated to this purpose. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 508698d |
||
|
||
def restart_agents(self, agent_list=None, parallel=True): | ||
"""Restart list of agents | ||
# Getting id - hostnames from manager | ||
agent_control = self.run_command('manager1', '/var/ossec/bin/manage_agents -l', True)[1] | ||
|
||
Args: | ||
agent_list (list, optional): Agent list. Defaults to None. | ||
""" | ||
pass | ||
# Creating id_list from hostnames | ||
agent_ids = [] | ||
for hostname in host_names: | ||
hostname = hostname.replace('\r', '').replace('\n', '') | ||
for line in agent_control.split('\n'): | ||
if 'Name: ' + hostname in line: | ||
id_value = line.split(',')[0].split(': ')[1].strip() | ||
agent_ids.append(id_value) | ||
break | ||
|
||
return agent_ids | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This implementation is a little difficult to read and it is error prone. Some suggestions:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 508698d |
||
|
||
def restart_manager(self, host): | ||
"""Restart manager | ||
|
@@ -576,26 +580,84 @@ def clean_client_keys(self, hosts=None): | |
""" | ||
pass | ||
|
||
def clean_logs(self, hosts): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method does not support parallel logs clean. Please include it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 508698d |
||
"""Remove host logs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Specify which logs are removed |
||
Args: | ||
hosts (_type_, hosts): host list. | ||
""" | ||
# Clean ossec.log and and cluster.log | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 508698d |
||
for host in hosts: | ||
logs_path = self.get_logs_directory_path(host) | ||
if self.get_host_variables(host)['os_name'] == 'windows': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid to use low level operation, we already has a method to check if the host is a windows: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 508698d |
||
self.truncate_file(host, f'{logs_path}/ossec.log', recreate=True, become=False, ignore_errors=False) | ||
else: | ||
self.truncate_file(host, f'{logs_path}/ossec.log', recreate=True, become=True, ignore_errors=False) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Specify the |
||
host_type = self.get_host_variables(host).get('type') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same |
||
if 'master' == host_type or 'worker' == host_type: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check if it is manager instead |
||
self.truncate_file(host, f'{logs_path}/cluster.log', recreate=True, become=True, ignore_errors=False) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded become |
||
|
||
def clean_agents(self, agents=None): | ||
"""Stop agents, remove them from manager and clean their client keys | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why remove this whitespace? |
||
Args: | ||
agents (_type_, agents_list): Agents list. Defaults to None. | ||
""" | ||
pass | ||
|
||
def remove_agents_from_manager(self, agents=None, status='all', older_than='0s'): | ||
def restart_agents(self, agent_list): | ||
"""Restart agents | ||
Args: | ||
agents_list (_type_, agents_list): Agents list. | ||
""" | ||
# Clean ossec.log and and cluster.log | ||
for agent in agent_list: | ||
if self.get_host_variables(agent).get('os_name') == 'windows': | ||
self.run_command(agent, f"NET STOP WazuhSvc", become=False, ignore_errors=False) | ||
self.run_command(agent, f"NET START WazuhSvc", become=False, ignore_errors=False) | ||
else: | ||
self.run_command(agent, f"service wazuh-agent restart", become=True, ignore_errors=False) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this method, it is included in other development: #43. |
||
|
||
def remove_agents_from_manager(self, agent_list, manager=None, method='cmd', parallel=True, logs=False, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not supported the deletion of the client.keys. Also logs is not a meaningful name for a variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comments changed in 508698d |
||
restart=False): | ||
"""Remove agents from manager | ||
|
||
Args: | ||
agents (list, optional): Agents list. Defaults to None. | ||
status (str, optional): Agents status. Defaults to 'all'. | ||
older_than (str, optional): Older than parameter. Defaults to '0s'. | ||
|
||
Returns: | ||
dict: API response | ||
agent_list (list, optional): Agents list. Defaults to None. | ||
manager (str, optional): Name of manager. Defaults to None. | ||
method (str): Method to be used to remove agents, Defaults to cmd. | ||
parallel (str): In case that cmd method is used, it defines the use of threads for remove. Defaults to True. | ||
logs (str): Remove logs from agents. Defaults to False. | ||
restart (str): Restart agents. Defaults to False. | ||
""" | ||
pass | ||
manager = 'manager1' if manager is None else manager | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be used the master always, we don't need to provide a manager host as parameter |
||
parallel = False if method == 'api' else parallel | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why we can not remove agents if we don't use the API? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line sets the "parallel" parameter to False in case the user wants to use the API as a method, as the API already considers parallel deletion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed in 508698d |
||
|
||
# Getting agent_ids list | ||
agent_ids = self.get_agents_id(agent_list) | ||
|
||
# Remove agent by cmd core function | ||
def remove_agent_cmd(id): | ||
self.run_command(manager, f"/var/ossec/bin/manage_agents -r {id}", True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be integrated in a separate method There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worked in 508698d |
||
|
||
# Remove processes | ||
if method == 'cmd': | ||
if parallel: | ||
self.pool.map(remove_agent_cmd, agent_ids) | ||
else: | ||
for id in agent_ids: | ||
remove_agent_cmd(id) | ||
else: | ||
agent_string = ','.join(agent_ids) | ||
self.make_api_call('manager1', port=55000, method='DELETE', | ||
endpoint=f'/agents?pretty=true&older_than=0s&agents_list={agent_string}&status=all', | ||
request_body=None, token=None, check=False) | ||
|
||
# Remove logs | ||
if logs: | ||
self.clean_logs(agent_list) | ||
|
||
# Restarting agents | ||
if restart: | ||
self.restart_agents(agent_list) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When #43 is merged, adapt this block to use it properly There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 508698d |
||
|
||
def stop_manager(self, manager): | ||
"""Stop manager | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These methods do not belong to the host manager. In addition, there are already defined a wazuh_api module in the repository. Please use it instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 508698d