Skip to content

Commit

Permalink
enhancement(#5229): macOS tests added
Browse files Browse the repository at this point in the history
  • Loading branch information
pro-akim committed Apr 18, 2024
1 parent ec5b4de commit 3a1f915
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 132 deletions.
10 changes: 8 additions & 2 deletions deployability/modules/generic/ansible.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Copyright (C) 2015, Wazuh Inc.
# Created by Wazuh, Inc. <info@wazuh.com>.
# This program is a free software; you can redistribute it and/or modify it under the terms of GPLv2

import ansible_runner
import jinja2
from typing import Optional
import yaml

from pathlib import Path
Expand All @@ -16,7 +18,8 @@ class Inventory(BaseModel):
ansible_host: str | IPvAnyAddress
ansible_user: str
ansible_port: int
ansible_ssh_private_key_file: str
ansible_ssh_private_key_file: Optional[str] = None
ansible_password: Optional[str] = None


class Ansible:
Expand Down Expand Up @@ -118,10 +121,13 @@ def generate_inventory(self) -> dict:
self.ansible_data.ansible_host: {
'ansible_port': self.ansible_data.ansible_port,
'ansible_user': self.ansible_data.ansible_user,
'ansible_ssh_private_key_file': self.ansible_data.ansible_ssh_private_key_file
**({'ansible_ssh_private_key_file': self.ansible_data.ansible_ssh_private_key_file}
if hasattr(self.ansible_data, 'ansible_ssh_private_key_file')
else {'ansible_password': self.ansible_data.ansible_password})
}
}
}
}


return inventory_data
116 changes: 67 additions & 49 deletions deployability/modules/testing/tests/helpers/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def install_agent(inventory_path, agent_name, wazuh_version, wazuh_revision, liv
release = 'pre-release'

os_type = HostInformation.get_os_type(inventory_path)
architecture = HostInformation.get_architecture(inventory_path)
commands = []
if 'linux' in os_type:
distribution = HostInformation.get_linux_distribution(inventory_path)
Expand Down Expand Up @@ -64,11 +65,11 @@ def install_agent(inventory_path, agent_name, wazuh_version, wazuh_revision, liv
"NET STATUS WazuhSvc"
])
elif 'macos' in os_type:
if 'intel' in architecture:
if 'x86_64' in architecture:
commands.extend([
f'curl -so wazuh-agent.pkg https://{s3_url}.wazuh.com/{release}/macos/wazuh-agent-{wazuh_version}-1.intel64.pkg && echo "WAZUH_MANAGER=\'MANAGER_IP\' && WAZUH_AGENT_NAME=\'{agent_name}\'" > /tmp/wazuh_envs && sudo installer -pkg ./wazuh-agent.pkg -target /'
])
elif 'apple' in architecture:
elif 'arm64' in architecture:
commands.extend([
f'curl -so wazuh-agent.pkg https://{s3_url}.wazuh.com/{release}/macos/wazuh-agent-{wazuh_version}-1.arm64.pkg && echo "WAZUH_MANAGER=\'MANAGER_IP\' && WAZUH_AGENT_NAME=\'{agent_name}\'" > /tmp/wazuh_envs && sudo installer -pkg ./wazuh-agent.pkg -target /'
])
Expand All @@ -95,15 +96,23 @@ def register_agent(inventory_path, manager_path):
manager_path = yaml.safe_load(yaml_file)
host = manager_path.get('ansible_host')

internal_ip = HostInformation.get_internal_ip_from_aws_dns(host) if 'amazonaws' in host else host

commands = [
f"sed -i 's/<address>MANAGER_IP<\/address>/<address>{internal_ip}<\/address>/g' {WAZUH_CONF}",
"systemctl restart wazuh-agent"
]

Executor.execute_commands(inventory_path, commands)
assert internal_ip in Executor.execute_command(inventory_path, f'cat {WAZUH_CONF}'), logger.error(f'Error configuring the Manager IP ({internal_ip})in: {HostInformation.get_os_name_and_version_from_inventory(inventory_path)} agent')
if 'linux' in inventory_path:
host_ip = HostInformation.get_internal_ip_from_aws_dns(host) if 'amazonaws' in host else host
commands = [
f"sed -i 's/<address>MANAGER_IP<\/address>/<address>{host_ip}<\/address>/g' {WAZUH_CONF}",
"systemctl restart wazuh-agent"
]
Executor.execute_commands(inventory_path, commands)
assert host_ip in Executor.execute_command(inventory_path, f'cat {WAZUH_CONF}'), logger.error(f'Error configuring the Manager IP ({host_ip}) in: {HostInformation.get_os_name_and_version_from_inventory(inventory_path)} agent')

