From 2471e4dffc61260ad3cf9065d69d182d6ab12ed4 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Fri, 7 Jul 2017 09:33:29 -0400 Subject: [PATCH] Detailed tweaking of inventory and playbook listings * exclude anything inside group_vars or host_vars directories * include all ini or yml files in inventory listing --- awx/main/models/projects.py | 6 ++++-- awx/main/utils/ansible.py | 32 +++++++++++++++++--------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/awx/main/models/projects.py b/awx/main/models/projects.py index 4275661437..93be2132a9 100644 --- a/awx/main/models/projects.py +++ b/awx/main/models/projects.py @@ -25,7 +25,7 @@ from awx.main.models.notifications import ( from awx.main.models.unified_jobs import * # noqa from awx.main.models.mixins import ResourceMixin from awx.main.utils import update_scm_url -from awx.main.utils.ansible import could_be_inventory, could_be_playbook +from awx.main.utils.ansible import skip_directory, could_be_inventory, could_be_playbook from awx.main.fields import ImplicitRoleField from awx.main.models.rbac import ( ROLE_SINGLETON_SYSTEM_ADMINISTRATOR, @@ -180,6 +180,8 @@ class ProjectOptions(models.Model): project_path = self.get_project_path() if project_path: for dirpath, dirnames, filenames in os.walk(smart_str(project_path)): + if skip_directory(dirpath): + continue for filename in filenames: playbook = could_be_playbook(project_path, dirpath, filename) if playbook is not None: @@ -195,7 +197,7 @@ class ProjectOptions(models.Model): # Cap the number of results, because it could include lots max_inventory_listing = 50 for dirpath, dirnames, filenames in os.walk(smart_str(project_path)): - if dirpath.startswith('.'): + if skip_directory(dirpath): continue for filename in filenames: inv_path = could_be_inventory(project_path, dirpath, filename) diff --git a/awx/main/utils/ansible.py b/awx/main/utils/ansible.py index 561ac7b5c9..0ec542209b 100644 --- a/awx/main/utils/ansible.py +++ b/awx/main/utils/ansible.py @@ -10,15 +10,15 @@ from itertools import islice from django.utils.encoding import smart_str -__all__ = ['could_be_playbook', 'could_be_inventory'] +__all__ = ['skip_directory', 'could_be_playbook', 'could_be_inventory'] valid_playbook_re = re.compile(r'^\s*?-?\s*?(?:hosts|include):\s*?.*?$') valid_inventory_re = re.compile(r'^[a-zA-Z0-9_.=\[\]]') -def _skip_directory(rel_path): - path_elements = rel_path.split(os.sep) +def skip_directory(relative_directory_path): + path_elements = relative_directory_path.split(os.sep) # Exclude files in a roles subdirectory. if 'roles' in path_elements: return True @@ -29,6 +29,9 @@ def _skip_directory(rel_path): # Do not include dot files or dirs if element.startswith('.'): return True + # Exclude anything inside of group or host vars directories + if 'group_vars' in path_elements or 'host_vars' in path_elements: + return True return False @@ -52,18 +55,20 @@ def could_be_playbook(project_path, dir_path, filename): return None if not matched: return None - playbook = os.path.relpath(playbook_path, smart_str(project_path)) - if _skip_directory(playbook): - return None - return playbook + return os.path.relpath(playbook_path, smart_str(project_path)) def could_be_inventory(project_path, dir_path, filename): - suspected_ext = os.path.splitext(filename)[-1] - # Allow for files with no extension, or with extensions in a certain set - if '.' in suspected_ext and suspected_ext not in ['.yml', '.yaml', '.ini']: - return None + # Decisions based exclusively on filename inventory_path = os.path.join(dir_path, filename) + suspected_ext = os.path.splitext(filename)[-1] + if suspected_ext in ['.yml', '.yaml', '.ini']: + # Files with any of these extensions are always included + return os.path.relpath(inventory_path, smart_str(project_path)) + elif '.' in suspected_ext: + # If not using those extensions, inventory must have _no_ extension + return None + # Filter files that do not use a character set consistent with # Ansible inventory mainly try: @@ -74,7 +79,4 @@ def could_be_inventory(project_path, dir_path, filename): return None except IOError: return None - inventory = os.path.relpath(inventory_path, smart_str(project_path)) - if _skip_directory(inventory): - return None - return inventory + return os.path.relpath(inventory_path, smart_str(project_path))