1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

[stable-6] inventory plugins: make data obtained from remote unsafe (#8147)

inventory plugins: make data obtained from remote unsafe (#8098)

Make data obtained from remote unsafe.

(cherry picked from commit d62fe154d2)
This commit is contained in:
Felix Fontein 2024-03-25 06:50:17 +01:00 committed by GitHub
parent 12df7f7a95
commit d250bb5217
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 83 additions and 46 deletions

View file

@ -0,0 +1,6 @@
security_fixes:
- "cobbler, gitlab_runners, icinga2, linode, lxd, nmap, online, opennebula, proxmox, scaleway, stackpath_compute, virtualbox,
and xen_orchestra inventory plugin - make sure all data received from the remote servers is marked as unsafe, so remote
code execution by obtaining texts that can be evaluated as templates is not possible
(https://www.die-welt.net/2024/03/remote-code-execution-in-ansible-dynamic-inventory-plugins/,
https://github.com/ansible-collections/community.general/pull/8098)."

View file

@ -88,6 +88,7 @@ from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.six import iteritems from ansible.module_utils.six import iteritems
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name
from ansible.module_utils.six import text_type from ansible.module_utils.six import text_type
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
# xmlrpc # xmlrpc
try: try:
@ -239,7 +240,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
for host in self._get_systems(): for host in self._get_systems():
# Get the FQDN for the host and add it to the right groups # Get the FQDN for the host and add it to the right groups
hostname = host['hostname'] # None hostname = make_unsafe(host['hostname']) # None
interfaces = host['interfaces'] interfaces = host['interfaces']
if self._exclude_profile(host['profile']): if self._exclude_profile(host['profile']):
@ -252,7 +253,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
if ivalue['management'] or not ivalue['static']: if ivalue['management'] or not ivalue['static']:
this_dns_name = ivalue.get('dns_name', None) this_dns_name = ivalue.get('dns_name', None)
if this_dns_name is not None and this_dns_name != "": if this_dns_name is not None and this_dns_name != "":
hostname = this_dns_name hostname = make_unsafe(this_dns_name)
self.display.vvvv('Set hostname to %s from %s\n' % (hostname, iname)) self.display.vvvv('Set hostname to %s from %s\n' % (hostname, iname))
if hostname == '': if hostname == '':
@ -283,6 +284,6 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
# Add host variables # Add host variables
if self.get_option('want_facts'): if self.get_option('want_facts'):
try: try:
self.inventory.set_variable(hostname, 'cobbler', host) self.inventory.set_variable(hostname, 'cobbler', make_unsafe(host))
except ValueError as e: except ValueError as e:
self.display.warning("Could not set host info for %s: %s" % (hostname, to_text(e))) self.display.warning("Could not set host info for %s: %s" % (hostname, to_text(e)))

View file

@ -84,6 +84,7 @@ keyed_groups:
from ansible.errors import AnsibleError, AnsibleParserError from ansible.errors import AnsibleError, AnsibleParserError
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
try: try:
import gitlab import gitlab
@ -106,11 +107,11 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
else: else:
runners = gl.runners.all() runners = gl.runners.all()
for runner in runners: for runner in runners:
host = str(runner['id']) host = make_unsafe(str(runner['id']))
ip_address = runner['ip_address'] ip_address = runner['ip_address']
host_attrs = vars(gl.runners.get(runner['id']))['_attrs'] host_attrs = make_unsafe(vars(gl.runners.get(runner['id']))['_attrs'])
self.inventory.add_host(host, group='gitlab_runners') self.inventory.add_host(host, group='gitlab_runners')
self.inventory.set_variable(host, 'ansible_host', ip_address) self.inventory.set_variable(host, 'ansible_host', make_unsafe(ip_address))
if self.get_option('verbose_output', True): if self.get_option('verbose_output', True):
self.inventory.set_variable(host, 'gitlab_runner_attributes', host_attrs) self.inventory.set_variable(host, 'gitlab_runner_attributes', host_attrs)

View file

@ -96,6 +96,7 @@ from ansible.errors import AnsibleParserError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
from ansible.module_utils.six.moves.urllib.error import HTTPError from ansible.module_utils.six.moves.urllib.error import HTTPError
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
class InventoryModule(BaseInventoryPlugin, Constructable): class InventoryModule(BaseInventoryPlugin, Constructable):
@ -233,15 +234,15 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
"""Convert Icinga2 API data to JSON format for Ansible""" """Convert Icinga2 API data to JSON format for Ansible"""
groups_dict = {"_meta": {"hostvars": {}}} groups_dict = {"_meta": {"hostvars": {}}}
for entry in json_data: for entry in json_data:
host_attrs = entry['attrs'] host_attrs = make_unsafe(entry['attrs'])
if self.inventory_attr == "name": if self.inventory_attr == "name":
host_name = entry.get('name') host_name = make_unsafe(entry.get('name'))
if self.inventory_attr == "address": if self.inventory_attr == "address":
# When looking for address for inventory, if missing fallback to object name # When looking for address for inventory, if missing fallback to object name
if host_attrs.get('address', '') != '': if host_attrs.get('address', '') != '':
host_name = host_attrs.get('address') host_name = make_unsafe(host_attrs.get('address'))
else: else:
host_name = entry.get('name') host_name = make_unsafe(entry.get('name'))
if self.inventory_attr == "display_name": if self.inventory_attr == "display_name":
host_name = host_attrs.get('display_name') host_name = host_attrs.get('display_name')
if host_attrs['state'] == 0: if host_attrs['state'] == 0:
@ -257,7 +258,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
# If the address attribute is populated, override ansible_host with the value # If the address attribute is populated, override ansible_host with the value
if host_attrs.get('address') != '': if host_attrs.get('address') != '':
self.inventory.set_variable(host_name, 'ansible_host', host_attrs.get('address')) self.inventory.set_variable(host_name, 'ansible_host', host_attrs.get('address'))
self.inventory.set_variable(host_name, 'hostname', entry.get('name')) self.inventory.set_variable(host_name, 'hostname', make_unsafe(entry.get('name')))
self.inventory.set_variable(host_name, 'display_name', host_attrs.get('display_name')) self.inventory.set_variable(host_name, 'display_name', host_attrs.get('display_name'))
self.inventory.set_variable(host_name, 'state', self.inventory.set_variable(host_name, 'state',
host_attrs['state']) host_attrs['state'])

View file

@ -123,6 +123,7 @@ compose:
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
try: try:
@ -199,20 +200,21 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
def _add_instances_to_groups(self): def _add_instances_to_groups(self):
"""Add instance names to their dynamic inventory groups.""" """Add instance names to their dynamic inventory groups."""
for instance in self.instances: for instance in self.instances:
self.inventory.add_host(instance.label, group=instance.group) self.inventory.add_host(make_unsafe(instance.label), group=instance.group)
def _add_hostvars_for_instances(self): def _add_hostvars_for_instances(self):
"""Add hostvars for instances in the dynamic inventory.""" """Add hostvars for instances in the dynamic inventory."""
ip_style = self.get_option('ip_style') ip_style = self.get_option('ip_style')
for instance in self.instances: for instance in self.instances:
hostvars = instance._raw_json hostvars = instance._raw_json
hostname = make_unsafe(instance.label)
for hostvar_key in hostvars: for hostvar_key in hostvars:
if ip_style == 'api' and hostvar_key in ['ipv4', 'ipv6']: if ip_style == 'api' and hostvar_key in ['ipv4', 'ipv6']:
continue continue
self.inventory.set_variable( self.inventory.set_variable(
instance.label, hostname,
hostvar_key, hostvar_key,
hostvars[hostvar_key] make_unsafe(hostvars[hostvar_key])
) )
if ip_style == 'api': if ip_style == 'api':
ips = instance.ips.ipv4.public + instance.ips.ipv4.private ips = instance.ips.ipv4.public + instance.ips.ipv4.private
@ -221,9 +223,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
for ip_type in set(ip.type for ip in ips): for ip_type in set(ip.type for ip in ips):
self.inventory.set_variable( self.inventory.set_variable(
instance.label, hostname,
ip_type, ip_type,
self._ip_data([ip for ip in ips if ip.type == ip_type]) make_unsafe(self._ip_data([ip for ip in ips if ip.type == ip_type]))
) )
def _ip_data(self, ip_list): def _ip_data(self, ip_list):
@ -254,21 +256,22 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self._add_instances_to_groups() self._add_instances_to_groups()
self._add_hostvars_for_instances() self._add_hostvars_for_instances()
for instance in self.instances: for instance in self.instances:
variables = self.inventory.get_host(instance.label).get_vars() hostname = make_unsafe(instance.label)
variables = self.inventory.get_host(hostname).get_vars()
self._add_host_to_composed_groups( self._add_host_to_composed_groups(
self.get_option('groups'), self.get_option('groups'),
variables, variables,
instance.label, hostname,
strict=strict) strict=strict)
self._add_host_to_keyed_groups( self._add_host_to_keyed_groups(
self.get_option('keyed_groups'), self.get_option('keyed_groups'),
variables, variables,
instance.label, hostname,
strict=strict) strict=strict)
self._set_composite_vars( self._set_composite_vars(
self.get_option('compose'), self.get_option('compose'),
variables, variables,
instance.label, hostname,
strict=strict) strict=strict)
def verify_file(self, path): def verify_file(self, path):

View file

@ -161,6 +161,7 @@ from ansible.module_utils.six import raise_from
from ansible.errors import AnsibleError, AnsibleParserError from ansible.errors import AnsibleError, AnsibleParserError
from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
try: try:
import ipaddress import ipaddress
@ -656,7 +657,7 @@ class InventoryModule(BaseInventoryPlugin):
if self._get_data_entry('inventory/{0}/network_interfaces'.format(instance_name)): # instance have network interfaces if self._get_data_entry('inventory/{0}/network_interfaces'.format(instance_name)): # instance have network interfaces
self.inventory.set_variable(instance_name, 'ansible_connection', 'ssh') self.inventory.set_variable(instance_name, 'ansible_connection', 'ssh')
self.inventory.set_variable(instance_name, 'ansible_host', interface_selection(instance_name)) self.inventory.set_variable(instance_name, 'ansible_host', make_unsafe(interface_selection(instance_name)))
else: else:
self.inventory.set_variable(instance_name, 'ansible_connection', 'local') self.inventory.set_variable(instance_name, 'ansible_connection', 'local')
@ -682,31 +683,39 @@ class InventoryModule(BaseInventoryPlugin):
if self.filter.lower() != instance_state: if self.filter.lower() != instance_state:
continue continue
# add instance # add instance
instance_name = make_unsafe(instance_name)
self.inventory.add_host(instance_name) self.inventory.add_host(instance_name)
# add network informations # add network informations
self.build_inventory_network(instance_name) self.build_inventory_network(instance_name)
# add os # add os
v = self._get_data_entry('inventory/{0}/os'.format(instance_name)) v = self._get_data_entry('inventory/{0}/os'.format(instance_name))
if v: if v:
self.inventory.set_variable(instance_name, 'ansible_lxd_os', v.lower()) self.inventory.set_variable(instance_name, 'ansible_lxd_os', make_unsafe(v.lower()))
# add release # add release
v = self._get_data_entry('inventory/{0}/release'.format(instance_name)) v = self._get_data_entry('inventory/{0}/release'.format(instance_name))
if v: if v:
self.inventory.set_variable(instance_name, 'ansible_lxd_release', v.lower()) self.inventory.set_variable(
instance_name, 'ansible_lxd_release', make_unsafe(v.lower()))
# add profile # add profile
self.inventory.set_variable(instance_name, 'ansible_lxd_profile', self._get_data_entry('inventory/{0}/profile'.format(instance_name))) self.inventory.set_variable(
instance_name, 'ansible_lxd_profile', make_unsafe(self._get_data_entry('inventory/{0}/profile'.format(instance_name))))
# add state # add state
self.inventory.set_variable(instance_name, 'ansible_lxd_state', instance_state) self.inventory.set_variable(
instance_name, 'ansible_lxd_state', make_unsafe(instance_state))
# add type # add type
self.inventory.set_variable(instance_name, 'ansible_lxd_type', self._get_data_entry('inventory/{0}/type'.format(instance_name))) self.inventory.set_variable(
instance_name, 'ansible_lxd_type', make_unsafe(self._get_data_entry('inventory/{0}/type'.format(instance_name))))
# add location information # add location information
if self._get_data_entry('inventory/{0}/location'.format(instance_name)) != "none": # wrong type by lxd 'none' != 'None' if self._get_data_entry('inventory/{0}/location'.format(instance_name)) != "none": # wrong type by lxd 'none' != 'None'
self.inventory.set_variable(instance_name, 'ansible_lxd_location', self._get_data_entry('inventory/{0}/location'.format(instance_name))) self.inventory.set_variable(
instance_name, 'ansible_lxd_location', make_unsafe(self._get_data_entry('inventory/{0}/location'.format(instance_name))))
# add VLAN_ID information # add VLAN_ID information
if self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name)): if self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name)):
self.inventory.set_variable(instance_name, 'ansible_lxd_vlan_ids', self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name))) self.inventory.set_variable(
instance_name, 'ansible_lxd_vlan_ids', make_unsafe(self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name))))
# add project # add project
self.inventory.set_variable(instance_name, 'ansible_lxd_project', self._get_data_entry('inventory/{0}/project'.format(instance_name))) self.inventory.set_variable(
instance_name, 'ansible_lxd_project', make_unsafe(self._get_data_entry('inventory/{0}/project'.format(instance_name))))
def build_inventory_groups_location(self, group_name): def build_inventory_groups_location(self, group_name):
"""create group by attribute: location """create group by attribute: location
@ -979,7 +988,7 @@ class InventoryModule(BaseInventoryPlugin):
for group_name in self.groupby: for group_name in self.groupby:
if not group_name.isalnum(): if not group_name.isalnum():
raise AnsibleParserError('Invalid character(s) in groupname: {0}'.format(to_native(group_name))) raise AnsibleParserError('Invalid character(s) in groupname: {0}'.format(to_native(group_name)))
group_type(group_name) group_type(make_unsafe(group_name))
def build_inventory(self): def build_inventory(self):
"""Build dynamic inventory """Build dynamic inventory

