diff options
Diffstat (limited to 'lib/ansible/plugins/vars/host_group_vars.py')
-rw-r--r-- | lib/ansible/plugins/vars/host_group_vars.py | 95 |
1 files changed, 29 insertions, 66 deletions
diff --git a/lib/ansible/plugins/vars/host_group_vars.py b/lib/ansible/plugins/vars/host_group_vars.py index 28b42131..521b3b6e 100644 --- a/lib/ansible/plugins/vars/host_group_vars.py +++ b/lib/ansible/plugins/vars/host_group_vars.py @@ -54,30 +54,20 @@ DOCUMENTATION = ''' ''' import os +from ansible import constants as C from ansible.errors import AnsibleParserError -from ansible.module_utils.common.text.converters import to_native +from ansible.module_utils._text import to_bytes, to_native, to_text from ansible.plugins.vars import BaseVarsPlugin -from ansible.utils.path import basedir -from ansible.inventory.group import InventoryObjectType +from ansible.inventory.host import Host +from ansible.inventory.group import Group from ansible.utils.vars import combine_vars -CANONICAL_PATHS = {} # type: dict[str, str] FOUND = {} # type: dict[str, list[str]] -NAK = set() # type: set[str] -PATH_CACHE = {} # type: dict[tuple[str, str], str] class VarsModule(BaseVarsPlugin): REQUIRES_ENABLED = True - is_stateless = True - - def load_found_files(self, loader, data, found_files): - for found in found_files: - new_data = loader.load_from_file(found, cache=True, unsafe=True) - if new_data: # ignore empty files - data = combine_vars(data, new_data) - return data def get_vars(self, loader, path, entities, cache=True): ''' parses the inventory file ''' @@ -85,68 +75,41 @@ class VarsModule(BaseVarsPlugin): if not isinstance(entities, list): entities = [entities] - # realpath is expensive - try: - realpath_basedir = CANONICAL_PATHS[path] - except KeyError: - CANONICAL_PATHS[path] = realpath_basedir = os.path.realpath(basedir(path)) + super(VarsModule, self).get_vars(loader, path, entities) data = {} for entity in entities: - try: - entity_name = entity.name - except AttributeError: - raise AnsibleParserError("Supplied entity must be Host or Group, got %s instead" % (type(entity))) - - try: - first_char = entity_name[0] - except (TypeError, IndexError, KeyError): + if isinstance(entity, Host): + subdir = 'host_vars' + elif isinstance(entity, Group): + subdir = 'group_vars' + else: raise AnsibleParserError("Supplied entity must be Host or Group, got %s instead" % (type(entity))) # avoid 'chroot' type inventory hostnames /path/to/chroot - if first_char != os.path.sep: + if not entity.name.startswith(os.path.sep): try: found_files = [] # load vars - try: - entity_type = entity.base_type - except AttributeError: - raise AnsibleParserError("Supplied entity must be Host or Group, got %s instead" % (type(entity))) - - if entity_type is InventoryObjectType.HOST: - subdir = 'host_vars' - elif entity_type is InventoryObjectType.GROUP: - subdir = 'group_vars' + b_opath = os.path.realpath(to_bytes(os.path.join(self._basedir, subdir))) + opath = to_text(b_opath) + key = '%s.%s' % (entity.name, opath) + if cache and key in FOUND: + found_files = FOUND[key] else: - raise AnsibleParserError("Supplied entity must be Host or Group, got %s instead" % (type(entity))) - - if cache: - try: - opath = PATH_CACHE[(realpath_basedir, subdir)] - except KeyError: - opath = PATH_CACHE[(realpath_basedir, subdir)] = os.path.join(realpath_basedir, subdir) - - if opath in NAK: - continue - key = '%s.%s' % (entity_name, opath) - if key in FOUND: - data = self.load_found_files(loader, data, FOUND[key]) - continue - else: - opath = PATH_CACHE[(realpath_basedir, subdir)] = os.path.join(realpath_basedir, subdir) - - if os.path.isdir(opath): - self._display.debug("\tprocessing dir %s" % opath) - FOUND[key] = found_files = loader.find_vars_files(opath, entity_name) - elif not os.path.exists(opath): - # cache missing dirs so we don't have to keep looking for things beneath the - NAK.add(opath) - else: - self._display.warning("Found %s that is not a directory, skipping: %s" % (subdir, opath)) - # cache non-directory matches - NAK.add(opath) - - data = self.load_found_files(loader, data, found_files) + # no need to do much if path does not exist for basedir + if os.path.exists(b_opath): + if os.path.isdir(b_opath): + self._display.debug("\tprocessing dir %s" % opath) + found_files = loader.find_vars_files(opath, entity.name) + FOUND[key] = found_files + else: + self._display.warning("Found %s that is not a directory, skipping: %s" % (subdir, opath)) + + for found in found_files: + new_data = loader.load_from_file(found, cache=True, unsafe=True) + if new_data: # ignore empty files + data = combine_vars(data, new_data) except Exception as e: raise AnsibleParserError(to_native(e)) |