Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use InventoryManager for inventory_hostnames lookup #71573

Merged
merged 5 commits into from Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions 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)
5 changes: 3 additions & 2 deletions lib/ansible/inventory/manager.py
Expand Up @@ -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
Expand All @@ -163,7 +163,8 @@ def __init__(self, loader, sources=None):
self._sources = sources

# get to work!
self.parse_sources(cache=True)
if parse:
self.parse_sources(cache=True)

@property
def localhost(self):
Expand Down
45 changes: 12 additions & 33 deletions lib/ansible/plugins/lookup/inventory_hostnames.py
Expand Up @@ -34,41 +34,20 @@
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 []
2 changes: 2 additions & 0 deletions test/integration/targets/lookup_inventory_hostnames/main.yml
Expand Up @@ -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:
Expand All @@ -19,3 +20,4 @@
- nogroup == ['nogroup01']
- doesnotexist == []
- all|length == 12
- from_patterns == ['test03']