allow implicit host to be grouped (#26614)
* allow implicit host to be grouped also optimized patternmatching fixes #24156 * resolved a great crime
This commit is contained in:
parent
d173217833
commit
661b2c5beb
1 changed files with 21 additions and 37 deletions
|
@ -290,27 +290,20 @@ class InventoryManager(object):
|
||||||
self._inventory = InventoryData()
|
self._inventory = InventoryData()
|
||||||
self.parse_sources(cache=False)
|
self.parse_sources(cache=False)
|
||||||
|
|
||||||
def _match(self, string, pattern_str):
|
def _match_list(self, items, pattern_str):
|
||||||
try:
|
# compile patterns
|
||||||
if pattern_str.startswith('~'):
|
|
||||||
return re.search(pattern_str[1:], string)
|
|
||||||
else:
|
|
||||||
return fnmatch.fnmatch(string, pattern_str)
|
|
||||||
except Exception as e:
|
|
||||||
raise AnsibleError('invalid host pattern (%s): %s' % (pattern_str, str(e)))
|
|
||||||
|
|
||||||
def _match_list(self, items, item_attr, pattern_str):
|
|
||||||
results = []
|
|
||||||
try:
|
try:
|
||||||
if not pattern_str.startswith('~'):
|
if not pattern_str.startswith('~'):
|
||||||
pattern = re.compile(fnmatch.translate(pattern_str))
|
pattern = re.compile(fnmatch.translate(pattern_str))
|
||||||
else:
|
else:
|
||||||
pattern = re.compile(pattern_str[1:])
|
pattern = re.compile(pattern_str[1:])
|
||||||
except Exception:
|
except Exception:
|
||||||
raise AnsibleError('invalid host list pattern: %s' % pattern_str)
|
raise AnsibleError('Invalid host list pattern: %s' % pattern_str)
|
||||||
|
|
||||||
|
# apply patterns
|
||||||
|
results = []
|
||||||
for item in items:
|
for item in items:
|
||||||
if pattern.match(getattr(item, item_attr)):
|
if pattern.match(item):
|
||||||
results.append(item)
|
results.append(item)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
@ -383,12 +376,11 @@ class InventoryManager(object):
|
||||||
else:
|
else:
|
||||||
that = self._match_one_pattern(p)
|
that = self._match_one_pattern(p)
|
||||||
if p.startswith("!"):
|
if p.startswith("!"):
|
||||||
hosts = [h for h in hosts if h not in that]
|
hosts = [h for h in hosts if h not in frozenset(that)]
|
||||||
elif p.startswith("&"):
|
elif p.startswith("&"):
|
||||||
hosts = [h for h in hosts if h in that]
|
hosts = [h for h in hosts if h in frozenset(that)]
|
||||||
else:
|
else:
|
||||||
to_append = [h for h in that if h.name not in [y.name for y in hosts]]
|
hosts.extend([h for h in that if h.name not in frozenset([y.name for y in hosts])])
|
||||||
hosts.extend(to_append)
|
|
||||||
return hosts
|
return hosts
|
||||||
|
|
||||||
def _match_one_pattern(self, pattern):
|
def _match_one_pattern(self, pattern):
|
||||||
|
@ -513,33 +505,25 @@ class InventoryManager(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
|
# check if pattern matches group
|
||||||
def __append_host_to_results(host):
|
matching_groups = self._match_list(self._inventory.groups, pattern)
|
||||||
if host.name not in results:
|
if matching_groups:
|
||||||
if not host.implicit:
|
for groupname in matching_groups:
|
||||||
results.append(host)
|
results.extend(self._inventory.groups[groupname].get_hosts())
|
||||||
|
else:
|
||||||
matched = False
|
# pattern might match host
|
||||||
for group in self._inventory.groups.values():
|
matching_hosts = self._match_list(self._inventory.hosts, pattern)
|
||||||
if self._match(to_text(group.name), pattern):
|
if matching_hosts:
|
||||||
matched = True
|
for hostname in matching_hosts:
|
||||||
for host in group.get_hosts():
|
results.append(self._inventory.hosts[hostname])
|
||||||
__append_host_to_results(host)
|
|
||||||
else:
|
|
||||||
matching_hosts = self._match_list(group.get_hosts(), 'name', pattern)
|
|
||||||
if matching_hosts:
|
|
||||||
matched = True
|
|
||||||
for host in matching_hosts:
|
|
||||||
__append_host_to_results(host)
|
|
||||||
|
|
||||||
if not results and pattern in C.LOCALHOST:
|
if not results and pattern in C.LOCALHOST:
|
||||||
# get_host autocreates implicit when needed
|
# get_host autocreates implicit when needed
|
||||||
implicit = self._inventory.get_host(pattern)
|
implicit = self._inventory.get_host(pattern)
|
||||||
if implicit:
|
if implicit:
|
||||||
results.append(implicit)
|
results.append(implicit)
|
||||||
matched = True
|
|
||||||
|
|
||||||
if not matched:
|
if not results:
|
||||||
display.warning("Could not match supplied host pattern, ignoring: %s" % pattern)
|
display.warning("Could not match supplied host pattern, ignoring: %s" % pattern)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue