summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--changelogs/fragments/84238-fix-reset_connection-ssh_executable-templated.yml2
-rw-r--r--lib/ansible/executor/task_executor.py15
-rw-r--r--lib/ansible/plugins/connection/__init__.py21
-rw-r--r--lib/ansible/plugins/strategy/__init__.py3
-rwxr-xr-xtest/integration/targets/connection/test.sh1
-rw-r--r--test/integration/targets/connection/test_reset_connection_templated.yml7
6 files changed, 35 insertions, 14 deletions
diff --git a/changelogs/fragments/84238-fix-reset_connection-ssh_executable-templated.yml b/changelogs/fragments/84238-fix-reset_connection-ssh_executable-templated.yml
new file mode 100644
index 0000000000..ea77b48dde
--- /dev/null
+++ b/changelogs/fragments/84238-fix-reset_connection-ssh_executable-templated.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - ssh - connection options were incorrectly templated during ``reset_connection`` tasks (https://github.com/ansible/ansible/pull/84238).
diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py
index ff1c33871f..77fae99af3 100644
--- a/lib/ansible/executor/task_executor.py
+++ b/lib/ansible/executor/task_executor.py
@@ -1073,18 +1073,6 @@ class TaskExecutor:
option_vars = C.config.get_plugin_vars('connection', self._connection._load_name)
varnames.extend(option_vars)
- # create dict of 'templated vars'
- options = {'_extras': {}}
- for k in option_vars:
- if k in variables:
- options[k] = templar.template(variables[k])
-
- # add extras if plugin supports them
- if getattr(self._connection, 'allow_extras', False):
- for k in variables:
- if k.startswith('ansible_%s_' % self._connection.extras_prefix) and k not in options:
- options['_extras'][k] = templar.template(variables[k])
-
task_keys = self._task.dump_attrs()
# The task_keys 'timeout' attr is the task's timeout, not the connection timeout.
@@ -1102,7 +1090,8 @@ class TaskExecutor:
del task_keys['retries']
# set options with 'templated vars' specific to this plugin and dependent ones
- self._connection.set_options(task_keys=task_keys, var_options=options)
+ var_options = self._connection._resolve_option_variables(variables, templar)
+ self._connection.set_options(task_keys=task_keys, var_options=var_options)
varnames.extend(self._set_plugin_options('shell', variables, templar, task_keys))
if self._connection.become is not None:
diff --git a/lib/ansible/plugins/connection/__init__.py b/lib/ansible/plugins/connection/__init__.py
index de4a79e981..3743d3601e 100644
--- a/lib/ansible/plugins/connection/__init__.py
+++ b/lib/ansible/plugins/connection/__init__.py
@@ -285,6 +285,27 @@ class ConnectionBase(AnsiblePlugin):
display.debug('Set connection var {0} to {1}'.format(varname, value))
variables[varname] = value
+ def _resolve_option_variables(self, variables, templar):
+ """
+ Return a dict of variable -> templated value, for any variables that
+ that match options registered by this plugin.
+ """
+ # create dict of 'templated vars'
+ var_options = {
+ '_extras': {},
+ }
+ for var_name in C.config.get_plugin_vars('connection', self._load_name):
+ if var_name in variables:
+ var_options[var_name] = templar.template(variables[var_name])
+
+ # add extras if plugin supports them
+ if getattr(self, 'allow_extras', False):
+ for var_name in variables:
+ if var_name.startswith(f'ansible_{self.extras_prefix}_') and var_name not in var_options:
+ var_options['_extras'][var_name] = templar.template(variables[var_name])
+
+ return var_options
+
class NetworkConnectionBase(ConnectionBase):
"""
diff --git a/lib/ansible/plugins/strategy/__init__.py b/lib/ansible/plugins/strategy/__init__.py
index 3eb5538b96..c9fdfeeb22 100644
--- a/lib/ansible/plugins/strategy/__init__.py
+++ b/lib/ansible/plugins/strategy/__init__.py
@@ -1068,7 +1068,8 @@ class StrategyBase:
del self._active_connections[target_host]
else:
connection = plugin_loader.connection_loader.get(play_context.connection, play_context, os.devnull)
- connection.set_options(task_keys=task.dump_attrs(), var_options=all_vars)
+ var_options = connection._resolve_option_variables(all_vars, templar)
+ connection.set_options(task_keys=task.dump_attrs(), var_options=var_options)
play_context.set_attributes_from_plugin(connection)
if connection:
diff --git a/test/integration/targets/connection/test.sh b/test/integration/targets/connection/test.sh
index 6e16a87ea7..c376e28a0a 100755
--- a/test/integration/targets/connection/test.sh
+++ b/test/integration/targets/connection/test.sh
@@ -20,3 +20,4 @@ else
fi
ansible-playbook test_reset_connection.yml -i "${INVENTORY}" "$@"
+ansible-playbook test_reset_connection_templated.yml -i "${INVENTORY}" "$@"
diff --git a/test/integration/targets/connection/test_reset_connection_templated.yml b/test/integration/targets/connection/test_reset_connection_templated.yml
new file mode 100644
index 0000000000..de36ca17ae
--- /dev/null
+++ b/test/integration/targets/connection/test_reset_connection_templated.yml
@@ -0,0 +1,7 @@
+- hosts: "{{ target_hosts }}"
+ gather_facts: false
+ vars:
+ ansible_ssh_executable: "{{ 'ssh' | trim }}"
+ tasks:
+ # https://github.com/ansible/ansible/issues/84238
+ - meta: reset_connection