Skip to content

Commit

Permalink
Merge pull request #4980 from wazuh/4852-dtt1-iteration-3-provision-m…
Browse files Browse the repository at this point in the history
…odule-improvements-and-fixes

Merge provision module into main DTT1
  • Loading branch information
pro-akim authored Feb 19, 2024
2 parents eca6527 + 4843122 commit ca42f7a
Show file tree
Hide file tree
Showing 14 changed files with 390 additions and 339 deletions.
13 changes: 12 additions & 1 deletion deployability/modules/generic/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,25 @@ def get_template_list(path, custom_order=None) -> list[Path]:
return sorted_list

@staticmethod
def load_from_yaml(file_path, map_keys=None, specific_key=None):
def load_from_yaml(file_path: str | Path, map_keys: dict = None, specific_key: dict = None) -> dict:
"""
Load data from a yaml file.
Args:
file_path: Path to the yaml file.
map_keys: Map of keys to change.
specific_key: Specific key to return.
Returns:
dict: Data from the yaml file.
Raises:
FileNotFoundError: If the file is not found.
"""
file_path = Path(file_path)
if not file_path.exists():
raise FileNotFoundError(f'File "{file_path}" not found.')

data = yaml.safe_load(open(file_path))

if map_keys:
Expand Down
27 changes: 17 additions & 10 deletions deployability/modules/provision/actions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from modules.generic import Ansible

from modules.provision.componentType import Package, AIO, Generic, Dependencies
from modules.provision.component_type import Package, AIO, Generic, Dependencies
from modules.provision.models import ComponentInfo
from modules.provision.utils import logger

