mirror of https://github.com/ansible/ansible.git
ansible-inventory prevent duplicating host entries (#80059)
this happened after implementing limits we introduced a bug that a host would be duplicated if it existed in a group's childrenpull/80151/head
parent
1055803c3a
commit
ff3ee9c4bd
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- ansible-inventory will no longer duplicate host entries if they were part of a group's childrens tree.
|
@ -0,0 +1,35 @@
|
||||
ihavenogroup
|
||||
|
||||
[all]
|
||||
hostinall
|
||||
|
||||
[all:vars]
|
||||
ansible_connection=local
|
||||
|
||||
[test_group1]
|
||||
test1 myvar=something
|
||||
test2 myvar=something2
|
||||
test3
|
||||
|
||||
[test_group2]
|
||||
test1
|
||||
test4
|
||||
test5
|
||||
|
||||
[test_group3]
|
||||
test2 othervar=stuff
|
||||
test3
|
||||
test6
|
||||
|
||||
[parent_1:children]
|
||||
test_group1
|
||||
|
||||
[parent_2:children]
|
||||
test_group1
|
||||
|
||||
[parent_3:children]
|
||||
test_group2
|
||||
test_group3
|
||||
|
||||
[parent_3]
|
||||
test2
|
@ -0,0 +1,50 @@
|
||||
# (c) 2017, Matt Martz <matt@sivel.net>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
# Make coding more python3-ish
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import functools
|
||||
|
||||
from ansible.plugins.inventory.toml import HAS_TOML, toml_dumps
|
||||
try:
|
||||
from ansible.plugins.inventory.toml import toml
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.common._collections_compat import MutableMapping
|
||||
from ansible.module_utils.six import string_types
|
||||
|
||||
|
||||
def _check_toml(func):
|
||||
@functools.wraps(func)
|
||||
def inner(o):
|
||||
if not HAS_TOML:
|
||||
raise AnsibleFilterError('The %s filter plugin requires the python "toml" library' % func.__name__)
|
||||
return func(o)
|
||||
return inner
|
||||
|
||||
|
||||
@_check_toml
|
||||
def from_toml(o):
|
||||
if not isinstance(o, string_types):
|
||||
raise AnsibleFilterError('from_toml requires a string, got %s' % type(o))
|
||||
return toml.loads(to_text(o, errors='surrogate_or_strict'))
|
||||
|
||||
|
||||
@_check_toml
|
||||
def to_toml(o):
|
||||
if not isinstance(o, MutableMapping):
|
||||
raise AnsibleFilterError('to_toml requires a dict, got %s' % type(o))
|
||||
return to_text(toml_dumps(o), errors='surrogate_or_strict')
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
def filters(self):
|
||||
return {
|
||||
'to_toml': to_toml,
|
||||
'from_toml': from_toml
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
- block:
|
||||
- name: check baseline
|
||||
command: ansible-inventory -i '{{ role_path }}/files/valid_sample.yml' --list
|
||||
register: limited
|
||||
|
||||
- name: ensure non empty host list
|
||||
assert:
|
||||
that:
|
||||
- "'something' in inv['_meta']['hostvars']"
|
||||
|
||||
- name: check that limit removes host
|
||||
command: ansible-inventory -i '{{ role_path }}/files/valid_sample.yml' --limit '!something' --list
|
||||
register: limited
|
||||
|
||||
- name: ensure empty host list
|
||||
assert:
|
||||
that:
|
||||
- "'something' not in inv['_meta']['hostvars']"
|
||||
|
||||
- name: check dupes
|
||||
command: ansible-inventory -i '{{ role_path }}/files/complex.ini' --list
|
||||
register: limited
|
||||
|
||||
- name: ensure host only appears on directly assigned
|
||||
assert:
|
||||
that:
|
||||
- "'hosts' not in inv['parent_1']"
|
||||
- "'hosts' not in inv['parent_2']"
|
||||
- "'hosts' in inv['parent_3']"
|
||||
- "'test1' in inv['test_group1']['hosts']"
|
||||
vars:
|
||||
inv: '{{limited.stdout|from_json }}'
|
||||
delegate_to: localhost
|
@ -0,0 +1,43 @@
|
||||
- name: only test if have toml in python
|
||||
command: "{{ansible_playbook_python}} -c 'import toml'"
|
||||
ignore_errors: true
|
||||
delegate_to: localhost
|
||||
register: has_toml
|
||||
|
||||
- block:
|
||||
- name: check baseline
|
||||
command: ansible-inventory -i '{{ role_path }}/files/valid_sample.yml' --list --toml
|
||||
register: limited
|
||||
|
||||
- name: ensure non empty host list
|
||||
assert:
|
||||
that:
|
||||
- "'something' in inv['somegroup']['hosts']"
|
||||
|
||||
- name: check that limit removes host
|
||||
command: ansible-inventory -i '{{ role_path }}/files/valid_sample.yml' --limit '!something' --list --toml
|
||||
register: limited
|
||||
ignore_errors: true
|
||||
|
||||
- name: ensure empty host list
|
||||
assert:
|
||||
that:
|
||||
- limited is failed
|
||||
|
||||
- name: check dupes
|
||||
command: ansible-inventory -i '{{ role_path }}/files/complex.ini' --list --toml
|
||||
register: limited
|
||||
|
||||
- debug: var=inv
|
||||
|
||||
- name: ensure host only appears on directly assigned
|
||||
assert:
|
||||
that:
|
||||
- "'hosts' not in inv['parent_1']"
|
||||
- "'hosts' not in inv['parent_2']"
|
||||
- "'hosts' in inv['parent_3']"
|
||||
- "'test1' in inv['test_group1']['hosts']"
|
||||
vars:
|
||||
inv: '{{limited.stdout|from_toml}}'
|
||||
when: has_toml is success
|
||||
delegate_to: localhost
|
@ -0,0 +1,34 @@
|
||||
- block:
|
||||
- name: check baseline
|
||||
command: ansible-inventory -i '{{ role_path }}/files/valid_sample.yml' --list --yaml
|
||||
register: limited
|
||||
|
||||
- name: ensure something in host list
|
||||
assert:
|
||||
that:
|
||||
- "'something' in inv['all']['children']['somegroup']['hosts']"
|
||||
|
||||
- name: check that limit removes host
|
||||
command: ansible-inventory -i '{{ role_path }}/files/valid_sample.yml' --limit '!something' --list --yaml
|
||||
register: limited
|
||||
|
||||
- name: ensure empty host list
|
||||
assert:
|
||||
that:
|
||||
- not inv
|
||||
|
||||
- name: check dupes
|
||||
command: ansible-inventory -i '{{ role_path }}/files/complex.ini' --list --yaml
|
||||
register: limited
|
||||
|
||||
- name: ensure host only appears on directly assigned
|
||||
assert:
|
||||
that:
|
||||
- "'hosts' not in inv['all']['children']['parent_1']"
|
||||
- "'hosts' not in inv['all']['children']['parent_2']"
|
||||
- "'hosts' in inv['all']['children']['parent_3']"
|
||||
- "'test1' in inv['all']['children']['parent_1']['children']['test_group1']['hosts']"
|
||||
- "'hosts' not in inv['all']['children']['parent_2']['children']['test_group1']"
|
||||
vars:
|
||||
inv: '{{limited.stdout|from_yaml}}'
|
||||
delegate_to: localhost
|
Loading…
Reference in New Issue