View file

@ -121,6 +121,7 @@ from ansible.errors import AnsibleParserError
from ansible.module_utils.common.text.converters import to_native, to_text from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.module_utils.common.process import get_bin_path from ansible.module_utils.common.process import get_bin_path
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
@ -138,6 +139,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
strict = self.get_option('strict') strict = self.get_option('strict')
for host in hosts: for host in hosts:
host = make_unsafe(host)
hostname = host['name'] hostname = host['name']
self.inventory.add_host(hostname) self.inventory.add_host(hostname)
for var, value in host.items(): for var, value in host.items():

View file

@ -68,6 +68,7 @@ from ansible.plugins.inventory import BaseInventoryPlugin
from ansible.module_utils.common.text.converters import to_text from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.ansible_release import __version__ as ansible_version from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.module_utils.six.moves.urllib.parse import urljoin from ansible.module_utils.six.moves.urllib.parse import urljoin
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
class InventoryModule(BaseInventoryPlugin): class InventoryModule(BaseInventoryPlugin):
@ -169,20 +170,20 @@ class InventoryModule(BaseInventoryPlugin):
"support" "support"
) )
for attribute in targeted_attributes: for attribute in targeted_attributes:
self.inventory.set_variable(hostname, attribute, host_infos[attribute]) self.inventory.set_variable(hostname, attribute, make_unsafe(host_infos[attribute]))
if self.extract_public_ipv4(host_infos=host_infos): if self.extract_public_ipv4(host_infos=host_infos):
self.inventory.set_variable(hostname, "public_ipv4", self.extract_public_ipv4(host_infos=host_infos)) self.inventory.set_variable(hostname, "public_ipv4", make_unsafe(self.extract_public_ipv4(host_infos=host_infos)))
self.inventory.set_variable(hostname, "ansible_host", self.extract_public_ipv4(host_infos=host_infos)) self.inventory.set_variable(hostname, "ansible_host", make_unsafe(self.extract_public_ipv4(host_infos=host_infos)))
if self.extract_private_ipv4(host_infos=host_infos): if self.extract_private_ipv4(host_infos=host_infos):
self.inventory.set_variable(hostname, "public_ipv4", self.extract_private_ipv4(host_infos=host_infos)) self.inventory.set_variable(hostname, "public_ipv4", make_unsafe(self.extract_private_ipv4(host_infos=host_infos)))
if self.extract_os_name(host_infos=host_infos): if self.extract_os_name(host_infos=host_infos):
self.inventory.set_variable(hostname, "os_name", self.extract_os_name(host_infos=host_infos)) self.inventory.set_variable(hostname, "os_name", make_unsafe(self.extract_os_name(host_infos=host_infos)))
if self.extract_os_version(host_infos=host_infos): if self.extract_os_version(host_infos=host_infos):
self.inventory.set_variable(hostname, "os_version", self.extract_os_name(host_infos=host_infos)) self.inventory.set_variable(hostname, "os_version", make_unsafe(self.extract_os_name(host_infos=host_infos)))
def _filter_host(self, host_infos, hostname_preferences): def _filter_host(self, host_infos, hostname_preferences):
@ -201,6 +202,8 @@ class InventoryModule(BaseInventoryPlugin):
if not hostname: if not hostname:
return return
hostname = make_unsafe(hostname)
self.inventory.add_host(host=hostname) self.inventory.add_host(host=hostname)
self._fill_host_variables(hostname=hostname, host_infos=host_infos) self._fill_host_variables(hostname=hostname, host_infos=host_infos)
@ -210,6 +213,8 @@ class InventoryModule(BaseInventoryPlugin):
if not group: if not group:
return return
group = make_unsafe(group)
self.inventory.add_group(group=group) self.inventory.add_group(group=group)
self.inventory.add_host(group=group, host=hostname) self.inventory.add_host(group=group, host=hostname)