Expand Down Expand Up @@ -47,22 +47,29 @@ def execute(self) -> dict:
"""
status = {}

logger.info(f"Executing {self.component.type} for {self.component.component}")
tasks = self.ansible.render_playbooks(self.component.variables_dict)
ansible_task = [{
'name': 'Capture ansible_os_family',
'set_fact': {
'ansible_os_family': "{{ ansible_facts['distribution_file_variety'] }}",
'cacheable': 'yes'
}
}]

playbook = {
'hosts': self.ansible.ansible_data.ansible_host,
'become': True,
'gather_facts': True,
'tasks': tasks
'tasks': ansible_task
}
status = self.ansible.run_playbook(playbook)

self.component.variables_dict['ansible_os_family'] = status.get_fact_cache(host=self.ansible.ansible_data.ansible_host)['ansible_os_family']

logger.info(f"Executing {self.component.type} for {self.component.component}")

tasks = self.ansible.render_playbooks(self.component.variables_dict)
playbook['tasks'] = tasks

status = self.ansible.run_playbook(playbook)

return status

def set_playbooks_variables(self, vars):
"""
Method to set the playbooks extra variables.
"""
pass
100 changes: 0 additions & 100 deletions deployability/modules/provision/componentType.py

This file was deleted.

146 changes: 146 additions & 0 deletions deployability/modules/provision/component_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Description: Class to define the type of component to be provisioned
from abc import ABC, abstractmethod

from modules.provision.models import ComponentInfo


class ComponentType(ABC):
"""
Class to define the type of component to be provisioned
Attributes:
component (str): The component to be provisioned.
type (str): The type of the component.
version (str): The version of the component.
manager_ip (str): The manager IP to be used in the provision.
templates_path (str): The path to the templates.
templates_order (list[str]): The order of the templates to be executed.
"""
templates_order: list[str]
templates_path: str

def __init__(self, component_info: ComponentInfo) -> None:
"""
Initialize the component type.
Args:
component_info (ComponentInfo): The component information.
"""
self.component = component_info.component
self.type = component_info.type
self.version = component_info.version
self.manager_ip = component_info.manager_ip or None

def get_templates_path(self, action: str):
"""
Get the path to the templates.
"""
pass

@abstractmethod
def get_templates_order(self, action: str) -> list:
"""
Get the order of the templates to be executed.
"""
pass

def generate_dict(self):
"""
Generate the dictionary with the variables to be used to render the templates.
"""
variables = {
'component': self.component,
'version': self.version,
'version': self.type,
'manager_ip': self.manager_ip,
'templates_path': self.templates_path,
'templates_order': self.templates_order or None
}

return variables


class Package(ComponentType):
"""
Class to define the type of package to be provisioned.
"""
__TEMPLATE_BASE_PATH = 'provision/wazuh'

def __init__(self, component_info: ComponentType, action: str) -> None:
"""
Initialize the package component type.
Args:
component_info (ComponentInfo): The component information.
action (str): The action to be executed.
"""
super().__init__(component_info)
self.templates_path = f'{self.__TEMPLATE_BASE_PATH}/{self.type}/{action}'
self.templates_order = self.get_templates_order(action)
self.variables_dict = self.generate_dict()

def get_templates_order(self, action: str) -> list[str]:
"""
Get the order of the templates to be executed.
Args:
action (str): The action to be executed.
"""
if action == "install":
return ["set_repo.j2", "install.j2", "register.j2", "service.j2"]
return []


class AIO(ComponentType):
"""
Class to define the type of AIO to be provisioned
"""
__TEMPLATE_BASE_PATH = 'provision/wazuh'

def __init__(self, component_info: ComponentType, action: str) -> None:
"""
Initialize the AIO component type.
Args:
component_info (ComponentInfo): The component information.
action (str): The action to be executed.
"""
super().__init__(component_info)
self.templates_path = f'{self.__TEMPLATE_BASE_PATH}/{self.type}/{action}'
self.templates_order = self.get_templates_order(action)
self.variables_dict = self.generate_dict()

def get_templates_order(self, action: str) -> list[str]:
return ["download.j2", f"{action}.j2"]


class Generic(ComponentType):
"""
Class to define the type of generic component to be provisioned
"""
__TEMPLATE_BASE_PATH = 'provision/generic'

def __init__(self, component_info: ComponentType, action: str) -> None:
super().__init__(component_info)
self.templates_path = f'{self.__TEMPLATE_BASE_PATH}/{action}'
self.templates_order = self.get_templates_order(action)
self.variables_dict = self.generate_dict()

def get_templates_order(self, action: str) -> list:
return []


class Dependencies(ComponentType):
"""
Class to define the type of dependencies to be provisioned
"""
__TEMPLATE_BASE_PATH = 'provision/deps'

def __init__(self, component_info: ComponentType, action: str) -> None:
super().__init__(component_info)
self.templates_path = f'{self.__TEMPLATE_BASE_PATH}'
self.templates_order = self.get_templates_order(action)
self.variables_dict = self.generate_dict()

def get_templates_order(self, action: str) -> list:
return []
27 changes: 13 additions & 14 deletions deployability/modules/provision/main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import argparse
import os
import sys
import ast
import json

# ---------------- Vars ------------------------

project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))
sys.path.append(project_root)
Expand All @@ -15,15 +11,18 @@


def parse_arguments():
parser = argparse.ArgumentParser(description="Provision infraestructure tool")
parser.add_argument("--inventory-agent", default=None, help="Inventory with agent host information")
parser.add_argument("--inventory-manager", default=None, help="Inventory with manager host information")
parser.add_argument('--install', action='append', default=[], help='List of dictionaries for installation.')
parser.add_argument('--uninstall', action='append', default=[], help='List of dictionaries for uninstall.')
return parser.parse_args()
parser = argparse.ArgumentParser(
description="Provision infraestructure tool")
parser.add_argument("--inventory-agent", default=None, help="Inventory with agent host information")
parser.add_argument("--inventory-manager", default=None, help="Inventory with manager host information")
parser.add_argument('--install', action='append', default=[], help='List of dictionaries for installation.')
parser.add_argument('--uninstall', action='append', default=[], help='List of dictionaries for uninstall.')
return parser.parse_args()

if __name__ == "__main__":
provision = Provision(models.InputPayload(**vars(parse_arguments())))
provision.run()

# ----------------------------------------------
if __name__ == "__main__":
try:
provision = Provision(models.InputPayload(**vars(parse_arguments())))
provision.run()
except Exception as e:
sys.exit(f"Error while provisioning: {e}")
Loading

0 comments on commit ca42f7a

Please sign in to comment.