diff --git a/Makefile b/Makefile index fd74f33b..f2614aeb 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ ROLES_DIR := ./roles APPLICATIONS_OUT := ./group_vars/all/04_applications.yml -APPLICATIONS_SCRIPT := ./cli/generate_applications.py +APPLICATIONS_SCRIPT := ./cli/generate/defaults/applications.py USERS_OUT := ./group_vars/all/03_users.yml -USERS_SCRIPT := ./cli/generate_users.py -INCLUDES_SCRIPT := ./cli/generate_playbook.py +USERS_SCRIPT := ./cli/generate/defaults/users.py +INCLUDES_SCRIPT := ./cli/generate/conditional_role_include.py # Define the prefixes for which we want individual role-include files INCLUDE_GROUPS := "drv-" "svc-" "desk-" "web-" "util-" diff --git a/cli/utils/__init__.py b/cli/create/__init__.py similarity index 100% rename from cli/utils/__init__.py rename to cli/create/__init__.py diff --git a/cli/create_credentials.py b/cli/create/credentials.py similarity index 97% rename from cli/create_credentials.py rename to cli/create/credentials.py index 6c9c619b..0782f64c 100644 --- a/cli/create_credentials.py +++ b/cli/create/credentials.py @@ -5,8 +5,8 @@ from pathlib import Path import yaml from typing import Dict, Any from utils.manager.inventory import InventoryManager -from utils.handler.vault import VaultHandler, VaultScalar -from utils.handler.yaml import YamlHandler +from utils.handler.vault import VaultHandler, VaultScalar +from utils.handler.yaml import YamlHandler from yaml.dumper import SafeDumper diff --git a/cli/create_web_app.py b/cli/create/role.py similarity index 100% rename from cli/create_web_app.py rename to cli/create/role.py diff --git a/cli/deploy.py b/cli/deploy.py index 3b60a1f4..ffdd7944 100644 --- a/cli/deploy.py +++ b/cli/deploy.py @@ -21,7 +21,7 @@ def run_ansible_playbook(inventory, modes, limit=None, allowed_applications=None print("\nšŸ” Validating inventory before deployment...\n") try: subprocess.run( - [sys.executable, os.path.join(script_dir, "validate_inventory.py"), os.path.dirname(inventory)], + [sys.executable, os.path.join(script_dir, "validate.inventory.py"), os.path.dirname(inventory)], check=True ) except subprocess.CalledProcessError: diff --git a/cli/utils/handler/__init__.py b/cli/encrypt/__init__.py similarity index 100% rename from cli/utils/handler/__init__.py rename to cli/encrypt/__init__.py diff --git a/cli/encrypt_inventory.py b/cli/encrypt/inventory.py similarity index 100% rename from cli/encrypt_inventory.py rename to cli/encrypt/inventory.py diff --git a/cli/fix/__init__.py b/cli/fix/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cli/fix/ini_py.py b/cli/fix/ini_py.py new file mode 100644 index 00000000..491ee0d0 --- /dev/null +++ b/cli/fix/ini_py.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 + +""" +This script creates __init__.py files in every subdirectory under the specified +folder relative to the project root. +""" + +import os +import argparse + + +def create_init_files(root_folder): + """ + Walk through all subdirectories of root_folder and create an __init__.py file + in each directory if it doesn't already exist. + """ + for dirpath, dirnames, filenames in os.walk(root_folder): + init_file = os.path.join(dirpath, '__init__.py') + if not os.path.exists(init_file): + open(init_file, 'w').close() + print(f"Created: {init_file}") + else: + print(f"Skipped (already exists): {init_file}") + + +def main(): + parser = argparse.ArgumentParser( + description='Create __init__.py files in every subdirectory.' + ) + parser.add_argument( + 'folder', + help='Relative path to the target folder (e.g., cli/fix)' + ) + args = parser.parse_args() + + # Determine the absolute path based on the current working directory + root_folder = os.path.abspath(args.folder) + + if not os.path.isdir(root_folder): + print(f"Error: The folder '{args.folder}' does not exist or is not a directory.") + exit(1) + + create_init_files(root_folder) + + +if __name__ == '__main__': + main() diff --git a/cli/fix-tabs.py b/cli/fix/tabs.py similarity index 100% rename from cli/fix-tabs.py rename to cli/fix/tabs.py diff --git a/cli/ensure_vars_main.py b/cli/fix/vars_main_files.py similarity index 100% rename from cli/ensure_vars_main.py rename to cli/fix/vars_main_files.py diff --git a/cli/generate/__init__.py b/cli/generate/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cli/generate_playbook.py b/cli/generate/conditional_role_include.py similarity index 98% rename from cli/generate_playbook.py rename to cli/generate/conditional_role_include.py index 1e9da5c8..7f28d3fd 100644 --- a/cli/generate_playbook.py +++ b/cli/generate/conditional_role_include.py @@ -156,7 +156,7 @@ def print_dependency_tree(graph): for root in roots: print_node(root) -def generate_playbook_entries(roles_dir, prefixes=None): +def gen_condi_role_incl(roles_dir, prefixes=None): """ Generate playbook entries based on the sorted order. Raises a ValueError if application_id is missing. @@ -209,7 +209,7 @@ def main(): print_dependency_tree(graph) sys.exit(0) - entries = generate_playbook_entries(args.roles_dir, prefixes) + entries = gen_condi_role_incl(args.roles_dir, prefixes) output = ''.join(entries) if args.output: diff --git a/cli/generate/defaults/__init__.py b/cli/generate/defaults/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cli/generate_applications.py b/cli/generate/defaults/applications.py similarity index 97% rename from cli/generate_applications.py rename to cli/generate/defaults/applications.py index 99ad80da..704a26e7 100644 --- a/cli/generate_applications.py +++ b/cli/generate/defaults/applications.py @@ -6,7 +6,7 @@ import yaml import sys from pathlib import Path -plugin_path = Path(__file__).resolve().parent / ".." / "lookup_plugins" +plugin_path = Path(__file__).resolve().parent / ".." / ".." / ".." /"lookup_plugins" sys.path.insert(0, str(plugin_path)) from application_gid import LookupModule diff --git a/cli/generate_users.py b/cli/generate/defaults/users.py similarity index 100% rename from cli/generate_users.py rename to cli/generate/defaults/users.py diff --git a/cli/meta/__init__.py b/cli/meta/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cli/invokable_paths.py b/cli/meta/invokable_paths.py similarity index 100% rename from cli/invokable_paths.py rename to cli/meta/invokable_paths.py diff --git a/cli/show_vault_variables_draft.py b/cli/show_vault_variables_draft.py deleted file mode 100644 index 6053fc8d..00000000 --- a/cli/show_vault_variables_draft.py +++ /dev/null @@ -1,105 +0,0 @@ -import argparse -import subprocess -from ansible.parsing.vault import VaultLib, VaultSecret -import sys -import yaml -import re -from utils.handler.vault import VaultScalar -from yaml.loader import SafeLoader -from yaml.dumper import SafeDumper - -# Register the custom constructor and representer for VaultScalar in PyYAML -SafeLoader.add_constructor('!vault', lambda loader, node: VaultScalar(node.value)) -SafeDumper.add_representer(VaultScalar, lambda dumper, data: dumper.represent_scalar('!vault', data)) - -def is_vault_encrypted_data(data: str) -> bool: - """Check if the given data is encrypted with Ansible Vault by looking for the vault header.""" - return data.lstrip().startswith('$ANSIBLE_VAULT') - -def decrypt_vault_data(encrypted_data: str, vault_secret: VaultSecret) -> str: - """ - Decrypt the given encrypted data using the provided vault_secret. - :param encrypted_data: Encrypted string to be decrypted - :param vault_secret: The VaultSecret instance used to decrypt the data - :return: Decrypted data as a string - """ - vault = VaultLib() - decrypted_data = vault.decrypt(encrypted_data, vault_secret) - return decrypted_data - -def decrypt_vault_file(vault_file: str, vault_password_file: str): - """ - Decrypt the Ansible Vault file and return its contents. - :param vault_file: Path to the encrypted Ansible Vault file - :param vault_password_file: Path to the file containing the Vault password - :return: Decrypted contents of the Vault file - """ - # Read the vault password - with open(vault_password_file, 'r') as f: - vault_password = f.read().strip() - - # Create a VaultSecret instance from the password - vault_secret = VaultSecret(vault_password.encode()) - - # Read the encrypted file - with open(vault_file, 'r') as f: - file_content = f.read() - - # If the file is partially encrypted, we'll decrypt only the encrypted values - decrypted_data = file_content # Start with the unmodified content - - # Find all vault-encrypted values (i.e., values starting with $ANSIBLE_VAULT) - encrypted_values = re.findall(r'^\s*([\w\.\-_]+):\s*["\']?\$ANSIBLE_VAULT[^\n]+', file_content, flags=re.MULTILINE) - - # If there are encrypted values, decrypt them - for value in encrypted_values: - # Extract the encrypted value and decrypt it - encrypted_value = re.search(r'(["\']?\$ANSIBLE_VAULT[^\n]+)', value) - if encrypted_value: - # Remove any newlines or extra spaces from the encrypted value - encrypted_value = encrypted_value.group(0).replace('\n', '').replace('\r', '') - decrypted_value = decrypt_vault_data(encrypted_value, vault_secret) - # Replace the encrypted value with the decrypted value in the content - decrypted_data = decrypted_data.replace(encrypted_value, decrypted_value.strip()) - - return decrypted_data - -def decrypt_and_display(vault_file: str, vault_password_file: str): - """ - Decrypts the Ansible Vault file and its values, then display the result. - Supports both full file and partial value encryption. - :param vault_file: Path to the encrypted Ansible Vault file - :param vault_password_file: Path to the file containing the Vault password - """ - decrypted_data = decrypt_vault_file(vault_file, vault_password_file) - - # Convert the decrypted data to a string format (YAML or JSON) - output_data = yaml.dump(yaml.safe_load(decrypted_data), default_flow_style=False) - - # Use subprocess to call `less` for paginated, scrollable output - subprocess.run(["less"], input=output_data, text=True) - -def main(): - # Set up the argument parser - parser = argparse.ArgumentParser(description="Decrypt and display variables from an Ansible Vault file.") - - # Add arguments for the vault file and vault password file - parser.add_argument( - 'vault_file', - type=str, - help="Path to the encrypted Ansible Vault file" - ) - parser.add_argument( - 'vault_password_file', - type=str, - help="Path to the file containing the Vault password" - ) - - # Parse the arguments - args = parser.parse_args() - - # Display vault variables in a scrollable manner - decrypt_and_display(args.vault_file, args.vault_password_file) - -if __name__ == "__main__": - main() diff --git a/cli/validate/__init__.py b/cli/validate/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cli/validate_inventory.py b/cli/validate/inventory.py similarity index 100% rename from cli/validate_inventory.py rename to cli/validate/inventory.py diff --git a/tests/integration/test_circular_dependencies.py b/tests/integration/test_circular_dependencies.py index 0a38b2e3..9612c750 100644 --- a/tests/integration/test_circular_dependencies.py +++ b/tests/integration/test_circular_dependencies.py @@ -2,7 +2,7 @@ import os import unittest # import the functions from your CLI script -from cli.generate_playbook import build_dependency_graph, find_cycle +from cli.generate.conditional_role_include import build_dependency_graph, find_cycle class TestCircularDependencies(unittest.TestCase): """ diff --git a/tests/unit/cli/create/__init__.py b/tests/unit/cli/create/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/cli/test_create_credentials.py b/tests/unit/cli/create/test_credentials.py similarity index 97% rename from tests/unit/cli/test_create_credentials.py rename to tests/unit/cli/create/test_credentials.py index 65bf0257..d2a32b7b 100644 --- a/tests/unit/cli/test_create_credentials.py +++ b/tests/unit/cli/create/test_credentials.py @@ -10,7 +10,7 @@ dir_path = os.path.abspath( sys.path.insert(0, dir_path) # Import functions and classes to test -from create_credentials import ask_for_confirmation, main +from cli.create.credentials import ask_for_confirmation, main from utils.handler.vault import VaultHandler, VaultScalar import subprocess import tempfile @@ -81,7 +81,7 @@ class TestCreateCredentials(unittest.TestCase): with mock.patch('subprocess.run', return_value=completed): # Run main with override for credentials.api_key and force to skip prompt sys.argv = [ - 'create_credentials.py', + 'create/credentials.py', '--role-path', role_path, '--inventory-file', inventory_file, '--vault-password-file', vault_pw_file, diff --git a/tests/unit/cli/test_create_web_app.py b/tests/unit/cli/create/test_role.py similarity index 99% rename from tests/unit/cli/test_create_web_app.py rename to tests/unit/cli/create/test_role.py index fb5fe8fe..0509ed89 100644 --- a/tests/unit/cli/test_create_web_app.py +++ b/tests/unit/cli/create/test_role.py @@ -6,7 +6,7 @@ import tempfile from ruamel.yaml import YAML # Import functions to test; adjust path as needed -from cli.create_web_app import ( +from cli.create.role import ( get_next_network, get_next_port, load_yaml_with_comments, diff --git a/tests/unit/cli/fix/__init__.py b/tests/unit/cli/fix/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/cli/test_ensure_vars_main.py b/tests/unit/cli/fix/test_vars_main_files.py similarity index 89% rename from tests/unit/cli/test_ensure_vars_main.py rename to tests/unit/cli/fix/test_vars_main_files.py index 49d813a2..e7d6f608 100644 --- a/tests/unit/cli/test_ensure_vars_main.py +++ b/tests/unit/cli/fix/test_vars_main_files.py @@ -1,4 +1,4 @@ -# tests/cli/test_ensure_vars_main.py +# tests/cli/test_fix/vars_main_files.py import os import shutil import tempfile @@ -6,7 +6,7 @@ import unittest import yaml # Adjust this import to match the real path in your project -from cli.ensure_vars_main import run, ROLES_DIR +from cli.ensure.vars_main_files import run, ROLES_DIR class TestEnsureVarsMain(unittest.TestCase): def setUp(self): @@ -17,11 +17,11 @@ class TestEnsureVarsMain(unittest.TestCase): # Monkey-patch the module's ROLES_DIR to point here self._orig_roles_dir = ROLES_DIR - setattr(__import__("cli.ensure_vars_main", fromlist=["ROLES_DIR"]), "ROLES_DIR", self.roles_dir) + setattr(__import__("cli.ensure.vars_main_files", fromlist=["ROLES_DIR"]), "ROLES_DIR", self.roles_dir) def tearDown(self): # restore and cleanup - setattr(__import__("cli.ensure_vars_main", fromlist=["ROLES_DIR"]), "ROLES_DIR", self._orig_roles_dir) + setattr(__import__("cli.ensure.vars_main_files", fromlist=["ROLES_DIR"]), "ROLES_DIR", self._orig_roles_dir) shutil.rmtree(self.tmpdir) def _make_role(self, name, vars_content=None): diff --git a/tests/unit/cli/generate/__init__.py b/tests/unit/cli/generate/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/cli/generate/conditional_role_include/__init__.py b/tests/unit/cli/generate/conditional_role_include/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/cli/test_generate_playbook.py b/tests/unit/cli/generate/conditional_role_include/test_conditional_role_include.py similarity index 92% rename from tests/unit/cli/test_generate_playbook.py rename to tests/unit/cli/generate/conditional_role_include/test_conditional_role_include.py index 8f4bfb2f..c45ad505 100644 --- a/tests/unit/cli/test_generate_playbook.py +++ b/tests/unit/cli/generate/conditional_role_include/test_conditional_role_include.py @@ -7,9 +7,9 @@ import shutil import yaml # Adjust path to include cli/ folder -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../..", "cli"))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../..", "cli"))) -from generate_playbook import build_dependency_graph, topological_sort, generate_playbook_entries +from cli.generate.conditional_role_include import build_dependency_graph, topological_sort, gen_condi_role_incl class TestGeneratePlaybook(unittest.TestCase): def setUp(self): @@ -66,8 +66,8 @@ class TestGeneratePlaybook(unittest.TestCase): # The expected order must be a → b → c, d can be anywhere before or after self.assertTrue(sorted_roles.index('role-a') < sorted_roles.index('role-b') < sorted_roles.index('role-c')) - def test_generate_playbook_entries(self): - entries = generate_playbook_entries(self.temp_dir) + def test_gen_condi_role_incl(self): + entries = gen_condi_role_incl(self.temp_dir) text = ''.join(entries) self.assertIn("setup a", text) diff --git a/tests/unit/cli/generate/defaults/__init__.py b/tests/unit/cli/generate/defaults/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/cli/test_generate_default_applications.py b/tests/unit/cli/generate/defaults/test_applications.py similarity index 96% rename from tests/unit/cli/test_generate_default_applications.py rename to tests/unit/cli/generate/defaults/test_applications.py index 17ba931e..73c01e78 100644 --- a/tests/unit/cli/test_generate_default_applications.py +++ b/tests/unit/cli/generate/defaults/test_applications.py @@ -30,7 +30,7 @@ class TestGenerateDefaultApplications(unittest.TestCase): shutil.rmtree(self.temp_dir) def test_script_generates_expected_yaml(self): - script_path = Path(__file__).resolve().parent.parent.parent.parent / "cli" / "generate_applications.py" + script_path = Path(__file__).resolve().parent.parent.parent.parent.parent.parent / "cli/generate/defaults/applications.py" result = subprocess.run( [ diff --git a/tests/unit/cli/test_generate_applications_defaults_users.py b/tests/unit/cli/generate/defaults/test_applications_and_users.py similarity index 95% rename from tests/unit/cli/test_generate_applications_defaults_users.py rename to tests/unit/cli/generate/defaults/test_applications_and_users.py index 461c3333..e59f96fb 100644 --- a/tests/unit/cli/test_generate_applications_defaults_users.py +++ b/tests/unit/cli/generate/defaults/test_applications_and_users.py @@ -45,7 +45,7 @@ class TestGenerateDefaultApplicationsUsers(unittest.TestCase): When a users.yml exists with defined users, the script should inject a 'users' mapping in the generated YAML, mapping each username to a Jinja2 reference. """ - script_path = Path(__file__).resolve().parents[3] / "cli" / "generate_applications.py" + script_path = Path(__file__).resolve().parents[5] / "cli" / "generate/defaults/applications.py" result = subprocess.run([ "python3", str(script_path), "--roles-dir", str(self.roles_dir), diff --git a/tests/unit/cli/test_generate_users.py b/tests/unit/cli/generate/defaults/test_users.py similarity index 74% rename from tests/unit/cli/test_generate_users.py rename to tests/unit/cli/generate/defaults/test_users.py index 01e801ec..58aaaf4a 100644 --- a/tests/unit/cli/test_generate_users.py +++ b/tests/unit/cli/generate/defaults/test_users.py @@ -7,9 +7,9 @@ import yaml from collections import OrderedDict # Add cli/ to import path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../..", "cli"))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../..", "cli/generate/defaults/"))) -import generate_users +import users class TestGenerateUsers(unittest.TestCase): def test_build_users_auto_increment_and_overrides(self): @@ -18,24 +18,24 @@ class TestGenerateUsers(unittest.TestCase): 'bob': {'uid': 2000, 'email': 'bob@custom.com', 'description': 'Custom user'}, 'carol': {} } - users = generate_users.build_users( + build = users.build_users( defs=defs, primary_domain='example.com', start_id=1001, become_pwd='pw' ) # alice should get uid/gid 1001 - self.assertEqual(users['alice']['uid'], 1001) - self.assertEqual(users['alice']['gid'], 1001) - self.assertEqual(users['alice']['email'], 'alice@example.com') + self.assertEqual(build['alice']['uid'], 1001) + self.assertEqual(build['alice']['gid'], 1001) + self.assertEqual(build['alice']['email'], 'alice@example.com') # bob overrides - self.assertEqual(users['bob']['uid'], 2000) - self.assertEqual(users['bob']['gid'], 2000) - self.assertEqual(users['bob']['email'], 'bob@custom.com') - self.assertIn('description', users['bob']) + self.assertEqual(build['bob']['uid'], 2000) + self.assertEqual(build['bob']['gid'], 2000) + self.assertEqual(build['bob']['email'], 'bob@custom.com') + self.assertIn('description', build['bob']) # carol should get next free id = 1002 - self.assertEqual(users['carol']['uid'], 1002) - self.assertEqual(users['carol']['gid'], 1002) + self.assertEqual(build['carol']['uid'], 1002) + self.assertEqual(build['carol']['gid'], 1002) def test_build_users_default_lookup_password(self): """ @@ -44,14 +44,14 @@ class TestGenerateUsers(unittest.TestCase): """ defs = {'frank': {}} lookup_template = '{{ lookup("password", "/dev/null length=42 chars=ascii_letters,digits") }}' - users = generate_users.build_users( + build = users.build_users( defs=defs, primary_domain='example.com', start_id=1001, become_pwd=lookup_template ) self.assertEqual( - users['frank']['password'], + build['frank']['password'], lookup_template, "The lookup template string was not correctly applied as the default password" ) @@ -63,14 +63,14 @@ class TestGenerateUsers(unittest.TestCase): """ defs = {'eva': {'password': 'custompw'}} lookup_template = '{{ lookup("password", "/dev/null length=42 chars=ascii_letters,digits") }}' - users = generate_users.build_users( + build = users.build_users( defs=defs, primary_domain='example.com', start_id=1001, become_pwd=lookup_template ) self.assertEqual( - users['eva']['password'], + build['eva']['password'], 'custompw', "The override password was not correctly applied" ) @@ -82,7 +82,7 @@ class TestGenerateUsers(unittest.TestCase): 'u2': {'uid': 1001} } with self.assertRaises(ValueError): - generate_users.build_users(defs, 'ex.com', 1001, 'pw') + users.build_users(defs, 'ex.com', 1001, 'pw') def test_build_users_shared_gid_allowed(self): # Allow two users to share the same GID when one overrides gid and the other uses that as uid @@ -90,10 +90,10 @@ class TestGenerateUsers(unittest.TestCase): 'a': {'uid': 1500}, 'b': {'gid': 1500} } - users = generate_users.build_users(defs, 'ex.com', 1500, 'pw') + build = users.build_users(defs, 'ex.com', 1500, 'pw') # Both should have gid 1500 - self.assertEqual(users['a']['gid'], 1500) - self.assertEqual(users['b']['gid'], 1500) + self.assertEqual(build['a']['gid'], 1500) + self.assertEqual(build['b']['gid'], 1500) def test_build_users_duplicate_username_email(self): defs = { @@ -102,11 +102,11 @@ class TestGenerateUsers(unittest.TestCase): } # second user with same username should raise with self.assertRaises(ValueError): - generate_users.build_users(defs, 'ex.com', 1001, 'pw') + users.build_users(defs, 'ex.com', 1001, 'pw') def test_dictify_converts_ordereddict(self): - od = generate_users.OrderedDict([('a', 1), ('b', {'c': 2})]) - result = generate_users.dictify(OrderedDict(od)) + od = users.OrderedDict([('a', 1), ('b', {'c': 2})]) + result = users.dictify(OrderedDict(od)) self.assertIsInstance(result, dict) self.assertEqual(result, {'a': 1, 'b': {'c': 2}}) @@ -122,13 +122,13 @@ class TestGenerateUsers(unittest.TestCase): # role2 defines same user x with same value with open(os.path.join(tmp, 'role2/users/main.yml'), 'w') as f: yaml.safe_dump({'users': {'x': {'email': 'x@a'}}}, f) - defs = generate_users.load_user_defs(tmp) + defs = users.load_user_defs(tmp) self.assertIn('x', defs) # now conflict definition with open(os.path.join(tmp, 'role2/users/main.yml'), 'w') as f: yaml.safe_dump({'users': {'x': {'email': 'x@b'}}}, f) with self.assertRaises(ValueError): - generate_users.load_user_defs(tmp) + users.load_user_defs(tmp) finally: shutil.rmtree(tmp) diff --git a/tests/unit/cli/test_inventory_manager.py b/tests/unit/cli/test_inventory_manager.py index 1cff1e8a..87d36ad1 100644 --- a/tests/unit/cli/test_inventory_manager.py +++ b/tests/unit/cli/test_inventory_manager.py @@ -16,7 +16,7 @@ sys.path.insert( from utils.handler.yaml import YamlHandler from utils.handler.vault import VaultHandler, VaultScalar -from cli.utils.manager.inventory import InventoryManager +from utils.manager.inventory import InventoryManager class TestInventoryManager(unittest.TestCase): diff --git a/tests/unit/cli/validate/__init__.py b/tests/unit/cli/validate/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/cli/test_validate_inventory.py b/tests/unit/cli/validate/test_inventory.py similarity index 98% rename from tests/unit/cli/test_validate_inventory.py rename to tests/unit/cli/validate/test_inventory.py index 192370fa..1d91b1ce 100644 --- a/tests/unit/cli/test_validate_inventory.py +++ b/tests/unit/cli/validate/test_inventory.py @@ -7,7 +7,7 @@ import subprocess import sys import yaml -SCRIPT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../cli/validate_inventory.py")) +SCRIPT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../../cli/validate/inventory.py")) class TestValidateInventory(unittest.TestCase): def setUp(self): diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/utils/handler/__init__.py b/utils/handler/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cli/utils/handler/vault.py b/utils/handler/vault.py similarity index 100% rename from cli/utils/handler/vault.py rename to utils/handler/vault.py diff --git a/cli/utils/handler/yaml.py b/utils/handler/yaml.py similarity index 100% rename from cli/utils/handler/yaml.py rename to utils/handler/yaml.py diff --git a/utils/manager/__init__.py b/utils/manager/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/cli/utils/manager/inventory.py b/utils/manager/inventory.py similarity index 100% rename from cli/utils/manager/inventory.py rename to utils/manager/inventory.py diff --git a/tests/unit/test_main.py b/utils/test_main.py similarity index 100% rename from tests/unit/test_main.py rename to utils/test_main.py