View file

@ -97,6 +97,7 @@ except ImportError:
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
from collections import namedtuple from collections import namedtuple
import os import os
@ -215,6 +216,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
filter_by_label = self.get_option('filter_by_label') filter_by_label = self.get_option('filter_by_label')
servers = self._retrieve_servers(filter_by_label) servers = self._retrieve_servers(filter_by_label)
for server in servers: for server in servers:
server = make_unsafe(server)
hostname = server['name'] hostname = server['name']
# check for labels # check for labels
if group_by_labels and server['LABELS']: if group_by_labels and server['LABELS']:

View file

@ -222,6 +222,7 @@ from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
@ -330,7 +331,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self._cache[self.cache_key][url] = data self._cache[self.cache_key][url] = data
return self._cache[self.cache_key][url] return make_unsafe(self._cache[self.cache_key][url])
def _get_nodes(self): def _get_nodes(self):
return self._get_json("%s/api2/json/nodes" % self.proxmox_url) return self._get_json("%s/api2/json/nodes" % self.proxmox_url)

View file

@ -124,6 +124,7 @@ from ansible_collections.community.general.plugins.module_utils.scaleway import
from ansible.module_utils.urls import open_url from ansible.module_utils.urls import open_url
from ansible.module_utils.common.text.converters import to_native, to_text from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.module_utils.six import raise_from from ansible.module_utils.six import raise_from
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
import ansible.module_utils.six.moves.urllib.parse as urllib_parse import ansible.module_utils.six.moves.urllib.parse as urllib_parse
@ -279,7 +280,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
zone_info = SCALEWAY_LOCATION[zone] zone_info = SCALEWAY_LOCATION[zone]
url = _build_server_url(zone_info["api_endpoint"]) url = _build_server_url(zone_info["api_endpoint"])
raw_zone_hosts_infos = _fetch_information(url=url, token=token) raw_zone_hosts_infos = make_unsafe(_fetch_information(url=url, token=token))
for host_infos in raw_zone_hosts_infos: for host_infos in raw_zone_hosts_infos:
@ -341,4 +342,4 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
hostname_preference = self.get_option("hostnames") hostname_preference = self.get_option("hostnames")
for zone in self._get_zones(config_zones): for zone in self._get_zones(config_zones):
self.do_zone_inventory(zone=zone, token=token, tags=tags, hostname_preferences=hostname_preference) self.do_zone_inventory(zone=make_unsafe(zone), token=token, tags=tags, hostname_preferences=hostname_preference)

