preserve same order as inventory manager when using host lookup (#55331)

* preserve same order as inventory manager when using inventory_hostnames lookup

add a test

* move generic code
pull/55535/head
Sloane Hertel 5 years ago committed by Brian Coca
parent 0330ea616e
commit afb5e02c19

@ -36,6 +36,7 @@ from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_bytes, to_text
from ansible.parsing.utils.addresses import parse_address
from ansible.plugins.loader import inventory_loader
from ansible.utils.helpers import deduplicate_list
from ansible.utils.path import unfrackpath
from ansible.utils.display import Display
@ -369,8 +370,7 @@ class InventoryManager(object):
# exclude hosts mentioned in any restriction (ex: failed hosts)
hosts = [h for h in hosts if h.name in self._restriction]
seen = set()
self._hosts_patterns_cache[pattern_hash] = [x for x in hosts if x not in seen and not seen.add(x)]
self._hosts_patterns_cache[pattern_hash] = deduplicate_list(hosts)
# sort hosts list if needed (should only happen when called from strategy)
if order in ['sorted', 'reverse_sorted']:

@ -36,6 +36,7 @@ RETURN = """
from ansible.inventory.manager import split_host_pattern, order_patterns
from ansible.plugins.lookup import LookupBase
from ansible.utils.helpers import deduplicate_list
class LookupModule(LookupBase):
@ -70,4 +71,4 @@ class LookupModule(LookupBase):
host_list.extend(that)
# return unique list
return list(set(host_list))
return deduplicate_list(host_list)

@ -41,3 +41,11 @@ def object_to_dict(obj, exclude=None):
if exclude is None or not isinstance(exclude, list):
exclude = []
return dict((key, getattr(obj, key)) for key in dir(obj) if not (key.startswith('_') or key in exclude))
def deduplicate_list(original_list):
"""
Creates a deduplicated list with the order in which each item is first found.
"""
seen = set()
return [x for x in original_list if x not in seen and not seen.add(x)]

@ -0,0 +1,6 @@
[group01]
test01
test05
test03
test02
test04

@ -0,0 +1,13 @@
---
- hosts: localhost
gather_facts: no
tasks:
- set_fact:
hosts_a: "{{ lookup('inventory_hostnames', 'group01', wantlist=true) }}"
- set_fact:
hosts_b: "{{ groups['group01'] }}"
- assert:
that:
- hosts_a == hosts_b

@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -eux
ansible-playbook main.yml -i inventory -e "$@"
Loading…
Cancel
Save