elif 'macos' in inventory_path:
host_ip = HostInformation.get_public_ip_from_aws_dns(host) if 'amazonaws' in host else host
commands = [
f"sed -i '.bak' 's/<address>MANAGER_IP<\/address>/<address>{host_ip}<\/address>/g' /Library/Ossec/etc/ossec.conf",
"/Library/Ossec/bin/wazuh-control restart"
]
Executor.execute_commands(inventory_path, commands)
assert host_ip in Executor.execute_command(inventory_path, f'cat /Library/Ossec/etc/ossec.conf'), logger.error(f'Error configuring the Manager IP ({host_ip}) in: {HostInformation.get_os_name_and_version_from_inventory(inventory_path)} agent')


@staticmethod
Expand Down Expand Up @@ -190,41 +199,47 @@ def perform_action_and_scan(agent_params, action_callback) -> dict:
os_name = HostInformation.get_os_name_from_inventory(agent_params)
logger.info(f'Applying filters in checkfiles in {HostInformation.get_os_name_and_version_from_inventory(agent_params)}')

if 'debian' in os_name:
filter_data = {
'/boot': {'added': [], 'removed': [], 'modified': ['grubenv']},
'/usr/bin': {
'added': [
'unattended-upgrade', 'gapplication', 'add-apt-repository', 'gpg-wks-server', 'pkexec', 'gpgsplit',
'watchgnupg', 'pinentry-curses', 'gpg-zip', 'gsettings', 'gpg-agent', 'gresource', 'gdbus',
'gpg-connect-agent', 'gpgconf', 'gpgparsemail', 'lspgpot', 'pkaction', 'pkttyagent', 'pkmon',
'dirmngr', 'kbxutil', 'migrate-pubring-from-classic-gpg', 'gpgcompose', 'pkcheck', 'gpgsm', 'gio',
'pkcon', 'gpgtar', 'dirmngr-client', 'gpg', 'filebeat', 'gawk', 'curl', 'update-mime-database',
'dh_installxmlcatalogs', 'appstreamcli', 'lspgpot', 'symcryptrun'
],
'removed': [],
'modified': []
},
'/root': {'added': ['trustdb.gpg', 'lesshst'], 'removed': [], 'modified': []},
'/usr/sbin': {
'added': [
'update-catalog', 'applygnupgdefaults', 'addgnupghome', 'install-sgmlcatalog', 'update-xmlcatalog'
],
'removed': [],
'modified': []
if 'linux' in agent_params:
if 'debian' in os_name:
filter_data = {
'/boot': {'added': [], 'removed': [], 'modified': ['grubenv']},
'/usr/bin': {
'added': [
'unattended-upgrade', 'gapplication', 'add-apt-repository', 'gpg-wks-server', 'pkexec', 'gpgsplit',
'watchgnupg', 'pinentry-curses', 'gpg-zip', 'gsettings', 'gpg-agent', 'gresource', 'gdbus',
'gpg-connect-agent', 'gpgconf', 'gpgparsemail', 'lspgpot', 'pkaction', 'pkttyagent', 'pkmon',
'dirmngr', 'kbxutil', 'migrate-pubring-from-classic-gpg', 'gpgcompose', 'pkcheck', 'gpgsm', 'gio',
'pkcon', 'gpgtar', 'dirmngr-client', 'gpg', 'filebeat', 'gawk', 'curl', 'update-mime-database',
'dh_installxmlcatalogs', 'appstreamcli', 'lspgpot', 'symcryptrun'
],
'removed': [],
'modified': []
},
'/root': {'added': ['trustdb.gpg', 'lesshst'], 'removed': [], 'modified': []},
'/usr/sbin': {
'added': [
'update-catalog', 'applygnupgdefaults', 'addgnupghome', 'install-sgmlcatalog', 'update-xmlcatalog'
],
'removed': [],
'modified': []
}
}
else:
filter_data = {
'/boot': {
'added': ['grub2', 'loader', 'vmlinuz', 'System.map', 'config-', 'initramfs'],
'removed': [],
'modified': ['grubenv']
},
'/usr/bin': {'added': ['filebeat'], 'removed': [], 'modified': []},
'/root': {'added': ['trustdb.gpg', 'lesshst'], 'removed': [], 'modified': []},
'/usr/sbin': {'added': [], 'removed': [], 'modified': []}
}
elif 'macos' in agent_params:
filter_data = {
'/usr/bin': {'added': [], 'removed': [], 'modified': []},
'/usr/sbin': {'added': [], 'removed': [], 'modified': []}
}
}
else:
filter_data = {
'/boot': {
'added': ['grub2', 'loader', 'vmlinuz', 'System.map', 'config-', 'initramfs'],
'removed': [],
'modified': ['grubenv']
},
'/usr/bin': {'added': ['filebeat'], 'removed': [], 'modified': []},
'/root': {'added': ['trustdb.gpg', 'lesshst'], 'removed': [], 'modified': []},
'/usr/sbin': {'added': [], 'removed': [], 'modified': []}
}

# Use of filters
for directory, changes in result.items():
Expand All @@ -248,7 +263,7 @@ def perform_install_and_scan_for_agent(agent_params, agent_name, wazuh_params) -
action_callback = lambda: WazuhAgent._install_agent_callback(wazuh_params, agent_name, agent_params)
result = WazuhAgent.perform_action_and_scan(agent_params, action_callback)
logger.info(f'Pre and post install checkfile comparison in {HostInformation.get_os_name_and_version_from_inventory(agent_params)}: {result}')
WazuhAgent.assert_results(result)
WazuhAgent.assert_results(result, agent_params)


@staticmethod
Expand All @@ -264,19 +279,22 @@ def perform_uninstall_and_scan_for_agent(agent_params, wazuh_params) -> None:
action_callback = lambda: WazuhAgent._uninstall_agent_callback(wazuh_params, agent_params)
result = WazuhAgent.perform_action_and_scan(agent_params, action_callback)
logger.info(f'Pre and post uninstall checkfile comparison in {HostInformation.get_os_name_and_version_from_inventory(agent_params)}: {result}')
WazuhAgent.assert_results(result)
WazuhAgent.assert_results(result, agent_params)


@staticmethod
def assert_results(result) -> None:
def assert_results(result, agent_params) -> None:
"""
Gets the status of an agent given its name.
Args:
result (dict): result of comparison between pre and post action scan
"""
categories = ['/root', '/usr/bin', '/usr/sbin', '/boot']
if 'linux' in agent_params:
categories = ['/root', '/usr/bin', '/usr/sbin', '/boot']
elif 'macos' in agent_params:
categories = ['/usr/bin', '/usr/sbin']
actions = ['added', 'modified', 'removed']
# Testing the results
for category in categories:
Expand Down
54 changes: 36 additions & 18 deletions deployability/modules/testing/tests/helpers/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# This program is a free software; you can redistribute it and/or modify it under the terms of GPLv2

import json
import paramiko
import requests
import subprocess
import urllib3
Expand All @@ -19,24 +20,41 @@ def execute_command(inventory_path, command) -> str:
with open(inventory_path, 'r') as yaml_file:
inventory_data = yaml.safe_load(yaml_file)

host = inventory_data.get('ansible_host')
port = inventory_data.get('ansible_port')
private_key_path = inventory_data.get('ansible_ssh_private_key_file')
username = inventory_data.get('ansible_user')

ssh_command = [
"ssh",
"-i", private_key_path,
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-p", str(port),
f"{username}@{host}",
"sudo",
command
]
result = subprocess.run(ssh_command, stdout=subprocess.PIPE, text=True)

return result.stdout
if 'ansible_ssh_private_key_file' in inventory_data:
host = inventory_data.get('ansible_host')
port = inventory_data.get('ansible_port')
private_key_path = inventory_data.get('ansible_ssh_private_key_file')
username = inventory_data.get('ansible_user')

ssh_command = [
"ssh",
"-i", private_key_path,
"-o", "StrictHostKeyChecking=no",
"-o", "UserKnownHostsFile=/dev/null",
"-p", str(port),
f"{username}@{host}",
"sudo",
command
]
result = subprocess.run(ssh_command, stdout=subprocess.PIPE, text=True)

return result.stdout
else:
host = inventory_data.get('ansible_host', None)
port = inventory_data.get('ansible_port', 22)
user = inventory_data.get('ansible_user', None)
password = inventory_data.get('ansible_password', None)

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh_client.connect(hostname=host, port=port, username=user, password=password)
stdin, stdout, stderr = ssh_client.exec_command(f"sudo {command}")

result = ''.join(stdout.readlines())

ssh_client.close()

return result


@staticmethod
Expand Down
Loading

0 comments on commit 3a1f915

Please sign in to comment.