Skip to content

Commit

Permalink
Merge pull request #4893 from wazuh/enhancement/4495-DTT1
Browse files Browse the repository at this point in the history
Merge 4495 into 4855
  • Loading branch information
fcaffieri authored Jan 31, 2024
2 parents b70eb2a + 2b174b3 commit 1ef37da
Show file tree
Hide file tree
Showing 29 changed files with 415 additions and 261 deletions.
2 changes: 1 addition & 1 deletion deployability/launchers/provision.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def parse_arguments():
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("--custom-credentials", required=False, default=None)
parser.add_argument('--uninstall', action='append', default=[], help='List of dictionaries for uninstall.')
return parser.parse_args()

if __name__ == "__main__":
Expand Down
4 changes: 1 addition & 3 deletions deployability/launchers/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,18 @@

from modules.testing import Tester, InputPayload


def parse_arguments():
parser = argparse.ArgumentParser(description="Wazuh testing tool")
parser.add_argument("--inventory", required=True)
parser.add_argument("--tests", required=True)
parser.add_argument("--component", choices=['manager', 'agent'], required=True)
parser.add_argument("--dependency", required=False)
parser.add_argument("--dependencies", required=False)
parser.add_argument("--cleanup", required=False, default=True)
parser.add_argument("--wazuh-version", required=True)
parser.add_argument("--wazuh-revision", required=True)
parser.add_argument("--wazuh-branch", required=False)
return parser.parse_args()


if __name__ == "__main__":
Tester.run(InputPayload(**vars(parse_arguments())))

Expand Down
3 changes: 1 addition & 2 deletions deployability/modules/generic/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
from .ansible import Ansible, Inventory
from .playbook import Playbook
from .schemaValidator import SchemaValidator
from .schemaValidator import SchemaValidator
22 changes: 9 additions & 13 deletions deployability/modules/generic/ansible.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

from jinja2 import Template
from modules.generic.utils import Utils
import subprocess, json

from modules.provision.componentType import ComponentType

class Inventory(BaseModel):
ansible_host: str | IPvAnyAddress
Expand All @@ -22,13 +21,9 @@ def __init__(self, ansible_data, path=None):
self.path = path
self.playbooks_path = Path(__file__).parents[2] / 'playbooks'
self.ansible_data = Inventory(**dict(ansible_data))
self.ansible_host = self.ansible_data.ansible_host
self.ansible_port = self.ansible_data.ansible_port
self.ansible_user = self.ansible_data.ansible_user
self.ansible_ssh_private_key_file = self.ansible_data.ansible_ssh_private_key_file
self.inventory = self.generate_inventory()

def render_playbooks(self, rendering_variables: dict) -> list:
def render_playbooks(self, rendering_variables) -> list:
"""
Render the playbooks with Jinja.
Expand All @@ -37,16 +32,17 @@ def render_playbooks(self, rendering_variables: dict) -> list:
rendering_variables: Extra variables to render the playbooks.
"""
tasks = []
path_to_render_playbooks = self.playbooks_path / rendering_variables['templates_path']
path_to_render_playbooks = self.playbooks_path / rendering_variables.get("templates_path")
template_loader = jinja2.FileSystemLoader(searchpath=path_to_render_playbooks)
template_env = jinja2.Environment(loader=template_loader)

list_template_tasks = Utils.get_template_list(
path_to_render_playbooks, rendering_variables.get('list_template_order'))
path_to_render_playbooks, rendering_variables.get("templates_order"))

if list_template_tasks:
for template in list_template_tasks:
loaded_template = template_env.get_template(template)

rendered = yaml.safe_load(loaded_template.render(host=self.ansible_data, **rendering_variables))

if not rendered:
Expand Down Expand Up @@ -110,10 +106,10 @@ def generate_inventory(self) -> dict:
inventory_data = {
'all': {
'hosts': {
self.ansible_host: {
'ansible_port': self.ansible_port,
'ansible_user': self.ansible_user,
'ansible_ssh_private_key_file': self.ansible_ssh_private_key_file
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
}
}
}
Expand Down
5 changes: 0 additions & 5 deletions deployability/modules/generic/playbook.py

This file was deleted.

3 changes: 3 additions & 0 deletions deployability/modules/generic/schemaValidator.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def preprocess_data(self):
raise jsonschema.exceptions.ValidationError(f"Missing required properties in 'with' for task: {task}")

def validateSchema(self):
"""
Validate the Workflow schema
"""
try:
jsonschema.validate(self.yamlData, self.schemaData)
except jsonschema.exceptions.ValidationError as e:
Expand Down
49 changes: 49 additions & 0 deletions deployability/modules/provision/actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from modules.generic import Ansible
from .componentType import Package, AIO, Generic, Dependencies

class Action:
"""
Class to define the action.
"""
def __init__(self, action, component_info, ansible_data):
action_type = component_info.type

if action_type == "package":
self.component = Package(component_info, action)
elif action_type == "aio":
self.component = AIO(component_info, action)
elif action_type == "generic":
self.component = Generic(component_info, action)
elif action_type == "dependencies":
self.component = Dependencies(component_info, action)
else:
raise ValueError(f"Unsupported action_type: {action_type}")

self.ansible = Ansible(ansible_data)

def execute(self):
"""
Execute the action.
"""
status = {}

print(self.component.variables_dict)

tasks = self.ansible.render_playbooks(self.component.variables_dict)

playbook = {
'hosts': self.ansible.ansible_data.ansible_host,
'become': True,
'gather_facts': True,
'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: 100 additions & 0 deletions deployability/modules/provision/componentType.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@


class ComponentType:
"""
Class to define the type of component to be provisioned
"""
def __init__(self, component_info):
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):
"""
Get the path to the templates.
"""
pass

def get_templates_order(self, action):
"""
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, action):
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):
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, action):
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):
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, action):
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):
return []

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

def __init__(self, component_info, action):
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):
return []
88 changes: 0 additions & 88 deletions deployability/modules/provision/install.py

This file was deleted.

Loading

0 comments on commit 1ef37da

Please sign in to comment.