|
|
@ -28,7 +28,7 @@ from ansible import constants as C
|
|
|
|
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
|
|
|
|
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
|
|
|
|
from ansible.inventory.data import InventoryData
|
|
|
|
from ansible.inventory.data import InventoryData
|
|
|
|
from ansible.module_utils.six import string_types
|
|
|
|
from ansible.module_utils.six import string_types
|
|
|
|
from ansible.module_utils._text import to_bytes, to_native, to_text
|
|
|
|
from ansible.module_utils._text import to_bytes, to_text
|
|
|
|
from ansible.parsing.utils.addresses import parse_address
|
|
|
|
from ansible.parsing.utils.addresses import parse_address
|
|
|
|
from ansible.plugins.loader import inventory_loader
|
|
|
|
from ansible.plugins.loader import inventory_loader
|
|
|
|
from ansible.utils.path import unfrackpath
|
|
|
|
from ansible.utils.path import unfrackpath
|
|
|
@ -86,12 +86,12 @@ def split_host_pattern(pattern):
|
|
|
|
if isinstance(pattern, list):
|
|
|
|
if isinstance(pattern, list):
|
|
|
|
return list(itertools.chain(*map(split_host_pattern, pattern)))
|
|
|
|
return list(itertools.chain(*map(split_host_pattern, pattern)))
|
|
|
|
elif not isinstance(pattern, string_types):
|
|
|
|
elif not isinstance(pattern, string_types):
|
|
|
|
pattern = to_native(pattern)
|
|
|
|
pattern = to_text(pattern, errors='surrogate_or_strict')
|
|
|
|
|
|
|
|
|
|
|
|
# If it's got commas in it, we'll treat it as a straightforward
|
|
|
|
# If it's got commas in it, we'll treat it as a straightforward
|
|
|
|
# comma-separated list of patterns.
|
|
|
|
# comma-separated list of patterns.
|
|
|
|
if ',' in pattern:
|
|
|
|
if u',' in pattern:
|
|
|
|
patterns = pattern.split(',')
|
|
|
|
patterns = pattern.split(u',')
|
|
|
|
|
|
|
|
|
|
|
|
# If it doesn't, it could still be a single pattern. This accounts for
|
|
|
|
# If it doesn't, it could still be a single pattern. This accounts for
|
|
|
|
# non-separator uses of colons: IPv6 addresses and [x:y] host ranges.
|
|
|
|
# non-separator uses of colons: IPv6 addresses and [x:y] host ranges.
|
|
|
@ -104,12 +104,12 @@ def split_host_pattern(pattern):
|
|
|
|
# This mishandles IPv6 addresses, and is retained only for backwards
|
|
|
|
# This mishandles IPv6 addresses, and is retained only for backwards
|
|
|
|
# compatibility.
|
|
|
|
# compatibility.
|
|
|
|
patterns = re.findall(
|
|
|
|
patterns = re.findall(
|
|
|
|
r'''(?: # We want to match something comprising:
|
|
|
|
to_text(r'''(?: # We want to match something comprising:
|
|
|
|
[^\s:\[\]] # (anything other than whitespace or ':[]'
|
|
|
|
[^\s:\[\]] # (anything other than whitespace or ':[]'
|
|
|
|
| # ...or...
|
|
|
|
| # ...or...
|
|
|
|
\[[^\]]*\] # a single complete bracketed expression)
|
|
|
|
\[[^\]]*\] # a single complete bracketed expression)
|
|
|
|
)+ # occurring once or more
|
|
|
|
)+ # occurring once or more
|
|
|
|
''', pattern, re.X
|
|
|
|
'''), pattern, re.X
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return [p.strip() for p in patterns]
|
|
|
|
return [p.strip() for p in patterns]
|
|
|
@ -236,9 +236,9 @@ class InventoryManager(object):
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
# recursively deal with directory entries
|
|
|
|
# recursively deal with directory entries
|
|
|
|
fullpath = os.path.join(b_source, i)
|
|
|
|
b_fullpath = os.path.join(b_source, i)
|
|
|
|
parsed_this_one = self.parse_source(to_native(fullpath), cache=cache)
|
|
|
|
parsed_this_one = self.parse_source(b_fullpath, cache=cache)
|
|
|
|
display.debug(u'parsed %s as %s' % (fullpath, parsed_this_one))
|
|
|
|
display.debug(u'parsed %s as %s' % (to_text(b_fullpath), parsed_this_one))
|
|
|
|
if not parsed:
|
|
|
|
if not parsed:
|
|
|
|
parsed = parsed_this_one
|
|
|
|
parsed = parsed_this_one
|
|
|
|
else:
|
|
|
|
else:
|
|
|
@ -254,7 +254,7 @@ class InventoryManager(object):
|
|
|
|
# try source with each plugin
|
|
|
|
# try source with each plugin
|
|
|
|
failures = []
|
|
|
|
failures = []
|
|
|
|
for plugin in self._inventory_plugins:
|
|
|
|
for plugin in self._inventory_plugins:
|
|
|
|
plugin_name = to_native(getattr(plugin, '_load_name', getattr(plugin, '_original_path', '')))
|
|
|
|
plugin_name = to_text(getattr(plugin, '_load_name', getattr(plugin, '_original_path', '')))
|
|
|
|
display.debug(u'Attempting to use plugin %s (%s)' % (plugin_name, plugin._original_path))
|
|
|
|
display.debug(u'Attempting to use plugin %s (%s)' % (plugin_name, plugin._original_path))
|
|
|
|
|
|
|
|
|
|
|
|
# initialize and figure out if plugin wants to attempt parsing this file
|
|
|
|
# initialize and figure out if plugin wants to attempt parsing this file
|
|
|
@ -337,10 +337,10 @@ class InventoryManager(object):
|
|
|
|
pattern_hash = pattern
|
|
|
|
pattern_hash = pattern
|
|
|
|
|
|
|
|
|
|
|
|
if not ignore_limits and self._subset:
|
|
|
|
if not ignore_limits and self._subset:
|
|
|
|
pattern_hash += ":%s" % to_native(self._subset)
|
|
|
|
pattern_hash += u":%s" % to_text(self._subset, errors='surrogate_or_strict')
|
|
|
|
|
|
|
|
|
|
|
|
if not ignore_restrictions and self._restriction:
|
|
|
|
if not ignore_restrictions and self._restriction:
|
|
|
|
pattern_hash += ":%s" % to_native(self._restriction)
|
|
|
|
pattern_hash += u":%s" % to_text(self._restriction, errors='surrogate_or_strict')
|
|
|
|
|
|
|
|
|
|
|
|
if pattern_hash not in self._hosts_patterns_cache:
|
|
|
|
if pattern_hash not in self._hosts_patterns_cache:
|
|
|
|
|
|
|
|
|
|
|
|