From db98433e7a99731dbbbbc571b1a03bd7ff9f827c Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Wed, 2 Sep 2020 15:42:09 -0500 Subject: [PATCH] Use InventoryManager for inventory_hostnames lookup (#71573) * Use InventoryManager for inventory_hostnames lookup. Fixes #17268 * Add test for using patterns * s/it's/its/ * Allow bypassing parse_sources in InventoryManager * Remove unneeded method call --- .../fragments/17268-inventory-hostnames.yml | 3 ++ lib/ansible/inventory/manager.py | 5 ++- .../plugins/lookup/inventory_hostnames.py | 45 +++++-------------- .../lookup_inventory_hostnames/main.yml | 2 + 4 files changed, 20 insertions(+), 35 deletions(-) create mode 100644 changelogs/fragments/17268-inventory-hostnames.yml diff --git a/changelogs/fragments/17268-inventory-hostnames.yml b/changelogs/fragments/17268-inventory-hostnames.yml new file mode 100644 index 00000000000..c0b104d9bbd --- /dev/null +++ b/changelogs/fragments/17268-inventory-hostnames.yml @@ -0,0 +1,3 @@ +bugfixes: +- inventory_hostnames - Use ``InventoryManager`` instead of trying to replicate its behavior + (https://github.com/ansible/ansible/issues/17268) diff --git a/lib/ansible/inventory/manager.py b/lib/ansible/inventory/manager.py index 5606b2655ee..cfc38180848 100644 --- a/lib/ansible/inventory/manager.py +++ b/lib/ansible/inventory/manager.py @@ -140,7 +140,7 @@ def split_host_pattern(pattern): class InventoryManager(object): ''' Creates and manages inventory ''' - def __init__(self, loader, sources=None): + def __init__(self, loader, sources=None, parse=True): # base objects self._loader = loader @@ -163,7 +163,8 @@ class InventoryManager(object): self._sources = sources # get to work! - self.parse_sources(cache=True) + if parse: + self.parse_sources(cache=True) @property def localhost(self): diff --git a/lib/ansible/plugins/lookup/inventory_hostnames.py b/lib/ansible/plugins/lookup/inventory_hostnames.py index 001abdbab39..0d10dc5a439 100644 --- a/lib/ansible/plugins/lookup/inventory_hostnames.py +++ b/lib/ansible/plugins/lookup/inventory_hostnames.py @@ -34,41 +34,20 @@ RETURN = """ type: list """ -from ansible.inventory.manager import split_host_pattern, order_patterns +from ansible.errors import AnsibleError +from ansible.inventory.manager import InventoryManager from ansible.plugins.lookup import LookupBase -from ansible.utils.helpers import deduplicate_list class LookupModule(LookupBase): - - def get_hosts(self, variables, pattern): - hosts = [] - if pattern[0] in ('!', '&'): - obj = pattern[1:] - else: - obj = pattern - - if obj in variables['groups']: - hosts = variables['groups'][obj] - elif obj in variables['groups']['all']: - hosts = [obj] - return hosts - def run(self, terms, variables=None, **kwargs): - - host_list = [] - - for term in terms: - patterns = order_patterns(split_host_pattern(term)) - - for p in patterns: - that = self.get_hosts(variables, p) - if p.startswith("!"): - host_list = [h for h in host_list if h not in that] - elif p.startswith("&"): - host_list = [h for h in host_list if h in that] - else: - host_list.extend(that) - - # return unique list - return deduplicate_list(host_list) + manager = InventoryManager(self._loader, parse=False) + for group, hosts in variables['groups'].items(): + manager.add_group(group) + for host in hosts: + manager.add_host(host, group=group) + + try: + return [h.name for h in manager.get_hosts(pattern=terms)] + except AnsibleError: + return [] diff --git a/test/integration/targets/lookup_inventory_hostnames/main.yml b/test/integration/targets/lookup_inventory_hostnames/main.yml index 820d37d25b0..4b822e348a0 100644 --- a/test/integration/targets/lookup_inventory_hostnames/main.yml +++ b/test/integration/targets/lookup_inventory_hostnames/main.yml @@ -10,6 +10,7 @@ nogroup: "{{ lookup('inventory_hostnames', 'nogroup01', wantlist=true) }}" doesnotexist: "{{ lookup('inventory_hostnames', 'doesnotexist', wantlist=true) }}" all: "{{ lookup('inventory_hostnames', 'all', wantlist=true) }}" + from_patterns: "{{ lookup('inventory_hostnames', 't?s?03', wantlist=True) }}" - assert: that: @@ -19,3 +20,4 @@ - nogroup == ['nogroup01'] - doesnotexist == [] - all|length == 12 + - from_patterns == ['test03']