From 8704b9fc292851685e0c4abfb2e68d33e6dfe7cf Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 28 Mar 2024 15:06:35 -0400 Subject: [PATCH] centralize and complete the internal static vars (#82872) * centralize and complete the internal static vars These vars are internal and should not be overridden nor templated from inventory nor hostvars. --- changelogs/fragments/internal_static_vars.yml | 3 ++ lib/ansible/cli/inventory.py | 22 +--------- lib/ansible/constants.py | 40 +++++++++++++++++++ lib/ansible/modules/unarchive.py | 1 + lib/ansible/vars/hostvars.py | 28 +++---------- 5 files changed, 51 insertions(+), 43 deletions(-) create mode 100644 changelogs/fragments/internal_static_vars.yml diff --git a/changelogs/fragments/internal_static_vars.yml b/changelogs/fragments/internal_static_vars.yml new file mode 100644 index 00000000000..68121f82aa8 --- /dev/null +++ b/changelogs/fragments/internal_static_vars.yml @@ -0,0 +1,3 @@ +bugfixes: + - Consolidated the list of internal static vars, centralized them as constant and completed from some missing entries. + - Slight optimization to hostvars (instantiate template only once per host, vs per call to var). diff --git a/lib/ansible/cli/inventory.py b/lib/ansible/cli/inventory.py index c92b1300cb9..8c7c7e51d71 100755 --- a/lib/ansible/cli/inventory.py +++ b/lib/ansible/cli/inventory.py @@ -24,26 +24,6 @@ from ansible.vars.plugins import get_vars_from_inventory_sources, get_vars_from_ display = Display() -INTERNAL_VARS = frozenset(['ansible_diff_mode', - 'ansible_config_file', - 'ansible_facts', - 'ansible_forks', - 'ansible_inventory_sources', - 'ansible_limit', - 'ansible_playbook_python', - 'ansible_run_tags', - 'ansible_skip_tags', - 'ansible_verbosity', - 'ansible_version', - 'inventory_dir', - 'inventory_file', - 'inventory_hostname', - 'inventory_hostname_short', - 'groups', - 'group_names', - 'omit', - 'playbook_dir', ]) - class InventoryCLI(CLI): ''' used to display or dump the configured inventory as Ansible sees it ''' @@ -245,7 +225,7 @@ class InventoryCLI(CLI): @staticmethod def _remove_internal(dump): - for internal in INTERNAL_VARS: + for internal in C.INTERNAL_STATIC_VARS: if internal in dump: del dump[internal] diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index 3bf952f271a..42b1b1c7bd7 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -111,6 +111,46 @@ CONFIGURABLE_PLUGINS = ('become', 'cache', 'callback', 'cliconf', 'connection', DOCUMENTABLE_PLUGINS = CONFIGURABLE_PLUGINS + ('module', 'strategy', 'test', 'filter') IGNORE_FILES = ("COPYING", "CONTRIBUTING", "LICENSE", "README", "VERSION", "GUIDELINES", "MANIFEST", "Makefile") # ignore during module search INTERNAL_RESULT_KEYS = ('add_host', 'add_group') +INTERNAL_STATIC_VARS = frozenset( + [ + "ansible_async_path", + "ansible_collection_name", + "ansible_config_file", + "ansible_dependent_role_names", + "ansible_diff_mode", + "ansible_config_file", + "ansible_facts", + "ansible_forks", + "ansible_inventory_sources", + "ansible_limit", + "ansible_play_batch", + "ansible_play_hosts", + "ansible_play_hosts_all", + "ansible_play_role_names", + "ansible_playbook_python", + "ansible_role_name", + "ansible_role_names", + "ansible_run_tags", + "ansible_skip_tags", + "ansible_verbosity", + "ansible_version", + "inventory_dir", + "inventory_file", + "inventory_hostname", + "inventory_hostname_short", + "groups", + "group_names", + "omit", + "hostvars", + "playbook_dir", + "play_hosts", + "role_name", + "role_names", + "role_path", + "role_uuid", + "role_names", + ] +) LOCALHOST = ('127.0.0.1', 'localhost', '::1') MODULE_REQUIRE_ARGS = tuple(add_internal_fqcns(('command', 'win_command', 'ansible.windows.win_command', 'shell', 'win_shell', 'ansible.windows.win_shell', 'raw', 'script'))) diff --git a/lib/ansible/modules/unarchive.py b/lib/ansible/modules/unarchive.py index bb10e3333ec..6c51f1d4992 100644 --- a/lib/ansible/modules/unarchive.py +++ b/lib/ansible/modules/unarchive.py @@ -978,6 +978,7 @@ class TarZstdArchive(TgzArchive): class ZipZArchive(ZipArchive): def __init__(self, src, b_dest, file_args, module): super(ZipZArchive, self).__init__(src, b_dest, file_args, module) + # NOTE: adds 'l', which is default on most linux but not all implementations self.zipinfoflag = '-Zl' self.binaries = ( ('unzip', 'cmd_path'), diff --git a/lib/ansible/vars/hostvars.py b/lib/ansible/vars/hostvars.py index 424e6ef70c9..bb0372e4907 100644 --- a/lib/ansible/vars/hostvars.py +++ b/lib/ansible/vars/hostvars.py @@ -19,26 +19,9 @@ from __future__ import annotations from collections.abc import Mapping +from ansible import constants as C from ansible.template import Templar, AnsibleUndefined -STATIC_VARS = [ - 'ansible_version', - 'ansible_play_hosts', - 'ansible_dependent_role_names', - 'ansible_play_role_names', - 'ansible_role_names', - 'inventory_hostname', - 'inventory_hostname_short', - 'inventory_file', - 'inventory_dir', - 'groups', - 'group_names', - 'omit', - 'playbook_dir', - 'play_hosts', - 'role_names', - 'ungrouped', -] __all__ = ['HostVars', 'HostVarsVars'] @@ -131,10 +114,12 @@ class HostVarsVars(Mapping): def __init__(self, variables, loader): self._vars = variables self._loader = loader + # NOTE: this only has access to the host's own vars, + # so templates that depend on vars in other scopes will not work. + self._templar = Templar(variables=self._vars, loader=self._loader) def __getitem__(self, var): - templar = Templar(variables=self._vars, loader=self._loader) - return templar.template(self._vars[var], fail_on_undefined=False, static_vars=STATIC_VARS) + return self._templar.template(self._vars[var], fail_on_undefined=False, static_vars=C.INTERNAL_STATIC_VARS) def __contains__(self, var): return (var in self._vars) @@ -146,5 +131,4 @@ class HostVarsVars(Mapping): return len(self._vars.keys()) def __repr__(self): - templar = Templar(variables=self._vars, loader=self._loader) - return repr(templar.template(self._vars, fail_on_undefined=False, static_vars=STATIC_VARS)) + return repr(self._templar.template(self._vars, fail_on_undefined=False, static_vars=C.INTERNAL_STATIC_VARS))