mirror of
https://github.com/wazuh/wazuh-virtual-machines.git
synced 2025-12-10 10:11:44 -06:00
add pasword tool to the ami customizer service
This commit is contained in:
parent
2221c47413
commit
8009f42548
@ -7,7 +7,7 @@ import paramiko
|
|||||||
from configurer.ami.ami_post_configurer.create_service_directory import create_directory_structure, generate_yaml
|
from configurer.ami.ami_post_configurer.create_service_directory import create_directory_structure, generate_yaml
|
||||||
from generic import exec_command, modify_file, remote_connection
|
from generic import exec_command, modify_file, remote_connection
|
||||||
from models import Inventory
|
from models import Inventory
|
||||||
from utils import CertificatesComponent, Logger, RemoteDirectories
|
from utils import CertificatesComponent, Logger, PasswordToolComponent, RemoteDirectories
|
||||||
|
|
||||||
logger = Logger("AmiPostConfigurer")
|
logger = Logger("AmiPostConfigurer")
|
||||||
|
|
||||||
@ -15,21 +15,21 @@ logger = Logger("AmiPostConfigurer")
|
|||||||
@dataclass
|
@dataclass
|
||||||
class AmiPostConfigurer:
|
class AmiPostConfigurer:
|
||||||
inventory: Inventory
|
inventory: Inventory
|
||||||
environment_name: str = "certs-env"
|
environment_name: str = "customizer-env"
|
||||||
enviroment_python_version: str = "3.11"
|
enviroment_python_version: str = "3.11"
|
||||||
custom_env_dependencies: ClassVar[list[str]] = [
|
custom_env_dependencies: ClassVar[list[str]] = [
|
||||||
"pydantic",
|
"pydantic",
|
||||||
"pyyaml",
|
"pyyaml",
|
||||||
"paramiko",
|
"paramiko",
|
||||||
]
|
]
|
||||||
custom_dir_name: str = "wazuh-ami-certs-customize"
|
custom_dir_name: str = "wazuh-ami-customizer"
|
||||||
custom_dir_base_path: str = "/etc"
|
custom_dir_base_path: str = "/etc"
|
||||||
cloud_instances_path: Path = Path("/var/lib/cloud/instances")
|
cloud_instances_path: Path = Path("/var/lib/cloud/instances")
|
||||||
journal_logs_path: Path = Path("/var/log/journal")
|
journal_logs_path: Path = Path("/var/log/journal")
|
||||||
journald__config_file_path: Path = Path("/etc/systemd/journald.conf")
|
journald__config_file_path: Path = Path("/etc/systemd/journald.conf")
|
||||||
log_directory_path: Path = Path("/var/log")
|
log_directory_path: Path = Path("/var/log")
|
||||||
wazuh_indexer_log_path: Path = Path("/var/log/wazuh-indexer")
|
wazuh_indexer_log_path: Path = Path("/var/log/wazuh-indexer")
|
||||||
wazuh_server_log_path: Path = Path("/var/log/wazuh-server")
|
wazuh_server_log_path: Path = Path("/var/ossec/logs")
|
||||||
wazuh_dashboard_log_path: Path = Path("/var/log/wazuh-dashboard")
|
wazuh_dashboard_log_path: Path = Path("/var/log/wazuh-dashboard")
|
||||||
|
|
||||||
@remote_connection
|
@remote_connection
|
||||||
@ -105,6 +105,8 @@ class AmiPostConfigurer:
|
|||||||
"remote_certs_path": RemoteDirectories.CERTS,
|
"remote_certs_path": RemoteDirectories.CERTS,
|
||||||
"certs_tool": CertificatesComponent.CERTS_TOOL,
|
"certs_tool": CertificatesComponent.CERTS_TOOL,
|
||||||
"certs_config": CertificatesComponent.CONFIG,
|
"certs_config": CertificatesComponent.CONFIG,
|
||||||
|
"password_tool_path": RemoteDirectories.PASSWORD_TOOL,
|
||||||
|
"password_tool": PasswordToolComponent.PASSWORD_TOOL,
|
||||||
}
|
}
|
||||||
directory_template = generate_yaml(
|
directory_template = generate_yaml(
|
||||||
context=context,
|
context=context,
|
||||||
@ -181,7 +183,7 @@ class AmiPostConfigurer:
|
|||||||
None
|
None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.stop_service("wazuh-server", client=client)
|
self.stop_service("wazuh-manager", client=client)
|
||||||
|
|
||||||
def remove_wazuh_indexes(self, client: paramiko.SSHClient) -> None:
|
def remove_wazuh_indexes(self, client: paramiko.SSHClient) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -1,13 +1,22 @@
|
|||||||
name: "wazuh-ami-certs-customize"
|
# The structure contains name, files, and directories:
|
||||||
|
# - name: name of the directory to be created
|
||||||
|
# - files: list of files to be created.
|
||||||
|
# - path: path where the file to be copied is located. (not the destination path, but the source. The destination path is constructed automatically)
|
||||||
|
# - local: indicates whether the file is on the local machine (true) or on the remote instance (false).
|
||||||
|
# - directories: list of subdirectories to be created within the current directory. Each subdirectory can contain its own files and subdirectories.
|
||||||
|
|
||||||
|
name: "wazuh-ami-customizer"
|
||||||
files:
|
files:
|
||||||
- path: "{{ remote_certs_path }}/{{ certs_tool }}"
|
- path: "{{ remote_certs_path }}/{{ certs_tool }}"
|
||||||
local: false
|
local: false
|
||||||
- path: "{{ remote_certs_path }}/{{ certs_config }}"
|
- path: "{{ remote_certs_path }}/{{ certs_config }}"
|
||||||
local: false
|
local: false
|
||||||
|
- path: "{{ password_tool_path }}/{{ password_tool }}"
|
||||||
|
local: false
|
||||||
directories:
|
directories:
|
||||||
- name: "custom_certificates"
|
- name: "src"
|
||||||
files:
|
files:
|
||||||
- path: "configurer/ami/ami_post_configurer/custom_certificates.py"
|
- path: "configurer/ami/ami_post_configurer/wazuh-ami-customizer.py"
|
||||||
local: true
|
local: true
|
||||||
directories:
|
directories:
|
||||||
- name: "configurer"
|
- name: "configurer"
|
||||||
|
|||||||
@ -7,10 +7,12 @@ from configurer.core.utils import ComponentCertsDirectory
|
|||||||
from generic import exec_command
|
from generic import exec_command
|
||||||
from utils import Component, Logger
|
from utils import Component, Logger
|
||||||
|
|
||||||
LOGFILE = Path("/var/log/wazuh-ami-custom-certificates.log")
|
LOGFILE = Path("/var/log/wazuh-ami-customizer.log")
|
||||||
TEMP_DIR = Path("/etc/wazuh-ami-certs-customize")
|
TEMP_DIR = Path("/etc/wazuh-ami-customizer")
|
||||||
CERTS_TOOL_PATH = Path(f"{TEMP_DIR}/certs-tool.sh")
|
CERTS_TOOL_PATH = Path(f"{TEMP_DIR}/certs-tool.sh")
|
||||||
CERTS_TOOL_CONFIG_PATH = Path(f"{TEMP_DIR}/config.yml")
|
CERTS_TOOL_CONFIG_PATH = Path(f"{TEMP_DIR}/config.yml")
|
||||||
|
PASSWORD_TOOL_PATH = Path(f"{TEMP_DIR}/password-tool.sh")
|
||||||
|
PASWORDS_FILE_NAME = Path("/etc/wazuh-ami-customizer/passwords.txt")
|
||||||
SERVICE_PATH = "/etc/systemd/system"
|
SERVICE_PATH = "/etc/systemd/system"
|
||||||
SERVICE_NAME = f"{SERVICE_PATH}/wazuh-ami-customizer.service"
|
SERVICE_NAME = f"{SERVICE_PATH}/wazuh-ami-customizer.service"
|
||||||
SERVICE_TIMER_NAME = f"{SERVICE_PATH}/wazuh-ami-customizer.timer"
|
SERVICE_TIMER_NAME = f"{SERVICE_PATH}/wazuh-ami-customizer.timer"
|
||||||
@ -63,7 +65,7 @@ def stop_service(name: str) -> None:
|
|||||||
logger.debug(f"{name} service stopped")
|
logger.debug(f"{name} service stopped")
|
||||||
|
|
||||||
|
|
||||||
def verify_component_connection(component: Component, command: str, retries: int = 5, wait_time: int = 5) -> None:
|
def verify_component_connection(component: Component, command: str, retries: int = 5, wait_time: int = 10) -> None:
|
||||||
"""
|
"""
|
||||||
Verifies the component connection by sending a request to the component's endpoint.
|
Verifies the component connection by sending a request to the component's endpoint.
|
||||||
Args:
|
Args:
|
||||||
@ -194,13 +196,13 @@ def stop_components_services() -> None:
|
|||||||
logger.debug("Stopping Wazuh components services...")
|
logger.debug("Stopping Wazuh components services...")
|
||||||
|
|
||||||
stop_service("wazuh-indexer")
|
stop_service("wazuh-indexer")
|
||||||
stop_service("wazuh-server")
|
stop_service("wazuh-manager")
|
||||||
stop_service("wazuh-dashboard")
|
stop_service("wazuh-dashboard")
|
||||||
|
|
||||||
logger.debug("Wazuh components services stopped")
|
logger.debug("Wazuh components services stopped")
|
||||||
|
|
||||||
|
|
||||||
def verify_indexer_connection() -> None:
|
def verify_indexer_connection(password: str = "admin") -> None:
|
||||||
"""
|
"""
|
||||||
Verifies the connection to the Wazuh indexer.
|
Verifies the connection to the Wazuh indexer.
|
||||||
This function sends a request to the Wazuh indexer endpoint and checks the response.
|
This function sends a request to the Wazuh indexer endpoint and checks the response.
|
||||||
@ -210,7 +212,7 @@ def verify_indexer_connection() -> None:
|
|||||||
None
|
None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
command = 'curl -XGET https://localhost:9200/ -uadmin:admin -k --max-time 120 --silent -w "%{http_code}" --output /dev/null'
|
command = f"curl -XGET https://localhost:9200/ -uadmin:{password} -k --max-time 120 --silent -w \"%{{http_code}}\" --output /dev/null"
|
||||||
verify_component_connection(Component.WAZUH_INDEXER, command)
|
verify_component_connection(Component.WAZUH_INDEXER, command)
|
||||||
|
|
||||||
|
|
||||||
@ -259,8 +261,8 @@ def start_components_services() -> None:
|
|||||||
run_indexer_security_init()
|
run_indexer_security_init()
|
||||||
verify_indexer_connection()
|
verify_indexer_connection()
|
||||||
|
|
||||||
enable_service("wazuh-server")
|
enable_service("wazuh-manager")
|
||||||
start_service("wazuh-server")
|
start_service("wazuh-manager")
|
||||||
|
|
||||||
enable_service("wazuh-dashboard")
|
enable_service("wazuh-dashboard")
|
||||||
start_service("wazuh-dashboard")
|
start_service("wazuh-dashboard")
|
||||||
@ -269,6 +271,70 @@ def start_components_services() -> None:
|
|||||||
logger.debug("Wazuh components services started")
|
logger.debug("Wazuh components services started")
|
||||||
|
|
||||||
|
|
||||||
|
def get_instance_id() -> str:
|
||||||
|
"""
|
||||||
|
Retrieves the instance ID of the current machine capitalized.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The instance ID of the current machine.
|
||||||
|
"""
|
||||||
|
|
||||||
|
logger.debug("Retrieving instance ID")
|
||||||
|
|
||||||
|
command = "ec2-metadata | grep 'instance-id' | cut -d':' -f2"
|
||||||
|
output, error_output = exec_command(command=command)
|
||||||
|
if error_output:
|
||||||
|
logger.error(f"Error retrieving instance ID: {error_output}")
|
||||||
|
raise RuntimeError("Error retrieving instance ID")
|
||||||
|
return output.strip().capitalize()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_password_file() -> None:
|
||||||
|
"""
|
||||||
|
Generates a password file using the password tool.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (Path): The path where the password file will be created.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
|
||||||
|
logger.debug("Generating password file")
|
||||||
|
|
||||||
|
command = f"bash {PASSWORD_TOOL_PATH} -gf {PASWORDS_FILE_NAME}"
|
||||||
|
_, error_output = exec_command(command=command)
|
||||||
|
if error_output:
|
||||||
|
logger.error(f"Error generating password file: {error_output}")
|
||||||
|
raise RuntimeError("Error generating password file")
|
||||||
|
|
||||||
|
logger.debug("Password file generated")
|
||||||
|
|
||||||
|
|
||||||
|
def change_passwords() -> None:
|
||||||
|
logger.name = "CustomPasswords"
|
||||||
|
logger.debug("Changing passwords started")
|
||||||
|
logger.debug("Getting instance ID")
|
||||||
|
instance_id = get_instance_id()
|
||||||
|
|
||||||
|
generate_password_file()
|
||||||
|
|
||||||
|
logger.debug("Changing passwords to instance ID")
|
||||||
|
command = f"""
|
||||||
|
sudo sed -i 's/password:.*/password: {instance_id}/g' {PASWORDS_FILE_NAME}
|
||||||
|
bash {PASSWORD_TOOL_PATH} -a -A -au wazuh -ap wazuh -f {PASWORDS_FILE_NAME}
|
||||||
|
"""
|
||||||
|
|
||||||
|
_, error_output = exec_command(command=command)
|
||||||
|
if error_output:
|
||||||
|
logger.error(f"Error changing passwords: {error_output}")
|
||||||
|
raise RuntimeError("Error changing passwords")
|
||||||
|
|
||||||
|
logger.debug("Passwords changed. Verifying indexer connection with new password")
|
||||||
|
verify_indexer_connection(password=instance_id)
|
||||||
|
logger.debug("Changing passwords finished successfully")
|
||||||
|
|
||||||
|
|
||||||
def clean_up() -> None:
|
def clean_up() -> None:
|
||||||
"""
|
"""
|
||||||
Cleans up temporary files and directories created during the process.
|
Cleans up temporary files and directories created during the process.
|
||||||
@ -301,11 +367,14 @@ if __name__ == "__main__":
|
|||||||
remove_certificates()
|
remove_certificates()
|
||||||
create_certificates()
|
create_certificates()
|
||||||
start_components_services()
|
start_components_services()
|
||||||
|
stop_service("wazuh-dashboard")
|
||||||
|
change_passwords()
|
||||||
|
start_service("wazuh-dashboard")
|
||||||
start_ssh_service()
|
start_ssh_service()
|
||||||
clean_up()
|
clean_up()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"An error occurred during the custom certificates configuration process: {e}")
|
logger.error(f"An error occurred during the customization process: {e}")
|
||||||
start_ssh_service()
|
start_ssh_service()
|
||||||
raise RuntimeError("An error occurred during the custom certificates configuration process") from e
|
raise RuntimeError("An error occurred during the customization process") from e
|
||||||
|
|
||||||
logger.info("Custom certificates configuration process finished")
|
logger.info("Customization process finished")
|
||||||
@ -13,8 +13,8 @@ Wants=wazuh-ami-customizer.timer
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
WorkingDirectory=/etc/wazuh-ami-certs-customize/custom_certificates
|
WorkingDirectory=/etc/wazuh-ami-customizer/src
|
||||||
ExecStart=/etc/wazuh-ami-certs-customize/certs-env/bin/python -m custom_certificates
|
ExecStart=/etc/wazuh-ami-customizer/customizer-env/bin/python -m wazuh-ami-customizer
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@ -95,6 +95,7 @@ def main(
|
|||||||
Provisioner(
|
Provisioner(
|
||||||
inventory=input.inventory_content,
|
inventory=input.inventory_content,
|
||||||
certs=input.certificates_content,
|
certs=input.certificates_content,
|
||||||
|
password_tool=input.password_tool_url,
|
||||||
components=components,
|
components=components,
|
||||||
arch=input.arch,
|
arch=input.arch,
|
||||||
package_type=input.package_type,
|
package_type=input.package_type,
|
||||||
|
|||||||
@ -3,3 +3,4 @@ from .component_info import ComponentInfo
|
|||||||
from .components_dependencies import ComponentsDependencies
|
from .components_dependencies import ComponentsDependencies
|
||||||
from .input import Input
|
from .input import Input
|
||||||
from .package_info import PackageInfo
|
from .package_info import PackageInfo
|
||||||
|
from .password_tool_info import PasswordToolInfo
|
||||||
|
|||||||
@ -40,7 +40,7 @@ class CertsInfo(BaseModel):
|
|||||||
"""
|
"""
|
||||||
logger.debug(f"Getting URL for {name}...")
|
logger.debug(f"Getting URL for {name}...")
|
||||||
try:
|
try:
|
||||||
url = AnyUrl(self.certs_url_content.get(name, None))
|
url = AnyUrl(self.certs_url_content.get(name, None)) # type: ignore
|
||||||
except pydantic_core._pydantic_core.ValidationError as err:
|
except pydantic_core._pydantic_core.ValidationError as err:
|
||||||
raise ValueError(f"URL for {name} has an invalid format: {err}") from err
|
raise ValueError(f"URL for {name} has an invalid format: {err}") from err
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,8 @@ from utils import Component
|
|||||||
from .certs_info import CertsInfo
|
from .certs_info import CertsInfo
|
||||||
from .components_dependencies import ComponentsDependencies
|
from .components_dependencies import ComponentsDependencies
|
||||||
from .package_info import PackageInfo
|
from .package_info import PackageInfo
|
||||||
from .utils import format_certificates_urls_file, format_component_urls_file
|
from .password_tool_info import PasswordToolInfo
|
||||||
|
from .utils import format_certificates_urls_file, format_component_urls_file, format_password_tool_urls_file
|
||||||
|
|
||||||
|
|
||||||
class Input(BaseModel):
|
class Input(BaseModel):
|
||||||
@ -67,6 +68,16 @@ class Input(BaseModel):
|
|||||||
except FileNotFoundError as err:
|
except FileNotFoundError as err:
|
||||||
raise FileNotFoundError(f"Certificates file not found at {self.packages_url_path}") from err
|
raise FileNotFoundError(f"Certificates file not found at {self.packages_url_path}") from err
|
||||||
|
|
||||||
|
@property
|
||||||
|
def password_tool_url(self) -> PasswordToolInfo:
|
||||||
|
try:
|
||||||
|
password_tool_data = format_password_tool_urls_file(self.packages_url_path)
|
||||||
|
if password_tool_data is None:
|
||||||
|
raise ValueError("Password tool URL not found in the packages URL file.")
|
||||||
|
return PasswordToolInfo(password_tool_url=password_tool_data)
|
||||||
|
except FileNotFoundError as err:
|
||||||
|
raise FileNotFoundError(f"Password tool file not found at {self.packages_url_path}") from err
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def inventory_content(self, host_name: str | None = None) -> Inventory | None:
|
def inventory_content(self, host_name: str | None = None) -> Inventory | None:
|
||||||
return Inventory(self.inventory_path, host_name) if self.inventory_path else None
|
return Inventory(self.inventory_path, host_name) if self.inventory_path else None
|
||||||
|
|||||||
30
provisioner/models/password_tool_info.py
Normal file
30
provisioner/models/password_tool_info.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
from pydantic import AnyUrl, BaseModel, field_validator
|
||||||
|
|
||||||
|
from provisioner.utils import AllowedUrlHost
|
||||||
|
from utils import Logger
|
||||||
|
|
||||||
|
from .utils import check_correct_url
|
||||||
|
|
||||||
|
logger = Logger("Password-tool provision")
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordToolInfo(BaseModel):
|
||||||
|
"""
|
||||||
|
PasswordToolInfo is a model that holds information about password tool URL.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
password_tool_url (str): A string containing the URL for the password-tool.
|
||||||
|
"""
|
||||||
|
|
||||||
|
password_tool_url: AnyUrl
|
||||||
|
|
||||||
|
@field_validator("password_tool_url")
|
||||||
|
def validate_password_tool_url(cls, url: AnyUrl) -> AnyUrl:
|
||||||
|
logger.debug("Validating password tool URL...")
|
||||||
|
if not check_correct_url(
|
||||||
|
url,
|
||||||
|
[AllowedUrlHost.RELEASE, AllowedUrlHost.PRE_RELEASE, AllowedUrlHost.INTERNAL],
|
||||||
|
):
|
||||||
|
raise ValueError("URL for password-tool is not for Wazuh packages.")
|
||||||
|
|
||||||
|
return url
|
||||||
@ -1,2 +1,2 @@
|
|||||||
from .file_formatter import format_certificates_urls_file, format_component_urls_file
|
from .file_formatter import format_certificates_urls_file, format_component_urls_file, format_password_tool_urls_file
|
||||||
from .helpers import check_correct_url
|
from .helpers import check_correct_url
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
from pydantic import AnyUrl
|
||||||
|
|
||||||
from provisioner.utils import (
|
from provisioner.utils import (
|
||||||
Component_arch,
|
Component_arch,
|
||||||
Package_type,
|
Package_type,
|
||||||
)
|
)
|
||||||
from utils import CertificatesComponent, Component
|
from utils import CertificatesComponent, Component, PasswordToolComponent
|
||||||
|
|
||||||
|
|
||||||
def file_to_dict(raw_urls_path: Path) -> dict:
|
def file_to_dict(raw_urls_path: Path) -> dict:
|
||||||
@ -157,6 +158,31 @@ def format_certificates_urls_file(raw_urls_path: Path) -> dict:
|
|||||||
return certificates_urls
|
return certificates_urls
|
||||||
|
|
||||||
|
|
||||||
|
def format_password_tool_urls_file(raw_urls_path: Path) -> AnyUrl | None:
|
||||||
|
"""
|
||||||
|
Formats a file containing raw URLs into a string of password tool URL.
|
||||||
|
|
||||||
|
This function reads a file containing raw URLs and retrieves the URL
|
||||||
|
for the password tool.
|
||||||
|
|
||||||
|
>>> raw_urls_path = Path("password_tool_urls.yaml")
|
||||||
|
>>> format_password_tool_urls_file(raw_urls_path)
|
||||||
|
'https://packages.wazuh.com/password-tool-example/password_tool'
|
||||||
|
|
||||||
|
Args:
|
||||||
|
raw_urls_path (Path): The path to the file containing the raw URLs.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The URL for the password tool.
|
||||||
|
"""
|
||||||
|
raw_urls_content = file_to_dict(raw_urls_path)
|
||||||
|
|
||||||
|
for component_name, url in raw_urls_content.items():
|
||||||
|
if PasswordToolComponent.PASSWORD_TOOL.name.lower() in component_name.lower():
|
||||||
|
return AnyUrl(url)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def format_component_urls_file(raw_urls_path: Path) -> dict:
|
def format_component_urls_file(raw_urls_path: Path) -> dict:
|
||||||
"""
|
"""
|
||||||
Formats the component URLs file by processing raw URLs and organizing them by component, architecture, and type.
|
Formats the component URLs file by processing raw URLs and organizing them by component, architecture, and type.
|
||||||
|
|||||||
@ -5,9 +5,9 @@ from pydantic import AnyUrl
|
|||||||
|
|
||||||
from generic import exec_command, remote_connection
|
from generic import exec_command, remote_connection
|
||||||
from models import Inventory
|
from models import Inventory
|
||||||
from provisioner.models import CertsInfo, ComponentInfo
|
from provisioner.models import CertsInfo, ComponentInfo, PasswordToolInfo
|
||||||
from provisioner.utils import Component_arch, Package_manager, Package_type
|
from provisioner.utils import Component_arch, Package_manager, Package_type
|
||||||
from utils import CertificatesComponent, Component, Logger, RemoteDirectories
|
from utils import CertificatesComponent, Component, Logger, PasswordToolComponent, RemoteDirectories
|
||||||
|
|
||||||
logger = Logger("Provisioner")
|
logger = Logger("Provisioner")
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ class Provisioner:
|
|||||||
|
|
||||||
inventory: Inventory | None
|
inventory: Inventory | None
|
||||||
certs: CertsInfo
|
certs: CertsInfo
|
||||||
|
password_tool: PasswordToolInfo
|
||||||
components: list[ComponentInfo]
|
components: list[ComponentInfo]
|
||||||
arch: Component_arch = Component_arch.X86_64
|
arch: Component_arch = Component_arch.X86_64
|
||||||
package_type: Package_type = Package_type.RPM
|
package_type: Package_type = Package_type.RPM
|
||||||
@ -49,7 +50,8 @@ class Provisioner:
|
|||||||
1. Logs the start of the provisioning process.
|
1. Logs the start of the provisioning process.
|
||||||
2. Provisions the certs_tool using `certs_tool_provision`.
|
2. Provisions the certs_tool using `certs_tool_provision`.
|
||||||
3. Provision the config file using `certs_config_provision`.
|
3. Provision the config file using `certs_config_provision`.
|
||||||
4. Iterates over each component and performs the following:
|
4. Provisions the password tool using `password_tool_provision`.
|
||||||
|
5. Iterates over each component and performs the following:
|
||||||
a. Logs the start of provisioning for the component.
|
a. Logs the start of provisioning for the component.
|
||||||
b. Provisions dependencies for the component using `dependencies_provision`.
|
b. Provisions dependencies for the component using `dependencies_provision`.
|
||||||
c. Provisions packages for the component using `packages_provision`.
|
c. Provisions packages for the component using `packages_provision`.
|
||||||
@ -63,6 +65,10 @@ class Provisioner:
|
|||||||
self.certs_tool_provision(client)
|
self.certs_tool_provision(client)
|
||||||
self.certs_config_provision(client)
|
self.certs_config_provision(client)
|
||||||
|
|
||||||
|
logger.debug_title("Provisioning password tool")
|
||||||
|
|
||||||
|
self.password_tool_provision(client)
|
||||||
|
|
||||||
logger.debug_title("Provisioning special dependencies")
|
logger.debug_title("Provisioning special dependencies")
|
||||||
|
|
||||||
self.special_dependencies_provision(client)
|
self.special_dependencies_provision(client)
|
||||||
@ -77,20 +83,22 @@ class Provisioner:
|
|||||||
Provisions the certs_tool on the specified client.
|
Provisions the certs_tool on the specified client.
|
||||||
|
|
||||||
This method uses the provided SSH client to connect to a remote machine
|
This method uses the provided SSH client to connect to a remote machine
|
||||||
and provision the certs_tool by calling the `certificates_provision`
|
and provision the certs_tool by calling the `tool_provision`
|
||||||
method with the appropriate URL.
|
method with the appropriate URL.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
client (paramiko.SSHClient): The SSH client used to connect to the remote machine.
|
client (paramiko.SSHClient): The SSH client used to connect to the remote machine.
|
||||||
"""
|
"""
|
||||||
self.certificates_provision(self.certs.certs_tool_url, CertificatesComponent.CERTS_TOOL, client)
|
self.tool_provision(
|
||||||
|
self.certs.certs_tool_url, f"{RemoteDirectories.CERTS}", CertificatesComponent.CERTS_TOOL, client
|
||||||
|
)
|
||||||
|
|
||||||
def certs_config_provision(self, client: paramiko.SSHClient | None = None) -> None:
|
def certs_config_provision(self, client: paramiko.SSHClient | None = None) -> None:
|
||||||
"""
|
"""
|
||||||
Provisions the certs config file on the remote client.
|
Provisions the certs config file on the remote client.
|
||||||
|
|
||||||
This method uses the provided SSH client to connect to a remote machine
|
This method uses the provided SSH client to connect to a remote machine
|
||||||
and provision the certs config file by calling the `certificates_provision`
|
and provision the certs config file by calling the `tool_provision`
|
||||||
method with the appropriate URL.
|
method with the appropriate URL.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -99,7 +107,25 @@ class Provisioner:
|
|||||||
Returns:
|
Returns:
|
||||||
None
|
None
|
||||||
"""
|
"""
|
||||||
self.certificates_provision(self.certs.config_url, CertificatesComponent.CONFIG, client)
|
self.tool_provision(self.certs.config_url, f"{RemoteDirectories.CERTS}", CertificatesComponent.CONFIG, client)
|
||||||
|
|
||||||
|
def password_tool_provision(self, client: paramiko.SSHClient | None = None) -> None:
|
||||||
|
"""
|
||||||
|
Provisions the password tool on the specified client.
|
||||||
|
|
||||||
|
This method uses the provided SSH client to connect to a remote machine
|
||||||
|
and provision the password tool by calling the `tool_provision`
|
||||||
|
method with the appropriate URL.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
client (paramiko.SSHClient): The SSH client used to connect to the remote machine.
|
||||||
|
"""
|
||||||
|
self.tool_provision(
|
||||||
|
self.password_tool.password_tool_url,
|
||||||
|
f"{RemoteDirectories.PASSWORD_TOOL}",
|
||||||
|
PasswordToolComponent.PASSWORD_TOOL,
|
||||||
|
client,
|
||||||
|
)
|
||||||
|
|
||||||
def special_dependencies_provision(self, client: paramiko.SSHClient | None = None) -> None:
|
def special_dependencies_provision(self, client: paramiko.SSHClient | None = None) -> None:
|
||||||
"""
|
"""
|
||||||
@ -177,39 +203,33 @@ class Provisioner:
|
|||||||
component.name.replace("_", " ").capitalize(),
|
component.name.replace("_", " ").capitalize(),
|
||||||
)
|
)
|
||||||
|
|
||||||
def certificates_provision(
|
def tool_provision(
|
||||||
self, certs_file_url: AnyUrl, filename: str, client: paramiko.SSHClient | None = None
|
self, tool_url: AnyUrl, tool_dir: str, tool_filename: str, client: paramiko.SSHClient | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Downloads a certificate file (certs_tool or config) from a given URL and saves it to a remote directory on a server.
|
Provisions a tool (certs_tool, config file, or password tool) on the remote client.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
certs_file_url (AnyUrl): The URL of the certificate file to be downloaded.
|
tool_url (AnyUrl): The URL of the tool to be provisioned.
|
||||||
client (paramiko.SSHClient): An active SSH client connected to the remote server.
|
tool_dir (str): The directory on the remote client where the tool will be stored.
|
||||||
|
tool_filename (str): The filename of the tool to be provisioned.
|
||||||
Raises:
|
client (paramiko.SSHClient): The SSH client used to connect to the remote machine.
|
||||||
Exception: If there is an error during the download process.
|
|
||||||
|
|
||||||
Logs:
|
|
||||||
Error message if the download fails.
|
|
||||||
Success message if the download is successful.
|
|
||||||
"""
|
"""
|
||||||
logger.debug(f"Provisioning {filename}")
|
logger.debug(f"Provisioning {tool_filename}")
|
||||||
|
|
||||||
command_template = "mkdir -p {dir} && curl -s -o {path} '{certs_file_url}'"
|
command_template = "mkdir -p {directory} && curl -s -o {path} '{tool_file_url}'"
|
||||||
|
|
||||||
command = command_template.format(
|
command = command_template.format(
|
||||||
dir=f"{RemoteDirectories.CERTS}",
|
directory=tool_dir,
|
||||||
path=f"{RemoteDirectories.CERTS}/{filename}",
|
path=f"{tool_dir}/{tool_filename}",
|
||||||
certs_file_url=certs_file_url,
|
tool_file_url=tool_url,
|
||||||
)
|
)
|
||||||
output, error_output = exec_command(command=command, client=client)
|
_, error_output = exec_command(command=command, client=client)
|
||||||
|
|
||||||
if error_output:
|
if error_output:
|
||||||
logger.error(f"Error downloading {filename}: {error_output}")
|
logger.error(f"Error downloading {tool_filename}: {error_output}")
|
||||||
raise RuntimeError(f"Error downloading {filename}")
|
raise RuntimeError(f"Error downloading {tool_filename}")
|
||||||
|
|
||||||
logger.info_success(f"{filename} downloaded successfully")
|
logger.info_success(f"{tool_filename} downloaded successfully")
|
||||||
|
|
||||||
def list_dependencies(self, elements: list[str], component_name: str) -> None:
|
def list_dependencies(self, elements: list[str], component_name: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -41,6 +41,7 @@ def mock_logger(autouse=True):
|
|||||||
logger_paths = [
|
logger_paths = [
|
||||||
"provisioner.provisioner.logger",
|
"provisioner.provisioner.logger",
|
||||||
"provisioner.models.certs_info.logger",
|
"provisioner.models.certs_info.logger",
|
||||||
|
"provisioner.models.password_tool_info.logger",
|
||||||
"generic.remote_connection.logger",
|
"generic.remote_connection.logger",
|
||||||
"configurer.core.models.wazuh_components_config_manager.logger",
|
"configurer.core.models.wazuh_components_config_manager.logger",
|
||||||
"configurer.core.models.certificates_manager.logger",
|
"configurer.core.models.certificates_manager.logger",
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from unittest.mock import MagicMock, patch
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from configurer.ami.ami_post_configurer.ami_post_configurer import AmiPostConfigurer
|
from configurer.ami.ami_post_configurer.ami_post_configurer import AmiPostConfigurer
|
||||||
from utils.enums import CertificatesComponent, RemoteDirectories
|
from utils.enums import CertificatesComponent, PasswordToolComponent, RemoteDirectories
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
@ -78,6 +78,8 @@ def test_create_custom_dir_success(mock_create_structure, mock_generate_yaml, mo
|
|||||||
"remote_certs_path": RemoteDirectories.CERTS,
|
"remote_certs_path": RemoteDirectories.CERTS,
|
||||||
"certs_tool": CertificatesComponent.CERTS_TOOL,
|
"certs_tool": CertificatesComponent.CERTS_TOOL,
|
||||||
"certs_config": CertificatesComponent.CONFIG,
|
"certs_config": CertificatesComponent.CONFIG,
|
||||||
|
"password_tool_path": RemoteDirectories.PASSWORD_TOOL,
|
||||||
|
"password_tool": PasswordToolComponent.PASSWORD_TOOL,
|
||||||
}
|
}
|
||||||
|
|
||||||
mock_generate_yaml.return_value = {"template": "test_value"}
|
mock_generate_yaml.return_value = {"template": "test_value"}
|
||||||
@ -145,11 +147,11 @@ def test_stop_service_fails(mock_ami_post_configurer, mock_exec_command, mock_pa
|
|||||||
|
|
||||||
def test_stop_wazuh_server(mock_ami_post_configurer, mock_exec_command, mock_paramiko, mock_logger):
|
def test_stop_wazuh_server(mock_ami_post_configurer, mock_exec_command, mock_paramiko, mock_logger):
|
||||||
mock_ami_post_configurer.stop_wazuh_server(mock_paramiko.return_value)
|
mock_ami_post_configurer.stop_wazuh_server(mock_paramiko.return_value)
|
||||||
command = "sudo systemctl stop wazuh-server"
|
command = "sudo systemctl stop wazuh-manager"
|
||||||
mock_exec_command.assert_called_once_with(command=command, client=mock_paramiko.return_value)
|
mock_exec_command.assert_called_once_with(command=command, client=mock_paramiko.return_value)
|
||||||
|
|
||||||
mock_logger.debug.assert_called_once_with("Stopping wazuh-server service")
|
mock_logger.debug.assert_called_once_with("Stopping wazuh-manager service")
|
||||||
mock_logger.info_success.assert_called_once_with("wazuh-server service stopped successfully")
|
mock_logger.info_success.assert_called_once_with("wazuh-manager service stopped successfully")
|
||||||
|
|
||||||
|
|
||||||
def test_stop_wazuh_indexer(mock_ami_post_configurer, mock_exec_command, mock_paramiko, mock_logger):
|
def test_stop_wazuh_indexer(mock_ami_post_configurer, mock_exec_command, mock_paramiko, mock_logger):
|
||||||
@ -176,7 +178,9 @@ def test_stop_wazuh_indexer(mock_ami_post_configurer, mock_exec_command, mock_pa
|
|||||||
def test_remove_wazuh_indexes(mock_ami_post_configurer, mock_exec_command, mock_paramiko, mock_logger):
|
def test_remove_wazuh_indexes(mock_ami_post_configurer, mock_exec_command, mock_paramiko, mock_logger):
|
||||||
mock_ami_post_configurer.remove_wazuh_indexes(mock_paramiko.return_value)
|
mock_ami_post_configurer.remove_wazuh_indexes(mock_paramiko.return_value)
|
||||||
|
|
||||||
command = 'sudo curl -s -o /dev/null -w "%{http_code}" -X DELETE -u "admin:admin" -k "https://127.0.0.1:9200/wazuh-*"'
|
command = (
|
||||||
|
'sudo curl -s -o /dev/null -w "%{http_code}" -X DELETE -u "admin:admin" -k "https://127.0.0.1:9200/wazuh-*"'
|
||||||
|
)
|
||||||
|
|
||||||
mock_exec_command.assert_called_once_with(command=command, client=mock_paramiko.return_value)
|
mock_exec_command.assert_called_once_with(command=command, client=mock_paramiko.return_value)
|
||||||
|
|
||||||
@ -192,6 +196,7 @@ def test_remove_wazuh_indexes_fail(mock_ami_post_configurer, mock_exec_command,
|
|||||||
|
|
||||||
mock_logger.error.assert_called_once_with("Error removing wazuh- indexes")
|
mock_logger.error.assert_called_once_with("Error removing wazuh- indexes")
|
||||||
|
|
||||||
|
|
||||||
def test_run_security_init_script(mock_ami_post_configurer, mock_exec_command, mock_paramiko, mock_logger):
|
def test_run_security_init_script(mock_ami_post_configurer, mock_exec_command, mock_paramiko, mock_logger):
|
||||||
mock_ami_post_configurer.run_security_init_script(mock_paramiko.return_value)
|
mock_ami_post_configurer.run_security_init_script(mock_paramiko.return_value)
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ from pydantic import AnyUrl
|
|||||||
|
|
||||||
from provisioner.models.certs_info import CertsInfo
|
from provisioner.models.certs_info import CertsInfo
|
||||||
from provisioner.models.component_info import ComponentInfo
|
from provisioner.models.component_info import ComponentInfo
|
||||||
|
from provisioner.models.password_tool_info import PasswordToolInfo
|
||||||
from provisioner.provisioner import Provisioner
|
from provisioner.provisioner import Provisioner
|
||||||
from provisioner.utils import Package_manager, Package_type
|
from provisioner.utils import Package_manager, Package_type
|
||||||
from utils.enums import Component
|
from utils.enums import Component
|
||||||
@ -32,10 +33,13 @@ def component_info_valid(valid_inventory):
|
|||||||
"config": "http://packages-dev.wazuh.com/example/config.yml",
|
"config": "http://packages-dev.wazuh.com/example/config.yml",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
password_tool = PasswordToolInfo(password_tool_url=AnyUrl("http://packages-dev.wazuh.com/example/password-tool.sh"))
|
||||||
|
|
||||||
package_type = Package_type.RPM
|
package_type = Package_type.RPM
|
||||||
return Provisioner(
|
return Provisioner(
|
||||||
inventory=valid_inventory,
|
inventory=valid_inventory,
|
||||||
certs=certs,
|
certs=certs,
|
||||||
|
password_tool=password_tool,
|
||||||
components=[component_server],
|
components=[component_server],
|
||||||
package_type=package_type,
|
package_type=package_type,
|
||||||
)
|
)
|
||||||
@ -56,9 +60,10 @@ def test_provision_success(mock_paramiko, mock_logger, component_info_valid, moc
|
|||||||
mock_client_instance = MagicMock()
|
mock_client_instance = MagicMock()
|
||||||
mock_paramiko.return_value = mock_client_instance
|
mock_paramiko.return_value = mock_client_instance
|
||||||
|
|
||||||
certs_expect_commands = [
|
tools_expect_commands = [
|
||||||
"mkdir -p ~/wazuh-configure/certs && curl -s -o ~/wazuh-configure/certs/certs-tool.sh 'http://packages-dev.wazuh.com/example/certs-tool.sh'",
|
"mkdir -p ~/wazuh-configure/tools/certs && curl -s -o ~/wazuh-configure/tools/certs/certs-tool.sh 'http://packages-dev.wazuh.com/example/certs-tool.sh'",
|
||||||
"mkdir -p ~/wazuh-configure/certs && curl -s -o ~/wazuh-configure/certs/config.yml 'http://packages-dev.wazuh.com/example/config.yml'",
|
"mkdir -p ~/wazuh-configure/tools/certs && curl -s -o ~/wazuh-configure/tools/certs/config.yml 'http://packages-dev.wazuh.com/example/config.yml'",
|
||||||
|
"mkdir -p ~/wazuh-configure/tools && curl -s -o ~/wazuh-configure/tools/password-tool.sh 'http://packages-dev.wazuh.com/example/password-tool.sh'"
|
||||||
]
|
]
|
||||||
|
|
||||||
dependencies_expect_commands = [
|
dependencies_expect_commands = [
|
||||||
@ -85,22 +90,22 @@ def test_provision_success(mock_paramiko, mock_logger, component_info_valid, moc
|
|||||||
key_filename=str(component_info_valid.inventory.ansible_ssh_private_key_file),
|
key_filename=str(component_info_valid.inventory.ansible_ssh_private_key_file),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert mock_exec_command.call_count == 7 # 3 for dependencies, 2 for certs, 1 download package, 1 install package
|
assert mock_exec_command.call_count == 8 # 3 for dependencies, 3 for tools (certs-tool and password-tool), 1 download package, 1 install package
|
||||||
|
|
||||||
# certs
|
# tools
|
||||||
assert certs_expect_commands[0] in mock_exec_command.call_args_list[0].kwargs["command"]
|
assert tools_expect_commands[0] in mock_exec_command.call_args_list[0].kwargs["command"]
|
||||||
assert certs_expect_commands[1] in mock_exec_command.call_args_list[1].kwargs["command"]
|
assert tools_expect_commands[1] in mock_exec_command.call_args_list[1].kwargs["command"]
|
||||||
|
assert tools_expect_commands[2] in mock_exec_command.call_args_list[2].kwargs["command"]
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
assert dependencies_expect_commands[0] in mock_exec_command.call_args_list[2].kwargs["command"]
|
assert dependencies_expect_commands[0] in mock_exec_command.call_args_list[3].kwargs["command"]
|
||||||
assert dependencies_expect_commands[1] in mock_exec_command.call_args_list[2].kwargs["command"]
|
assert dependencies_expect_commands[1] in mock_exec_command.call_args_list[3].kwargs["command"]
|
||||||
assert dependencies_expect_commands[2] in mock_exec_command.call_args_list[3].kwargs["command"]
|
assert dependencies_expect_commands[2] in mock_exec_command.call_args_list[4].kwargs["command"]
|
||||||
assert dependencies_expect_commands[3] in mock_exec_command.call_args_list[4].kwargs["command"]
|
assert dependencies_expect_commands[3] in mock_exec_command.call_args_list[5].kwargs["command"]
|
||||||
|
|
||||||
# package
|
# package
|
||||||
assert package_expect_commands[0] in mock_exec_command.call_args_list[5].kwargs["command"]
|
assert package_expect_commands[0] in mock_exec_command.call_args_list[6].kwargs["command"]
|
||||||
assert package_expect_commands[1] in mock_exec_command.call_args_list[6].kwargs["command"]
|
assert package_expect_commands[1] in mock_exec_command.call_args_list[7].kwargs["command"]
|
||||||
|
|
||||||
mock_logger.debug_title.assert_any_call("Starting provisioning")
|
mock_logger.debug_title.assert_any_call("Starting provisioning")
|
||||||
mock_logger.debug_title.assert_any_call("Provisioning certificates files")
|
mock_logger.debug_title.assert_any_call("Provisioning certificates files")
|
||||||
mock_logger.debug_title.assert_any_call("Starting provisioning for wazuh manager")
|
mock_logger.debug_title.assert_any_call("Starting provisioning for wazuh manager")
|
||||||
@ -120,7 +125,7 @@ def test_certs_tool_provision_success(
|
|||||||
getattr(component_info_valid, certs_method)(mock_client_instance)
|
getattr(component_info_valid, certs_method)(mock_client_instance)
|
||||||
|
|
||||||
mock_exec_command.assert_called_once_with(
|
mock_exec_command.assert_called_once_with(
|
||||||
command=f"mkdir -p ~/wazuh-configure/certs && curl -s -o ~/wazuh-configure/certs/{certs_component} 'http://packages-dev.wazuh.com/example/{certs_component}'",
|
command=f"mkdir -p ~/wazuh-configure/tools/certs && curl -s -o ~/wazuh-configure/tools/certs/{certs_component} 'http://packages-dev.wazuh.com/example/{certs_component}'",
|
||||||
client=mock_client_instance,
|
client=mock_client_instance,
|
||||||
)
|
)
|
||||||
mock_logger.debug.assert_any_call(f"Provisioning {certs_component}")
|
mock_logger.debug.assert_any_call(f"Provisioning {certs_component}")
|
||||||
@ -142,7 +147,7 @@ def test_certs_tool_provision_failure(
|
|||||||
getattr(component_info_valid, certs_method)(mock_client_instance)
|
getattr(component_info_valid, certs_method)(mock_client_instance)
|
||||||
|
|
||||||
mock_exec_command.assert_called_once_with(
|
mock_exec_command.assert_called_once_with(
|
||||||
command=f"mkdir -p ~/wazuh-configure/certs && curl -s -o ~/wazuh-configure/certs/{certs_component} 'http://packages-dev.wazuh.com/example/{certs_component}'",
|
command=f"mkdir -p ~/wazuh-configure/tools/certs && curl -s -o ~/wazuh-configure/tools/certs/{certs_component} 'http://packages-dev.wazuh.com/example/{certs_component}'",
|
||||||
client=mock_client_instance,
|
client=mock_client_instance,
|
||||||
)
|
)
|
||||||
mock_logger.debug.assert_any_call(f"Provisioning {certs_component}")
|
mock_logger.debug.assert_any_call(f"Provisioning {certs_component}")
|
||||||
@ -345,9 +350,10 @@ def test_install_package(
|
|||||||
if "installed successfully" in expected_log and "WARNING" not in error_output:
|
if "installed successfully" in expected_log and "WARNING" not in error_output:
|
||||||
mock_logger.info_success.assert_called_once_with(f"{package_name} {expected_log}")
|
mock_logger.info_success.assert_called_once_with(f"{package_name} {expected_log}")
|
||||||
elif "is already installed" in expected_log:
|
elif "is already installed" in expected_log:
|
||||||
mock_logger.debug.assert_has_calls(
|
mock_logger.debug.assert_has_calls([
|
||||||
[mock.call(f"Installing {package_name}"), mock.call(f"{package_name} {expected_log}")]
|
mock.call(f"Installing {package_name}"),
|
||||||
)
|
mock.call(f"{package_name} {expected_log}"),
|
||||||
|
])
|
||||||
elif "installed successfully" in expected_log and "WARNING" in error_output:
|
elif "installed successfully" in expected_log and "WARNING" in error_output:
|
||||||
mock_logger.warning.assert_called_once_with(f"{error_output}")
|
mock_logger.warning.assert_called_once_with(f"{error_output}")
|
||||||
mock_logger.info_success.assert_called_once_with(f"{package_name} {expected_log}")
|
mock_logger.info_success.assert_called_once_with(f"{package_name} {expected_log}")
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
from .enums import CertificatesComponent, Component, RemoteDirectories
|
from .enums import CertificatesComponent, Component, PasswordToolComponent, RemoteDirectories
|
||||||
from .logger import Logger
|
from .logger import Logger
|
||||||
|
|||||||
@ -8,6 +8,10 @@ class Component(StrEnum):
|
|||||||
ALL = auto()
|
ALL = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordToolComponent(StrEnum):
|
||||||
|
PASSWORD_TOOL = "password-tool.sh"
|
||||||
|
|
||||||
|
|
||||||
class CertificatesComponent(StrEnum):
|
class CertificatesComponent(StrEnum):
|
||||||
CERTS_TOOL = "certs-tool.sh"
|
CERTS_TOOL = "certs-tool.sh"
|
||||||
CONFIG = "config.yml"
|
CONFIG = "config.yml"
|
||||||
@ -15,5 +19,7 @@ class CertificatesComponent(StrEnum):
|
|||||||
|
|
||||||
class RemoteDirectories(StrEnum):
|
class RemoteDirectories(StrEnum):
|
||||||
WAZUH_ROOT_DIR = "~/wazuh-configure"
|
WAZUH_ROOT_DIR = "~/wazuh-configure"
|
||||||
|
TOOLS_DIR = f"{WAZUH_ROOT_DIR}/tools"
|
||||||
PACKAGES = f"{WAZUH_ROOT_DIR}/packages"
|
PACKAGES = f"{WAZUH_ROOT_DIR}/packages"
|
||||||
CERTS = f"{WAZUH_ROOT_DIR}/certs"
|
CERTS = f"{TOOLS_DIR}/certs"
|
||||||
|
PASSWORD_TOOL = f"{TOOLS_DIR}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user