View file

@ -72,6 +72,7 @@ from ansible.plugins.inventory import (
Cacheable Cacheable
) )
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
display = Display() display = Display()
@ -271,7 +272,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
if not cache or cache_needs_update: if not cache or cache_needs_update:
results = self._query() results = self._query()
self._populate(results) self._populate(make_unsafe(results))
# If the cache has expired/doesn't exist or # If the cache has expired/doesn't exist or
# if refresh_inventory/flush cache is used # if refresh_inventory/flush cache is used

View file

@ -62,6 +62,7 @@ from ansible.module_utils.common.text.converters import to_bytes, to_native, to_
from ansible.module_utils.common._collections_compat import MutableMapping from ansible.module_utils.common._collections_compat import MutableMapping
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.module_utils.common.process import get_bin_path from ansible.module_utils.common.process import get_bin_path
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
@ -116,6 +117,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), hostvars[host], host, strict=strict) self._add_host_to_keyed_groups(self.get_option('keyed_groups'), hostvars[host], host, strict=strict)
def _populate_from_cache(self, source_data): def _populate_from_cache(self, source_data):
source_data = make_unsafe(source_data)
hostvars = source_data.pop('_meta', {}).get('hostvars', {}) hostvars = source_data.pop('_meta', {}).get('hostvars', {})
for group in source_data: for group in source_data:
if group == 'all': if group == 'all':
@ -162,7 +164,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
v = v.strip() v = v.strip()
# found host # found host
if k.startswith('Name') and ',' not in v: # some setting strings appear in Name if k.startswith('Name') and ',' not in v: # some setting strings appear in Name
current_host = v current_host = make_unsafe(v)
if current_host not in hostvars: if current_host not in hostvars:
hostvars[current_host] = {} hostvars[current_host] = {}
self.inventory.add_host(current_host) self.inventory.add_host(current_host)
@ -170,12 +172,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
# try to get network info # try to get network info
netdata = self._query_vbox_data(current_host, netinfo) netdata = self._query_vbox_data(current_host, netinfo)
if netdata: if netdata:
self.inventory.set_variable(current_host, 'ansible_host', netdata) self.inventory.set_variable(current_host, 'ansible_host', make_unsafe(netdata))
# found groups # found groups
elif k == 'Groups': elif k == 'Groups':
for group in v.split('/'): for group in v.split('/'):
if group: if group:
group = make_unsafe(group)
group = self.inventory.add_group(group) group = self.inventory.add_group(group)
self.inventory.add_child(group, current_host) self.inventory.add_child(group, current_host)
if group not in cacheable_results: if group not in cacheable_results:
@ -185,17 +188,17 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
else: else:
# found vars, accumulate in hostvars for clean inventory set # found vars, accumulate in hostvars for clean inventory set
pref_k = 'vbox_' + k.strip().replace(' ', '_') pref_k = make_unsafe('vbox_' + k.strip().replace(' ', '_'))
leading_spaces = len(k) - len(k.lstrip(' ')) leading_spaces = len(k) - len(k.lstrip(' '))
if 0 < leading_spaces <= 2: if 0 < leading_spaces <= 2:
if prevkey not in hostvars[current_host] or not isinstance(hostvars[current_host][prevkey], dict): if prevkey not in hostvars[current_host] or not isinstance(hostvars[current_host][prevkey], dict):
hostvars[current_host][prevkey] = {} hostvars[current_host][prevkey] = {}
hostvars[current_host][prevkey][pref_k] = v hostvars[current_host][prevkey][pref_k] = make_unsafe(v)
elif leading_spaces > 2: elif leading_spaces > 2:
continue continue
else: else:
if v != '': if v != '':
hostvars[current_host][pref_k] = v hostvars[current_host][pref_k] = make_unsafe(v)
if self._ungrouped_host(current_host, cacheable_results): if self._ungrouped_host(current_host, cacheable_results):
if 'ungrouped' not in cacheable_results: if 'ungrouped' not in cacheable_results:
cacheable_results['ungrouped'] = {'hosts': []} cacheable_results['ungrouped'] = {'hosts': []}

View file

@ -82,6 +82,7 @@ from time import sleep
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
from ansible.utils.unsafe_proxy import wrap_var as make_unsafe
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
@ -347,4 +348,4 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
self.protocol = 'ws' self.protocol = 'ws'
objects = self._get_objects() objects = self._get_objects()
self._populate(objects) self._populate(make_unsafe(objects))