Skip to content

Commit

Permalink
Fix python3 and nonascii handling in inventory plugins
Browse files Browse the repository at this point in the history
Fixes #30663

(cherry picked from commit 72bdf7a)
  • Loading branch information
abadger committed Sep 21, 2017
1 parent 46fd30d commit 11cc64d
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 41 deletions.
6 changes: 3 additions & 3 deletions lib/ansible/plugins/inventory/__init__.py
Expand Up @@ -60,18 +60,18 @@ def parse(self, inventory, loader, path, cache=True):
def verify_file(self, path):
''' Verify if file is usable by this plugin, base does minimal accessability check '''

b_path = to_bytes(path)
b_path = to_bytes(path, errors='surrogate_or_strict')
return (os.path.exists(b_path) and os.access(b_path, os.R_OK))

def get_cache_prefix(self, path):
''' create predictable unique prefix for plugin/inventory '''

m = hashlib.sha1()
m.update(to_bytes(self.NAME))
m.update(to_bytes(self.NAME, errors='surrogate_or_strict'))
d1 = m.hexdigest()

n = hashlib.sha1()
n.update(to_bytes(path))
n.update(to_bytes(path, errors='surrogate_or_strict'))
d2 = n.hexdigest()

return 's_'.join([d1[:5], d2[:5]])
Expand Down
6 changes: 3 additions & 3 deletions lib/ansible/plugins/inventory/advanced_host_list.py
Expand Up @@ -36,9 +36,9 @@ class InventoryModule(BaseInventoryPlugin):
def verify_file(self, host_list):

valid = False
b_path = to_bytes(host_list)
b_path = to_bytes(host_list, errors='surrogate_or_strict')
if not os.path.exists(b_path) and ',' in host_list:
valid = True
valid = True
return valid

def parse(self, inventory, loader, host_list, cache=True):
Expand All @@ -61,7 +61,7 @@ def parse(self, inventory, loader, host_list, cache=True):
if host not in self.inventory.hosts:
self.inventory.add_host(host, group='ungrouped', port=port)
except Exception as e:
raise AnsibleParserError("Invalid data from string, could not parse: %s" % str(e))
raise AnsibleParserError("Invalid data from string, could not parse: %s" % to_native(e))

