From 1ee9109a738c217df32113905a864457a2c74d7e Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Thu, 18 Apr 2024 07:52:15 +0200 Subject: [PATCH] Make wrapping variables as unsafe smarter to avoid triggering an AWX bug. (#835) --- changelogs/fragments/835-unsafe.yml | 2 ++ plugins/inventory/docker_containers.py | 2 +- plugins/inventory/docker_machine.py | 2 +- plugins/inventory/docker_swarm.py | 2 +- plugins/plugin_utils/unsafe.py | 41 ++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 changelogs/fragments/835-unsafe.yml create mode 100644 plugins/plugin_utils/unsafe.py diff --git a/changelogs/fragments/835-unsafe.yml b/changelogs/fragments/835-unsafe.yml new file mode 100644 index 000000000..a8c16e743 --- /dev/null +++ b/changelogs/fragments/835-unsafe.yml @@ -0,0 +1,2 @@ +bugfixes: + - "inventory plugins - add unsafe wrapper to avoid marking strings that do not contain ``{`` or ``}`` as unsafe, to work around a bug in AWX (https://github.com/ansible-collections/community.docker/pull/835)." diff --git a/plugins/inventory/docker_containers.py b/plugins/inventory/docker_containers.py index 75b49ff92..0cae05472 100644 --- a/plugins/inventory/docker_containers.py +++ b/plugins/inventory/docker_containers.py @@ -167,7 +167,6 @@ from ansible.errors import AnsibleError from ansible.module_utils.common.text.converters import to_native from ansible.plugins.inventory import BaseInventoryPlugin, Constructable -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe from ansible_collections.community.docker.plugins.module_utils.common_api import ( RequestException, @@ -180,6 +179,7 @@ ) from ansible_collections.community.docker.plugins.module_utils._api.errors import APIError, DockerException +from ansible_collections.community.docker.plugins.plugin_utils.unsafe import make_unsafe from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import parse_filters, filter_host MIN_DOCKER_API = None diff --git a/plugins/inventory/docker_machine.py b/plugins/inventory/docker_machine.py index e3330a339..984c9932b 100644 --- a/plugins/inventory/docker_machine.py +++ b/plugins/inventory/docker_machine.py @@ -96,8 +96,8 @@ from ansible.module_utils.common.process import get_bin_path from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable from ansible.utils.display import Display -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe +from ansible_collections.community.docker.plugins.plugin_utils.unsafe import make_unsafe from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import parse_filters, filter_host import json diff --git a/plugins/inventory/docker_swarm.py b/plugins/inventory/docker_swarm.py index 0d60033f9..acceac86c 100644 --- a/plugins/inventory/docker_swarm.py +++ b/plugins/inventory/docker_swarm.py @@ -159,8 +159,8 @@ from ansible_collections.community.docker.plugins.module_utils.util import update_tls_hostname from ansible.plugins.inventory import BaseInventoryPlugin, Constructable from ansible.parsing.utils.addresses import parse_address -from ansible.utils.unsafe_proxy import wrap_var as make_unsafe +from ansible_collections.community.docker.plugins.plugin_utils.unsafe import make_unsafe from ansible_collections.community.library_inventory_filtering_v1.plugins.plugin_utils.inventory_filter import parse_filters, filter_host try: diff --git a/plugins/plugin_utils/unsafe.py b/plugins/plugin_utils/unsafe.py new file mode 100644 index 000000000..1eb61bea0 --- /dev/null +++ b/plugins/plugin_utils/unsafe.py @@ -0,0 +1,41 @@ +# Copyright (c) 2023, Felix Fontein +# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) +# SPDX-License-Identifier: GPL-3.0-or-later + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import re + +from ansible.module_utils.six import binary_type, text_type +from ansible.module_utils.common._collections_compat import Mapping, Set +from ansible.module_utils.common.collections import is_sequence +from ansible.utils.unsafe_proxy import ( + AnsibleUnsafe, + wrap_var as _make_unsafe, +) + +_RE_TEMPLATE_CHARS = re.compile(u'[{}]') +_RE_TEMPLATE_CHARS_BYTES = re.compile(b'[{}]') + + +def make_unsafe(value): + if value is None or isinstance(value, AnsibleUnsafe): + return value + + if isinstance(value, Mapping): + return dict((make_unsafe(key), make_unsafe(val)) for key, val in value.items()) + elif isinstance(value, Set): + return set(make_unsafe(elt) for elt in value) + elif is_sequence(value): + return type(value)(make_unsafe(elt) for elt in value) + elif isinstance(value, binary_type): + if _RE_TEMPLATE_CHARS_BYTES.search(value): + value = _make_unsafe(value) + return value + elif isinstance(value, text_type): + if _RE_TEMPLATE_CHARS.search(value): + value = _make_unsafe(value) + return value + + return value