def _expand_hostpattern(self, hostpattern):
'''
Expand Down
9 changes: 4 additions & 5 deletions lib/ansible/plugins/inventory/host_list.py
Expand Up @@ -27,8 +27,7 @@
import os

from ansible.errors import AnsibleError, AnsibleParserError
from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_bytes, to_text, to_native
from ansible.module_utils._text import to_bytes, to_native
from ansible.parsing.utils.addresses import parse_address
from ansible.plugins.inventory import BaseInventoryPlugin

Expand All @@ -40,9 +39,9 @@ class InventoryModule(BaseInventoryPlugin):
def verify_file(self, host_list):

valid = False
b_path = to_bytes(host_list)
b_path = to_bytes(host_list, errors='surrogate_or_strict')
if not os.path.exists(b_path) and ',' in host_list:
valid = True
valid = True
return valid

def parse(self, inventory, loader, host_list, cache=True):
Expand All @@ -64,4 +63,4 @@ def parse(self, inventory, loader, host_list, cache=True):
if host not in self.inventory.hosts:
self.inventory.add_host(host, group='ungrouped', port=port)
except Exception as e:
raise AnsibleParserError("Invalid data from string, could not parse: %s" % str(e))
raise AnsibleParserError("Invalid data from string, could not parse: %s" % to_native(e))
10 changes: 5 additions & 5 deletions lib/ansible/plugins/inventory/ini.py
Expand Up @@ -105,7 +105,7 @@ def parse(self, inventory, loader, path, cache=True):
if self.loader:
(b_data, private) = self.loader._get_file_contents(path)
else:
b_path = to_bytes(path)
b_path = to_bytes(path, errors='surrogate_or_strict')
with open(b_path, 'rb') as fh:
b_data = fh.read()

Expand Down Expand Up @@ -366,14 +366,14 @@ def _compile_patterns(self):
# [naughty:children] # only get coal in their stockings

self.patterns['section'] = re.compile(
r'''^\[
to_text(r'''^\[
([^:\]\s]+) # group name (see groupname below)
(?::(\w+))? # optional : and tag name
\]
\s* # ignore trailing whitespace
(?:\#.*)? # and/or a comment till the
$ # end of the line
''', re.X
''', errors='surrogate_or_strict'), re.X
)

# FIXME: What are the real restrictions on group names, or rather, what
Expand All @@ -382,10 +382,10 @@ def _compile_patterns(self):
# precise rules in order to support better diagnostics.

self.patterns['groupname'] = re.compile(
r'''^
to_text(r'''^
([^:\]\s]+)
\s* # ignore trailing whitespace
(?:\#.*)? # and/or a comment till the
$ # end of the line
''', re.X
''', errors='surrogate_or_strict'), re.X
)
35 changes: 18 additions & 17 deletions lib/ansible/plugins/inventory/virtualbox.py
Expand Up @@ -49,25 +49,26 @@

import os

from collections import MutableMapping
from subprocess import Popen, PIPE

from ansible.errors import AnsibleParserError
from ansible.module_utils._text import to_bytes, to_text
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.plugins.inventory import BaseInventoryPlugin


class InventoryModule(BaseInventoryPlugin):
''' Host inventory parser for ansible using local virtualbox. '''

NAME = 'virtualbox'
VBOX = "VBoxManage"
VBOX = b"VBoxManage"

def _query_vbox_data(self, host, property_path):
ret = None
try:
cmd = [self.VBOX, 'guestproperty', 'get', host, property_path]
cmd = [self.VBOX, b'guestproperty', b'get', to_bytes(host, errors='surrogate_or_strict'), to_bytes(property_path, errors='surrogate_or_strict')]
x = Popen(cmd, stdout=PIPE)
ipinfo = x.stdout.read()
ipinfo = to_text(x.stdout.read(), errors='surrogate_or_strict')
if 'Value' in ipinfo:
a, ip = ipinfo.split(':', 1)
ret = ip.strip()
Expand All @@ -81,7 +82,7 @@ def _set_variables(self, hostvars, data):
for host in hostvars:

# create vars from vbox properties
if data.get('query') and isinstance(data['query'], dict):
if data.get('query') and isinstance(data['query'], MutableMapping):
for varname in data['query']:
hostvars[host][varname] = self._query_vbox_data(host, data['query'][varname])

Expand Down Expand Up @@ -168,7 +169,7 @@ def parse(self, inventory, loader, path, cache=True):
try:
config_data = self.loader.load_from_file(path)
except Exception as e:
raise AnsibleParserError(e)
raise AnsibleParserError(to_native(e))

if not config_data or config_data.get('plugin') != self.NAME:
# this is not my config file
Expand All @@ -182,26 +183,26 @@ def parse(self, inventory, loader, path, cache=True):
pass

if not source_data:
pwfile = to_bytes(config_data.get('settings_password_file'))
b_pwfile = to_bytes(config_data.get('settings_password_file'), errors='surrogate_or_strict')
running = config_data.get('running_only', False)

# start getting data
cmd = [self.VBOX, 'list', '-l']
cmd = [self.VBOX, b'list', b'-l']
if running:
cmd.append('runningvms')
cmd.append(b'runningvms')
else:
cmd.append('vms')
cmd.append(b'vms')

if pwfile and os.path.exists(pwfile):
cmd.append('--settingspwfile')
cmd.append(pwfile)
if b_pwfile and os.path.exists(b_pwfile):
cmd.append(b'--settingspwfile')
cmd.append(b_pwfile)

try:
p = Popen(cmd, stdout=PIPE)
except Exception as e:
AnsibleParserError(e)
AnsibleParserError(to_native(e))

source_data = p.stdout.readlines()
inventory.cache[cache_key] = to_text(source_data)
source_data = p.stdout.read()
inventory.cache[cache_key] = to_text(source_data, errors='surrogate_or_strict')

self._populate_from_source(source_data, config_data)
self._populate_from_source(source_data.splitlines(), config_data)
16 changes: 8 additions & 8 deletions lib/ansible/plugins/inventory/yaml.py
Expand Up @@ -51,11 +51,12 @@

import re
import os
from collections import MutableMapping

from ansible import constants as C
from ansible.errors import AnsibleParserError
from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_bytes, to_text
from ansible.module_utils._text import to_native
from ansible.parsing.utils.addresses import parse_address
from ansible.plugins.inventory import BaseFileInventoryPlugin, detect_range, expand_hostname_range

Expand All @@ -74,9 +75,8 @@ def __init__(self):
def verify_file(self, path):

valid = False
b_path = to_bytes(path)
if super(InventoryModule, self).verify_file(b_path):
file_name, ext = os.path.splitext(b_path)
if super(InventoryModule, self).verify_file(path):
file_name, ext = os.path.splitext(path)
if ext and ext in C.YAML_FILENAME_EXTENSIONS:
valid = True
return valid
Expand All @@ -96,19 +96,19 @@ def parse(self, inventory, loader, path, cache=True):

# We expect top level keys to correspond to groups, iterate over them
# to get host, vars and subgroups (which we iterate over recursivelly)
if isinstance(data, dict):
if isinstance(data, MutableMapping):
for group_name in data:
self._parse_group(group_name, data[group_name])
else:
raise AnsibleParserError("Invalid data from file, expected dictionary and got:\n\n%s" % data)
raise AnsibleParserError("Invalid data from file, expected dictionary and got:\n\n%s" % to_native(data))

def _parse_group(self, group, group_data):

if self.patterns['groupname'].match(group):

self.inventory.add_group(group)

if isinstance(group_data, dict):
if isinstance(group_data, MutableMapping):
# make sure they are dicts
for section in ['vars', 'children', 'hosts']:
if section in group_data and isinstance(group_data[section], string_types):
Expand Down Expand Up @@ -167,4 +167,4 @@ def _compile_patterns(self):
'''
Compiles the regular expressions required to parse the inventory and stores them in self.patterns.
'''
self.patterns['groupname'] = re.compile(r'''^[A-Za-z_][A-Za-z0-9_]*$''')
self.patterns['groupname'] = re.compile(u'''^[A-Za-z_][A-Za-z0-9_]*$''')

0 comments on commit 11cc64d

Please sign in to comment.